mirror of
https://github.com/drone/drone-cli.git
synced 2025-09-02 19:21:10 +02:00
patch vendored files to use new drone-go
This commit is contained in:
parent
488a2157c8
commit
0c0e049ef0
@ -284,7 +284,7 @@ func run(client dockerclient.Client, args []string, input string) (int, error) {
|
||||
},
|
||||
}
|
||||
|
||||
info, err := docker.Run(client, conf, false)
|
||||
info, err := docker.Run(client, conf, nil, false, os.Stdout, os.Stderr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
3
vendor/github.com/Sirupsen/logrus/README.md
generated
vendored
3
vendor/github.com/Sirupsen/logrus/README.md
generated
vendored
@ -242,6 +242,9 @@ func init() {
|
||||
* [`github.com/johntdyer/slackrus`](https://github.com/johntdyer/slackrus)
|
||||
Hook for Slack chat.
|
||||
|
||||
* [`github.com/wercker/journalhook`](https://github.com/wercker/journalhook).
|
||||
Hook for logging to `systemd-journald`.
|
||||
|
||||
#### Level logging
|
||||
|
||||
Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic.
|
||||
|
53
vendor/github.com/Sirupsen/logrus/entry_test.go
generated
vendored
53
vendor/github.com/Sirupsen/logrus/entry_test.go
generated
vendored
@ -1,53 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEntryPanicln(t *testing.T) {
|
||||
errBoom := fmt.Errorf("boom time")
|
||||
|
||||
defer func() {
|
||||
p := recover()
|
||||
assert.NotNil(t, p)
|
||||
|
||||
switch pVal := p.(type) {
|
||||
case *Entry:
|
||||
assert.Equal(t, "kaboom", pVal.Message)
|
||||
assert.Equal(t, errBoom, pVal.Data["err"])
|
||||
default:
|
||||
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
|
||||
}
|
||||
}()
|
||||
|
||||
logger := New()
|
||||
logger.Out = &bytes.Buffer{}
|
||||
entry := NewEntry(logger)
|
||||
entry.WithField("err", errBoom).Panicln("kaboom")
|
||||
}
|
||||
|
||||
func TestEntryPanicf(t *testing.T) {
|
||||
errBoom := fmt.Errorf("boom again")
|
||||
|
||||
defer func() {
|
||||
p := recover()
|
||||
assert.NotNil(t, p)
|
||||
|
||||
switch pVal := p.(type) {
|
||||
case *Entry:
|
||||
assert.Equal(t, "kaboom true", pVal.Message)
|
||||
assert.Equal(t, errBoom, pVal.Data["err"])
|
||||
default:
|
||||
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
|
||||
}
|
||||
}()
|
||||
|
||||
logger := New()
|
||||
logger.Out = &bytes.Buffer{}
|
||||
entry := NewEntry(logger)
|
||||
entry.WithField("err", errBoom).Panicf("kaboom %v", true)
|
||||
}
|
40
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
40
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
@ -1,40 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
var log = logrus.New()
|
||||
|
||||
func init() {
|
||||
log.Formatter = new(logrus.JSONFormatter)
|
||||
log.Formatter = new(logrus.TextFormatter) // default
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err != nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"err": err,
|
||||
"number": 100,
|
||||
}).Fatal("The ice breaks!")
|
||||
}
|
||||
}()
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 122,
|
||||
}).Warn("The group's number increased tremendously!")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "orca",
|
||||
"size": 9009,
|
||||
}).Panic("It's over 9000!")
|
||||
}
|
35
vendor/github.com/Sirupsen/logrus/examples/hook/hook.go
generated
vendored
35
vendor/github.com/Sirupsen/logrus/examples/hook/hook.go
generated
vendored
@ -1,35 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus/hooks/airbrake"
|
||||
"github.com/tobi/airbrake-go"
|
||||
)
|
||||
|
||||
var log = logrus.New()
|
||||
|
||||
func init() {
|
||||
log.Formatter = new(logrus.TextFormatter) // default
|
||||
log.Hooks.Add(new(logrus_airbrake.AirbrakeHook))
|
||||
}
|
||||
|
||||
func main() {
|
||||
airbrake.Endpoint = "https://exceptions.whatever.com/notifier_api/v2/notices.xml"
|
||||
airbrake.ApiKey = "whatever"
|
||||
airbrake.Environment = "production"
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 122,
|
||||
}).Warn("The group's number increased tremendously!")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 100,
|
||||
}).Fatal("The ice breaks!")
|
||||
}
|
2
vendor/github.com/Sirupsen/logrus/exported.go
generated
vendored
2
vendor/github.com/Sirupsen/logrus/exported.go
generated
vendored
@ -36,6 +36,8 @@ func SetLevel(level Level) {
|
||||
|
||||
// GetLevel returns the standard logger level.
|
||||
func GetLevel() Level {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
return std.Level
|
||||
}
|
||||
|
||||
|
88
vendor/github.com/Sirupsen/logrus/formatter_bench_test.go
generated
vendored
88
vendor/github.com/Sirupsen/logrus/formatter_bench_test.go
generated
vendored
@ -1,88 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// smallFields is a small size data set for benchmarking
|
||||
var smallFields = Fields{
|
||||
"foo": "bar",
|
||||
"baz": "qux",
|
||||
"one": "two",
|
||||
"three": "four",
|
||||
}
|
||||
|
||||
// largeFields is a large size data set for benchmarking
|
||||
var largeFields = Fields{
|
||||
"foo": "bar",
|
||||
"baz": "qux",
|
||||
"one": "two",
|
||||
"three": "four",
|
||||
"five": "six",
|
||||
"seven": "eight",
|
||||
"nine": "ten",
|
||||
"eleven": "twelve",
|
||||
"thirteen": "fourteen",
|
||||
"fifteen": "sixteen",
|
||||
"seventeen": "eighteen",
|
||||
"nineteen": "twenty",
|
||||
"a": "b",
|
||||
"c": "d",
|
||||
"e": "f",
|
||||
"g": "h",
|
||||
"i": "j",
|
||||
"k": "l",
|
||||
"m": "n",
|
||||
"o": "p",
|
||||
"q": "r",
|
||||
"s": "t",
|
||||
"u": "v",
|
||||
"w": "x",
|
||||
"y": "z",
|
||||
"this": "will",
|
||||
"make": "thirty",
|
||||
"entries": "yeah",
|
||||
}
|
||||
|
||||
func BenchmarkSmallTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields)
|
||||
}
|
||||
|
||||
func BenchmarkLargeTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields)
|
||||
}
|
||||
|
||||
func BenchmarkSmallColoredTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields)
|
||||
}
|
||||
|
||||
func BenchmarkLargeColoredTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields)
|
||||
}
|
||||
|
||||
func BenchmarkSmallJSONFormatter(b *testing.B) {
|
||||
doBenchmark(b, &JSONFormatter{}, smallFields)
|
||||
}
|
||||
|
||||
func BenchmarkLargeJSONFormatter(b *testing.B) {
|
||||
doBenchmark(b, &JSONFormatter{}, largeFields)
|
||||
}
|
||||
|
||||
func doBenchmark(b *testing.B, formatter Formatter, fields Fields) {
|
||||
entry := &Entry{
|
||||
Time: time.Time{},
|
||||
Level: InfoLevel,
|
||||
Message: "message",
|
||||
Data: fields,
|
||||
}
|
||||
var d []byte
|
||||
var err error
|
||||
for i := 0; i < b.N; i++ {
|
||||
d, err = formatter.Format(entry)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(int64(len(d)))
|
||||
}
|
||||
}
|
122
vendor/github.com/Sirupsen/logrus/hook_test.go
generated
vendored
122
vendor/github.com/Sirupsen/logrus/hook_test.go
generated
vendored
@ -1,122 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type TestHook struct {
|
||||
Fired bool
|
||||
}
|
||||
|
||||
func (hook *TestHook) Fire(entry *Entry) error {
|
||||
hook.Fired = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *TestHook) Levels() []Level {
|
||||
return []Level{
|
||||
DebugLevel,
|
||||
InfoLevel,
|
||||
WarnLevel,
|
||||
ErrorLevel,
|
||||
FatalLevel,
|
||||
PanicLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func TestHookFires(t *testing.T) {
|
||||
hook := new(TestHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
assert.Equal(t, hook.Fired, false)
|
||||
|
||||
log.Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, hook.Fired, true)
|
||||
})
|
||||
}
|
||||
|
||||
type ModifyHook struct {
|
||||
}
|
||||
|
||||
func (hook *ModifyHook) Fire(entry *Entry) error {
|
||||
entry.Data["wow"] = "whale"
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *ModifyHook) Levels() []Level {
|
||||
return []Level{
|
||||
DebugLevel,
|
||||
InfoLevel,
|
||||
WarnLevel,
|
||||
ErrorLevel,
|
||||
FatalLevel,
|
||||
PanicLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func TestHookCanModifyEntry(t *testing.T) {
|
||||
hook := new(ModifyHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
log.WithField("wow", "elephant").Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["wow"], "whale")
|
||||
})
|
||||
}
|
||||
|
||||
func TestCanFireMultipleHooks(t *testing.T) {
|
||||
hook1 := new(ModifyHook)
|
||||
hook2 := new(TestHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook1)
|
||||
log.Hooks.Add(hook2)
|
||||
|
||||
log.WithField("wow", "elephant").Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["wow"], "whale")
|
||||
assert.Equal(t, hook2.Fired, true)
|
||||
})
|
||||
}
|
||||
|
||||
type ErrorHook struct {
|
||||
Fired bool
|
||||
}
|
||||
|
||||
func (hook *ErrorHook) Fire(entry *Entry) error {
|
||||
hook.Fired = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *ErrorHook) Levels() []Level {
|
||||
return []Level{
|
||||
ErrorLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorHookShouldntFireOnInfo(t *testing.T) {
|
||||
hook := new(ErrorHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
log.Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, hook.Fired, false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestErrorHookShouldFireOnError(t *testing.T) {
|
||||
hook := new(ErrorHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
log.Error("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, hook.Fired, true)
|
||||
})
|
||||
}
|
54
vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go
generated
vendored
54
vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go
generated
vendored
@ -1,54 +0,0 @@
|
||||
package logrus_airbrake
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/tobi/airbrake-go"
|
||||
)
|
||||
|
||||
// AirbrakeHook to send exceptions to an exception-tracking service compatible
|
||||
// with the Airbrake API. You must set:
|
||||
// * airbrake.Endpoint
|
||||
// * airbrake.ApiKey
|
||||
// * airbrake.Environment (only sends exceptions when set to "production")
|
||||
//
|
||||
// Before using this hook, to send an error. Entries that trigger an Error,
|
||||
// Fatal or Panic should now include an "error" field to send to Airbrake.
|
||||
type AirbrakeHook struct{}
|
||||
|
||||
func (hook *AirbrakeHook) Fire(entry *logrus.Entry) error {
|
||||
if entry.Data["error"] == nil {
|
||||
entry.Logger.WithFields(logrus.Fields{
|
||||
"source": "airbrake",
|
||||
"endpoint": airbrake.Endpoint,
|
||||
}).Warn("Exceptions sent to Airbrake must have an 'error' key with the error")
|
||||
return nil
|
||||
}
|
||||
|
||||
err, ok := entry.Data["error"].(error)
|
||||
if !ok {
|
||||
entry.Logger.WithFields(logrus.Fields{
|
||||
"source": "airbrake",
|
||||
"endpoint": airbrake.Endpoint,
|
||||
}).Warn("Exceptions sent to Airbrake must have an `error` key of type `error`")
|
||||
return nil
|
||||
}
|
||||
|
||||
airErr := airbrake.Notify(err)
|
||||
if airErr != nil {
|
||||
entry.Logger.WithFields(logrus.Fields{
|
||||
"source": "airbrake",
|
||||
"endpoint": airbrake.Endpoint,
|
||||
"error": airErr,
|
||||
}).Warn("Failed to send error to Airbrake")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *AirbrakeHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.ErrorLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.PanicLevel,
|
||||
}
|
||||
}
|
28
vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md
generated
vendored
28
vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md
generated
vendored
@ -1,28 +0,0 @@
|
||||
# Papertrail Hook for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:" />
|
||||
|
||||
[Papertrail](https://papertrailapp.com) provides hosted log management. Once stored in Papertrail, you can [group](http://help.papertrailapp.com/kb/how-it-works/groups/) your logs on various dimensions, [search](http://help.papertrailapp.com/kb/how-it-works/search-syntax) them, and trigger [alerts](http://help.papertrailapp.com/kb/how-it-works/alerts).
|
||||
|
||||
In most deployments, you'll want to send logs to Papertrail via their [remote_syslog](http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-text-log-files-in-unix/) daemon, which requires no application-specific configuration. This hook is intended for relatively low-volume logging, likely in managed cloud hosting deployments where installing `remote_syslog` is not possible.
|
||||
|
||||
## Usage
|
||||
|
||||
You can find your Papertrail UDP port on your [Papertrail account page](https://papertrailapp.com/account/destinations). Substitute it below for `YOUR_PAPERTRAIL_UDP_PORT`.
|
||||
|
||||
For `YOUR_APP_NAME`, substitute a short string that will readily identify your application or service in the logs.
|
||||
|
||||
```go
|
||||
import (
|
||||
"log/syslog"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus/hooks/papertrail"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
hook, err := logrus_papertrail.NewPapertrailHook("logs.papertrailapp.com", YOUR_PAPERTRAIL_UDP_PORT, YOUR_APP_NAME)
|
||||
|
||||
if err == nil {
|
||||
log.Hooks.Add(hook)
|
||||
}
|
||||
}
|
||||
```
|
55
vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
generated
vendored
55
vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
generated
vendored
@ -1,55 +0,0 @@
|
||||
package logrus_papertrail
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
format = "Jan 2 15:04:05"
|
||||
)
|
||||
|
||||
// PapertrailHook to send logs to a logging service compatible with the Papertrail API.
|
||||
type PapertrailHook struct {
|
||||
Host string
|
||||
Port int
|
||||
AppName string
|
||||
UDPConn net.Conn
|
||||
}
|
||||
|
||||
// NewPapertrailHook creates a hook to be added to an instance of logger.
|
||||
func NewPapertrailHook(host string, port int, appName string) (*PapertrailHook, error) {
|
||||
conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port))
|
||||
return &PapertrailHook{host, port, appName, conn}, err
|
||||
}
|
||||
|
||||
// Fire is called when a log event is fired.
|
||||
func (hook *PapertrailHook) Fire(entry *logrus.Entry) error {
|
||||
date := time.Now().Format(format)
|
||||
msg, _ := entry.String()
|
||||
payload := fmt.Sprintf("<22> %s %s: %s", date, hook.AppName, msg)
|
||||
|
||||
bytesWritten, err := hook.UDPConn.Write([]byte(payload))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to send log line to Papertrail via UDP. Wrote %d bytes before error: %v", bytesWritten, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Levels returns the available logging levels.
|
||||
func (hook *PapertrailHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.PanicLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.ErrorLevel,
|
||||
logrus.WarnLevel,
|
||||
logrus.InfoLevel,
|
||||
logrus.DebugLevel,
|
||||
}
|
||||
}
|
26
vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go
generated
vendored
26
vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
package logrus_papertrail
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/stvp/go-udp-testing"
|
||||
)
|
||||
|
||||
func TestWritingToUDP(t *testing.T) {
|
||||
port := 16661
|
||||
udp.SetAddr(fmt.Sprintf(":%d", port))
|
||||
|
||||
hook, err := NewPapertrailHook("localhost", port, "test")
|
||||
if err != nil {
|
||||
t.Errorf("Unable to connect to local UDP server.")
|
||||
}
|
||||
|
||||
log := logrus.New()
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
udp.ShouldReceive(t, "foo", func() {
|
||||
log.Info("foo")
|
||||
})
|
||||
}
|
61
vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md
generated
vendored
61
vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md
generated
vendored
@ -1,61 +0,0 @@
|
||||
# Sentry Hook for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:" />
|
||||
|
||||
[Sentry](https://getsentry.com) provides both self-hosted and hosted
|
||||
solutions for exception tracking.
|
||||
Both client and server are
|
||||
[open source](https://github.com/getsentry/sentry).
|
||||
|
||||
## Usage
|
||||
|
||||
Every sentry application defined on the server gets a different
|
||||
[DSN](https://www.getsentry.com/docs/). In the example below replace
|
||||
`YOUR_DSN` with the one created for your application.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus/hooks/sentry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
hook, err := logrus_sentry.NewSentryHook(YOUR_DSN, []logrus.Level{
|
||||
logrus.PanicLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.ErrorLevel,
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
log.Hooks.Add(hook)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Special fields
|
||||
|
||||
Some logrus fields have a special meaning in this hook,
|
||||
these are server_name and logger.
|
||||
When logs are sent to sentry these fields are treated differently.
|
||||
- server_name (also known as hostname) is the name of the server which
|
||||
is logging the event (hostname.example.com)
|
||||
- logger is the part of the application which is logging the event.
|
||||
In go this usually means setting it to the name of the package.
|
||||
|
||||
## Timeout
|
||||
|
||||
`Timeout` is the time the sentry hook will wait for a response
|
||||
from the sentry server.
|
||||
|
||||
If this time elapses with no response from
|
||||
the server an error will be returned.
|
||||
|
||||
If `Timeout` is set to 0 the SentryHook will not wait for a reply
|
||||
and will assume a correct delivery.
|
||||
|
||||
The SentryHook has a default timeout of `100 milliseconds` when created
|
||||
with a call to `NewSentryHook`. This can be changed by assigning a value to the `Timeout` field:
|
||||
|
||||
```go
|
||||
hook, _ := logrus_sentry.NewSentryHook(...)
|
||||
hook.Timeout = 20*time.Seconds
|
||||
```
|
100
vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go
generated
vendored
100
vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go
generated
vendored
@ -1,100 +0,0 @@
|
||||
package logrus_sentry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/getsentry/raven-go"
|
||||
)
|
||||
|
||||
var (
|
||||
severityMap = map[logrus.Level]raven.Severity{
|
||||
logrus.DebugLevel: raven.DEBUG,
|
||||
logrus.InfoLevel: raven.INFO,
|
||||
logrus.WarnLevel: raven.WARNING,
|
||||
logrus.ErrorLevel: raven.ERROR,
|
||||
logrus.FatalLevel: raven.FATAL,
|
||||
logrus.PanicLevel: raven.FATAL,
|
||||
}
|
||||
)
|
||||
|
||||
func getAndDel(d logrus.Fields, key string) (string, bool) {
|
||||
var (
|
||||
ok bool
|
||||
v interface{}
|
||||
val string
|
||||
)
|
||||
if v, ok = d[key]; !ok {
|
||||
return "", false
|
||||
}
|
||||
|
||||
if val, ok = v.(string); !ok {
|
||||
return "", false
|
||||
}
|
||||
delete(d, key)
|
||||
return val, true
|
||||
}
|
||||
|
||||
// SentryHook delivers logs to a sentry server.
|
||||
type SentryHook struct {
|
||||
// Timeout sets the time to wait for a delivery error from the sentry server.
|
||||
// If this is set to zero the server will not wait for any response and will
|
||||
// consider the message correctly sent
|
||||
Timeout time.Duration
|
||||
|
||||
client *raven.Client
|
||||
levels []logrus.Level
|
||||
}
|
||||
|
||||
// NewSentryHook creates a hook to be added to an instance of logger
|
||||
// and initializes the raven client.
|
||||
// This method sets the timeout to 100 milliseconds.
|
||||
func NewSentryHook(DSN string, levels []logrus.Level) (*SentryHook, error) {
|
||||
client, err := raven.NewClient(DSN, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &SentryHook{100 * time.Millisecond, client, levels}, nil
|
||||
}
|
||||
|
||||
// Called when an event should be sent to sentry
|
||||
// Special fields that sentry uses to give more information to the server
|
||||
// are extracted from entry.Data (if they are found)
|
||||
// These fields are: logger and server_name
|
||||
func (hook *SentryHook) Fire(entry *logrus.Entry) error {
|
||||
packet := &raven.Packet{
|
||||
Message: entry.Message,
|
||||
Timestamp: raven.Timestamp(entry.Time),
|
||||
Level: severityMap[entry.Level],
|
||||
Platform: "go",
|
||||
}
|
||||
|
||||
d := entry.Data
|
||||
|
||||
if logger, ok := getAndDel(d, "logger"); ok {
|
||||
packet.Logger = logger
|
||||
}
|
||||
if serverName, ok := getAndDel(d, "server_name"); ok {
|
||||
packet.ServerName = serverName
|
||||
}
|
||||
packet.Extra = map[string]interface{}(d)
|
||||
|
||||
_, errCh := hook.client.Capture(packet, nil)
|
||||
timeout := hook.Timeout
|
||||
if timeout != 0 {
|
||||
timeoutCh := time.After(timeout)
|
||||
select {
|
||||
case err := <-errCh:
|
||||
return err
|
||||
case <-timeoutCh:
|
||||
return fmt.Errorf("no response from sentry server in %s", timeout)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Levels returns the available logging levels.
|
||||
func (hook *SentryHook) Levels() []logrus.Level {
|
||||
return hook.levels
|
||||
}
|
97
vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry_test.go
generated
vendored
97
vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry_test.go
generated
vendored
@ -1,97 +0,0 @@
|
||||
package logrus_sentry
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/getsentry/raven-go"
|
||||
)
|
||||
|
||||
const (
|
||||
message = "error message"
|
||||
server_name = "testserver.internal"
|
||||
logger_name = "test.logger"
|
||||
)
|
||||
|
||||
func getTestLogger() *logrus.Logger {
|
||||
l := logrus.New()
|
||||
l.Out = ioutil.Discard
|
||||
return l
|
||||
}
|
||||
|
||||
func WithTestDSN(t *testing.T, tf func(string, <-chan *raven.Packet)) {
|
||||
pch := make(chan *raven.Packet, 1)
|
||||
s := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
defer req.Body.Close()
|
||||
d := json.NewDecoder(req.Body)
|
||||
p := &raven.Packet{}
|
||||
err := d.Decode(p)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
pch <- p
|
||||
}))
|
||||
defer s.Close()
|
||||
|
||||
fragments := strings.SplitN(s.URL, "://", 2)
|
||||
dsn := fmt.Sprintf(
|
||||
"%s://public:secret@%s/sentry/project-id",
|
||||
fragments[0],
|
||||
fragments[1],
|
||||
)
|
||||
tf(dsn, pch)
|
||||
}
|
||||
|
||||
func TestSpecialFields(t *testing.T) {
|
||||
WithTestDSN(t, func(dsn string, pch <-chan *raven.Packet) {
|
||||
logger := getTestLogger()
|
||||
|
||||
hook, err := NewSentryHook(dsn, []logrus.Level{
|
||||
logrus.ErrorLevel,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
logger.Hooks.Add(hook)
|
||||
logger.WithFields(logrus.Fields{
|
||||
"server_name": server_name,
|
||||
"logger": logger_name,
|
||||
}).Error(message)
|
||||
|
||||
packet := <-pch
|
||||
if packet.Logger != logger_name {
|
||||
t.Errorf("logger should have been %s, was %s", logger_name, packet.Logger)
|
||||
}
|
||||
|
||||
if packet.ServerName != server_name {
|
||||
t.Errorf("server_name should have been %s, was %s", server_name, packet.ServerName)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSentryHandler(t *testing.T) {
|
||||
WithTestDSN(t, func(dsn string, pch <-chan *raven.Packet) {
|
||||
logger := getTestLogger()
|
||||
hook, err := NewSentryHook(dsn, []logrus.Level{
|
||||
logrus.ErrorLevel,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
logger.Hooks.Add(hook)
|
||||
|
||||
logger.Error(message)
|
||||
packet := <-pch
|
||||
if packet.Message != message {
|
||||
t.Errorf("message should have been %s, was %s", message, packet.Message)
|
||||
}
|
||||
})
|
||||
}
|
20
vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
generated
vendored
20
vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
generated
vendored
@ -1,20 +0,0 @@
|
||||
# Syslog Hooks for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
import (
|
||||
"log/syslog"
|
||||
"github.com/Sirupsen/logrus"
|
||||
logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||
|
||||
if err == nil {
|
||||
log.Hooks.Add(hook)
|
||||
}
|
||||
}
|
||||
```
|
59
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
59
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
@ -1,59 +0,0 @@
|
||||
package logrus_syslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"log/syslog"
|
||||
"os"
|
||||
)
|
||||
|
||||
// SyslogHook to send logs via syslog.
|
||||
type SyslogHook struct {
|
||||
Writer *syslog.Writer
|
||||
SyslogNetwork string
|
||||
SyslogRaddr string
|
||||
}
|
||||
|
||||
// Creates a hook to be added to an instance of logger. This is called with
|
||||
// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
|
||||
// `if err == nil { log.Hooks.Add(hook) }`
|
||||
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
|
||||
w, err := syslog.Dial(network, raddr, priority, tag)
|
||||
return &SyslogHook{w, network, raddr}, err
|
||||
}
|
||||
|
||||
func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
|
||||
line, err := entry.String()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
switch entry.Level {
|
||||
case logrus.PanicLevel:
|
||||
return hook.Writer.Crit(line)
|
||||
case logrus.FatalLevel:
|
||||
return hook.Writer.Crit(line)
|
||||
case logrus.ErrorLevel:
|
||||
return hook.Writer.Err(line)
|
||||
case logrus.WarnLevel:
|
||||
return hook.Writer.Warning(line)
|
||||
case logrus.InfoLevel:
|
||||
return hook.Writer.Info(line)
|
||||
case logrus.DebugLevel:
|
||||
return hook.Writer.Debug(line)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (hook *SyslogHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.PanicLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.ErrorLevel,
|
||||
logrus.WarnLevel,
|
||||
logrus.InfoLevel,
|
||||
logrus.DebugLevel,
|
||||
}
|
||||
}
|
26
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
26
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
package logrus_syslog
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"log/syslog"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLocalhostAddAndPrint(t *testing.T) {
|
||||
log := logrus.New()
|
||||
hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Unable to connect to local syslog.")
|
||||
}
|
||||
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
for _, level := range hook.Levels() {
|
||||
if len(log.Hooks[level]) != 1 {
|
||||
t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level]))
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("Congratulations!")
|
||||
}
|
8
vendor/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
8
vendor/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
@ -11,7 +11,13 @@ type JSONFormatter struct{}
|
||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
data := make(Fields, len(entry.Data)+3)
|
||||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
// Otherwise errors are ignored by `encoding/json`
|
||||
// https://github.com/Sirupsen/logrus/issues/137
|
||||
if err, ok := v.(error); ok {
|
||||
data[k] = err.Error()
|
||||
} else {
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
prefixFieldClashes(data)
|
||||
data["time"] = entry.Time.Format(time.RFC3339)
|
||||
|
283
vendor/github.com/Sirupsen/logrus/logrus_test.go
generated
vendored
283
vendor/github.com/Sirupsen/logrus/logrus_test.go
generated
vendored
@ -1,283 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) {
|
||||
var buffer bytes.Buffer
|
||||
var fields Fields
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = new(JSONFormatter)
|
||||
|
||||
log(logger)
|
||||
|
||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assertions(fields)
|
||||
}
|
||||
|
||||
func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = &TextFormatter{
|
||||
DisableColors: true,
|
||||
}
|
||||
|
||||
log(logger)
|
||||
|
||||
fields := make(map[string]string)
|
||||
for _, kv := range strings.Split(buffer.String(), " ") {
|
||||
if !strings.Contains(kv, "=") {
|
||||
continue
|
||||
}
|
||||
kvArr := strings.Split(kv, "=")
|
||||
key := strings.TrimSpace(kvArr[0])
|
||||
val := kvArr[1]
|
||||
if kvArr[1][0] == '"' {
|
||||
var err error
|
||||
val, err = strconv.Unquote(val)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
fields[key] = val
|
||||
}
|
||||
assertions(fields)
|
||||
}
|
||||
|
||||
func TestPrint(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["level"], "info")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfo(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["level"], "info")
|
||||
})
|
||||
}
|
||||
|
||||
func TestWarn(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Warn("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["level"], "warning")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln("test", "test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test test")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln("test", 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test 10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln(10, 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "10 10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln(10, 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "10 10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Info("test", 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Info("test", "test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "testtest")
|
||||
})
|
||||
}
|
||||
|
||||
func TestWithFieldsShouldAllowAssignments(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
var fields Fields
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = new(JSONFormatter)
|
||||
|
||||
localLog := logger.WithFields(Fields{
|
||||
"key1": "value1",
|
||||
})
|
||||
|
||||
localLog.WithField("key2", "value2").Info("test")
|
||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, "value2", fields["key2"])
|
||||
assert.Equal(t, "value1", fields["key1"])
|
||||
|
||||
buffer = bytes.Buffer{}
|
||||
fields = Fields{}
|
||||
localLog.Info("test")
|
||||
err = json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, ok := fields["key2"]
|
||||
assert.Equal(t, false, ok)
|
||||
assert.Equal(t, "value1", fields["key1"])
|
||||
}
|
||||
|
||||
func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("msg", "hello").Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("msg", "hello").Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["fields.msg"], "hello")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("time", "hello").Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["fields.time"], "hello")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("level", 1).Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["level"], "info")
|
||||
assert.Equal(t, fields["fields.level"], 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDefaultFieldsAreNotPrefixed(t *testing.T) {
|
||||
LogAndAssertText(t, func(log *Logger) {
|
||||
ll := log.WithField("herp", "derp")
|
||||
ll.Info("hello")
|
||||
ll.Info("bye")
|
||||
}, func(fields map[string]string) {
|
||||
for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} {
|
||||
if _, ok := fields[fieldName]; ok {
|
||||
t.Fatalf("should not have prefixed %q: %v", fieldName, fields)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
|
||||
|
||||
var buffer bytes.Buffer
|
||||
var fields Fields
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = new(JSONFormatter)
|
||||
|
||||
llog := logger.WithField("context", "eating raw fish")
|
||||
|
||||
llog.Info("looks delicious")
|
||||
|
||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.NoError(t, err, "should have decoded first message")
|
||||
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
|
||||
assert.Equal(t, fields["msg"], "looks delicious")
|
||||
assert.Equal(t, fields["context"], "eating raw fish")
|
||||
|
||||
buffer.Reset()
|
||||
|
||||
llog.Warn("omg it is!")
|
||||
|
||||
err = json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.NoError(t, err, "should have decoded second message")
|
||||
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
|
||||
assert.Equal(t, fields["msg"], "omg it is!")
|
||||
assert.Equal(t, fields["context"], "eating raw fish")
|
||||
assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
|
||||
|
||||
}
|
||||
|
||||
func TestConvertLevelToString(t *testing.T) {
|
||||
assert.Equal(t, "debug", DebugLevel.String())
|
||||
assert.Equal(t, "info", InfoLevel.String())
|
||||
assert.Equal(t, "warning", WarnLevel.String())
|
||||
assert.Equal(t, "error", ErrorLevel.String())
|
||||
assert.Equal(t, "fatal", FatalLevel.String())
|
||||
assert.Equal(t, "panic", PanicLevel.String())
|
||||
}
|
||||
|
||||
func TestParseLevel(t *testing.T) {
|
||||
l, err := ParseLevel("panic")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, PanicLevel, l)
|
||||
|
||||
l, err = ParseLevel("fatal")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, FatalLevel, l)
|
||||
|
||||
l, err = ParseLevel("error")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, ErrorLevel, l)
|
||||
|
||||
l, err = ParseLevel("warn")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, WarnLevel, l)
|
||||
|
||||
l, err = ParseLevel("warning")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, WarnLevel, l)
|
||||
|
||||
l, err = ParseLevel("info")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, InfoLevel, l)
|
||||
|
||||
l, err = ParseLevel("debug")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, DebugLevel, l)
|
||||
|
||||
l, err = ParseLevel("invalid")
|
||||
assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
|
||||
}
|
39
vendor/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
39
vendor/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
@ -15,6 +15,7 @@ const (
|
||||
green = 32
|
||||
yellow = 33
|
||||
blue = 34
|
||||
gray = 37
|
||||
)
|
||||
|
||||
var (
|
||||
@ -34,20 +35,34 @@ func miniTS() int {
|
||||
|
||||
type TextFormatter struct {
|
||||
// Set to true to bypass checking for a TTY before outputting colors.
|
||||
ForceColors bool
|
||||
ForceColors bool
|
||||
|
||||
// Force disabling colors.
|
||||
DisableColors bool
|
||||
// Set to true to disable timestamp logging (useful when the output
|
||||
// is redirected to a logging system already adding a timestamp)
|
||||
|
||||
// Disable timestamp logging. useful when output is redirected to logging
|
||||
// system that already adds timestamps.
|
||||
DisableTimestamp bool
|
||||
|
||||
// Enable logging the full timestamp when a TTY is attached instead of just
|
||||
// the time passed since beginning of execution.
|
||||
FullTimestamp bool
|
||||
|
||||
// The fields are sorted by default for a consistent output. For applications
|
||||
// that log extremely frequently and don't use the JSON formatter this may not
|
||||
// be desired.
|
||||
DisableSorting bool
|
||||
}
|
||||
|
||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
|
||||
var keys []string = make([]string, 0, len(entry.Data))
|
||||
for k := range entry.Data {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
if !f.DisableSorting {
|
||||
sort.Strings(keys)
|
||||
}
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
|
||||
@ -56,7 +71,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
isColored := (f.ForceColors || isTerminal) && !f.DisableColors
|
||||
|
||||
if isColored {
|
||||
printColored(b, entry, keys)
|
||||
f.printColored(b, entry, keys)
|
||||
} else {
|
||||
if !f.DisableTimestamp {
|
||||
f.appendKeyValue(b, "time", entry.Time.Format(time.RFC3339))
|
||||
@ -72,9 +87,11 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func printColored(b *bytes.Buffer, entry *Entry, keys []string) {
|
||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string) {
|
||||
var levelColor int
|
||||
switch entry.Level {
|
||||
case DebugLevel:
|
||||
levelColor = gray
|
||||
case WarnLevel:
|
||||
levelColor = yellow
|
||||
case ErrorLevel, FatalLevel, PanicLevel:
|
||||
@ -85,7 +102,11 @@ func printColored(b *bytes.Buffer, entry *Entry, keys []string) {
|
||||
|
||||
levelText := strings.ToUpper(entry.Level.String())[0:4]
|
||||
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message)
|
||||
if !f.FullTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message)
|
||||
} else {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(time.RFC3339), entry.Message)
|
||||
}
|
||||
for _, k := range keys {
|
||||
v := entry.Data[k]
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%v", levelColor, k, v)
|
||||
@ -96,7 +117,7 @@ func needsQuoting(text string) bool {
|
||||
for _, ch := range text {
|
||||
if !((ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= '0' && ch < '9') ||
|
||||
(ch >= '0' && ch <= '9') ||
|
||||
ch == '-' || ch == '.') {
|
||||
return false
|
||||
}
|
||||
|
33
vendor/github.com/Sirupsen/logrus/text_formatter_test.go
generated
vendored
33
vendor/github.com/Sirupsen/logrus/text_formatter_test.go
generated
vendored
@ -1,33 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestQuoting(t *testing.T) {
|
||||
tf := &TextFormatter{DisableColors: true}
|
||||
|
||||
checkQuoting := func(q bool, value interface{}) {
|
||||
b, _ := tf.Format(WithField("test", value))
|
||||
idx := bytes.Index(b, ([]byte)("test="))
|
||||
cont := bytes.Contains(b[idx+5:], []byte{'"'})
|
||||
if cont != q {
|
||||
if q {
|
||||
t.Errorf("quoting expected for: %#v", value)
|
||||
} else {
|
||||
t.Errorf("quoting not expected for: %#v", value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkQuoting(false, "abcd")
|
||||
checkQuoting(false, "v1.0")
|
||||
checkQuoting(true, "/foobar")
|
||||
checkQuoting(true, "x y")
|
||||
checkQuoting(true, "x,y")
|
||||
checkQuoting(false, errors.New("invalid"))
|
||||
checkQuoting(true, errors.New("invalid argument"))
|
||||
}
|
31
vendor/github.com/codegangsta/cli/README.md
generated
vendored
31
vendor/github.com/codegangsta/cli/README.md
generated
vendored
@ -1,11 +1,10 @@
|
||||
[](http://gocover.io/github.com/codegangsta/cli)
|
||||
[](https://travis-ci.org/codegangsta/cli)
|
||||
[](https://godoc.org/github.com/codegangsta/cli)
|
||||
|
||||
# cli.go
|
||||
`cli.go` is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way.
|
||||
|
||||
You can view the API docs here:
|
||||
http://godoc.org/github.com/codegangsta/cli
|
||||
|
||||
## Overview
|
||||
Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app.
|
||||
|
||||
@ -159,6 +158,32 @@ app.Action = func(c *cli.Context) {
|
||||
...
|
||||
```
|
||||
|
||||
You can also set a destination variable for a flag, to which the content will be scanned.
|
||||
``` go
|
||||
...
|
||||
var language string
|
||||
app.Flags = []cli.Flag {
|
||||
cli.StringFlag{
|
||||
Name: "lang",
|
||||
Value: "english",
|
||||
Usage: "language for the greeting",
|
||||
Destination: &language,
|
||||
},
|
||||
}
|
||||
app.Action = func(c *cli.Context) {
|
||||
name := "someone"
|
||||
if len(c.Args()) > 0 {
|
||||
name = c.Args()[0]
|
||||
}
|
||||
if language == "spanish" {
|
||||
println("Hola", name)
|
||||
} else {
|
||||
println("Hello", name)
|
||||
}
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
See full list of flags at http://godoc.org/github.com/codegangsta/cli
|
||||
|
||||
#### Alternate Names
|
||||
|
960
vendor/github.com/codegangsta/cli/app_test.go
generated
vendored
960
vendor/github.com/codegangsta/cli/app_test.go
generated
vendored
@ -1,960 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func ExampleApp() {
|
||||
// set args for examples sake
|
||||
os.Args = []string{"greet", "--name", "Jeremy"}
|
||||
|
||||
app := NewApp()
|
||||
app.Name = "greet"
|
||||
app.Flags = []Flag{
|
||||
StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
|
||||
}
|
||||
app.Action = func(c *Context) {
|
||||
fmt.Printf("Hello %v\n", c.String("name"))
|
||||
}
|
||||
app.Author = "Harrison"
|
||||
app.Email = "harrison@lolwut.com"
|
||||
app.Authors = []Author{Author{Name: "Oliver Allen", Email: "oliver@toyshop.com"}}
|
||||
app.Run(os.Args)
|
||||
// Output:
|
||||
// Hello Jeremy
|
||||
}
|
||||
|
||||
func ExampleAppSubcommand() {
|
||||
// set args for examples sake
|
||||
os.Args = []string{"say", "hi", "english", "--name", "Jeremy"}
|
||||
app := NewApp()
|
||||
app.Name = "say"
|
||||
app.Commands = []Command{
|
||||
{
|
||||
Name: "hello",
|
||||
Aliases: []string{"hi"},
|
||||
Usage: "use it to see a description",
|
||||
Description: "This is how we describe hello the function",
|
||||
Subcommands: []Command{
|
||||
{
|
||||
Name: "english",
|
||||
Aliases: []string{"en"},
|
||||
Usage: "sends a greeting in english",
|
||||
Description: "greets someone in english",
|
||||
Flags: []Flag{
|
||||
StringFlag{
|
||||
Name: "name",
|
||||
Value: "Bob",
|
||||
Usage: "Name of the person to greet",
|
||||
},
|
||||
},
|
||||
Action: func(c *Context) {
|
||||
fmt.Println("Hello,", c.String("name"))
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run(os.Args)
|
||||
// Output:
|
||||
// Hello, Jeremy
|
||||
}
|
||||
|
||||
func ExampleAppHelp() {
|
||||
// set args for examples sake
|
||||
os.Args = []string{"greet", "h", "describeit"}
|
||||
|
||||
app := NewApp()
|
||||
app.Name = "greet"
|
||||
app.Flags = []Flag{
|
||||
StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
|
||||
}
|
||||
app.Commands = []Command{
|
||||
{
|
||||
Name: "describeit",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "use it to see a description",
|
||||
Description: "This is how we describe describeit the function",
|
||||
Action: func(c *Context) {
|
||||
fmt.Printf("i like to describe things")
|
||||
},
|
||||
},
|
||||
}
|
||||
app.Run(os.Args)
|
||||
// Output:
|
||||
// NAME:
|
||||
// greet describeit - use it to see a description
|
||||
//
|
||||
// USAGE:
|
||||
// greet describeit [arguments...]
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// This is how we describe describeit the function
|
||||
}
|
||||
|
||||
func ExampleAppBashComplete() {
|
||||
// set args for examples sake
|
||||
os.Args = []string{"greet", "--generate-bash-completion"}
|
||||
|
||||
app := NewApp()
|
||||
app.Name = "greet"
|
||||
app.EnableBashCompletion = true
|
||||
app.Commands = []Command{
|
||||
{
|
||||
Name: "describeit",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "use it to see a description",
|
||||
Description: "This is how we describe describeit the function",
|
||||
Action: func(c *Context) {
|
||||
fmt.Printf("i like to describe things")
|
||||
},
|
||||
}, {
|
||||
Name: "next",
|
||||
Usage: "next example",
|
||||
Description: "more stuff to see when generating bash completion",
|
||||
Action: func(c *Context) {
|
||||
fmt.Printf("the next example")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run(os.Args)
|
||||
// Output:
|
||||
// describeit
|
||||
// d
|
||||
// next
|
||||
// help
|
||||
// h
|
||||
}
|
||||
|
||||
func TestApp_Run(t *testing.T) {
|
||||
s := ""
|
||||
|
||||
app := NewApp()
|
||||
app.Action = func(c *Context) {
|
||||
s = s + c.Args().First()
|
||||
}
|
||||
|
||||
err := app.Run([]string{"command", "foo"})
|
||||
expect(t, err, nil)
|
||||
err = app.Run([]string{"command", "bar"})
|
||||
expect(t, err, nil)
|
||||
expect(t, s, "foobar")
|
||||
}
|
||||
|
||||
var commandAppTests = []struct {
|
||||
name string
|
||||
expected bool
|
||||
}{
|
||||
{"foobar", true},
|
||||
{"batbaz", true},
|
||||
{"b", true},
|
||||
{"f", true},
|
||||
{"bat", false},
|
||||
{"nothing", false},
|
||||
}
|
||||
|
||||
func TestApp_Command(t *testing.T) {
|
||||
app := NewApp()
|
||||
fooCommand := Command{Name: "foobar", Aliases: []string{"f"}}
|
||||
batCommand := Command{Name: "batbaz", Aliases: []string{"b"}}
|
||||
app.Commands = []Command{
|
||||
fooCommand,
|
||||
batCommand,
|
||||
}
|
||||
|
||||
for _, test := range commandAppTests {
|
||||
expect(t, app.Command(test.name) != nil, test.expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_CommandWithArgBeforeFlags(t *testing.T) {
|
||||
var parsedOption, firstArg string
|
||||
|
||||
app := NewApp()
|
||||
command := Command{
|
||||
Name: "cmd",
|
||||
Flags: []Flag{
|
||||
StringFlag{Name: "option", Value: "", Usage: "some option"},
|
||||
},
|
||||
Action: func(c *Context) {
|
||||
parsedOption = c.String("option")
|
||||
firstArg = c.Args().First()
|
||||
},
|
||||
}
|
||||
app.Commands = []Command{command}
|
||||
|
||||
app.Run([]string{"", "cmd", "my-arg", "--option", "my-option"})
|
||||
|
||||
expect(t, parsedOption, "my-option")
|
||||
expect(t, firstArg, "my-arg")
|
||||
}
|
||||
|
||||
func TestApp_RunAsSubcommandParseFlags(t *testing.T) {
|
||||
var context *Context
|
||||
|
||||
a := NewApp()
|
||||
a.Commands = []Command{
|
||||
{
|
||||
Name: "foo",
|
||||
Action: func(c *Context) {
|
||||
context = c
|
||||
},
|
||||
Flags: []Flag{
|
||||
StringFlag{
|
||||
Name: "lang",
|
||||
Value: "english",
|
||||
Usage: "language for the greeting",
|
||||
},
|
||||
},
|
||||
Before: func(_ *Context) error { return nil },
|
||||
},
|
||||
}
|
||||
a.Run([]string{"", "foo", "--lang", "spanish", "abcd"})
|
||||
|
||||
expect(t, context.Args().Get(0), "abcd")
|
||||
expect(t, context.String("lang"), "spanish")
|
||||
}
|
||||
|
||||
func TestApp_CommandWithFlagBeforeTerminator(t *testing.T) {
|
||||
var parsedOption string
|
||||
var args []string
|
||||
|
||||
app := NewApp()
|
||||
command := Command{
|
||||
Name: "cmd",
|
||||
Flags: []Flag{
|
||||
StringFlag{Name: "option", Value: "", Usage: "some option"},
|
||||
},
|
||||
Action: func(c *Context) {
|
||||
parsedOption = c.String("option")
|
||||
args = c.Args()
|
||||
},
|
||||
}
|
||||
app.Commands = []Command{command}
|
||||
|
||||
app.Run([]string{"", "cmd", "my-arg", "--option", "my-option", "--", "--notARealFlag"})
|
||||
|
||||
expect(t, parsedOption, "my-option")
|
||||
expect(t, args[0], "my-arg")
|
||||
expect(t, args[1], "--")
|
||||
expect(t, args[2], "--notARealFlag")
|
||||
}
|
||||
|
||||
func TestApp_CommandWithNoFlagBeforeTerminator(t *testing.T) {
|
||||
var args []string
|
||||
|
||||
app := NewApp()
|
||||
command := Command{
|
||||
Name: "cmd",
|
||||
Action: func(c *Context) {
|
||||
args = c.Args()
|
||||
},
|
||||
}
|
||||
app.Commands = []Command{command}
|
||||
|
||||
app.Run([]string{"", "cmd", "my-arg", "--", "notAFlagAtAll"})
|
||||
|
||||
expect(t, args[0], "my-arg")
|
||||
expect(t, args[1], "--")
|
||||
expect(t, args[2], "notAFlagAtAll")
|
||||
}
|
||||
|
||||
func TestApp_Float64Flag(t *testing.T) {
|
||||
var meters float64
|
||||
|
||||
app := NewApp()
|
||||
app.Flags = []Flag{
|
||||
Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"},
|
||||
}
|
||||
app.Action = func(c *Context) {
|
||||
meters = c.Float64("height")
|
||||
}
|
||||
|
||||
app.Run([]string{"", "--height", "1.93"})
|
||||
expect(t, meters, 1.93)
|
||||
}
|
||||
|
||||
func TestApp_ParseSliceFlags(t *testing.T) {
|
||||
var parsedOption, firstArg string
|
||||
var parsedIntSlice []int
|
||||
var parsedStringSlice []string
|
||||
|
||||
app := NewApp()
|
||||
command := Command{
|
||||
Name: "cmd",
|
||||
Flags: []Flag{
|
||||
IntSliceFlag{Name: "p", Value: &IntSlice{}, Usage: "set one or more ip addr"},
|
||||
StringSliceFlag{Name: "ip", Value: &StringSlice{}, Usage: "set one or more ports to open"},
|
||||
},
|
||||
Action: func(c *Context) {
|
||||
parsedIntSlice = c.IntSlice("p")
|
||||
parsedStringSlice = c.StringSlice("ip")
|
||||
parsedOption = c.String("option")
|
||||
firstArg = c.Args().First()
|
||||
},
|
||||
}
|
||||
app.Commands = []Command{command}
|
||||
|
||||
app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"})
|
||||
|
||||
IntsEquals := func(a, b []int) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i, v := range a {
|
||||
if v != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
StrsEquals := func(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i, v := range a {
|
||||
if v != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
var expectedIntSlice = []int{22, 80}
|
||||
var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"}
|
||||
|
||||
if !IntsEquals(parsedIntSlice, expectedIntSlice) {
|
||||
t.Errorf("%v does not match %v", parsedIntSlice, expectedIntSlice)
|
||||
}
|
||||
|
||||
if !StrsEquals(parsedStringSlice, expectedStringSlice) {
|
||||
t.Errorf("%v does not match %v", parsedStringSlice, expectedStringSlice)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_ParseSliceFlagsWithMissingValue(t *testing.T) {
|
||||
var parsedIntSlice []int
|
||||
var parsedStringSlice []string
|
||||
|
||||
app := NewApp()
|
||||
command := Command{
|
||||
Name: "cmd",
|
||||
Flags: []Flag{
|
||||
IntSliceFlag{Name: "a", Usage: "set numbers"},
|
||||
StringSliceFlag{Name: "str", Usage: "set strings"},
|
||||
},
|
||||
Action: func(c *Context) {
|
||||
parsedIntSlice = c.IntSlice("a")
|
||||
parsedStringSlice = c.StringSlice("str")
|
||||
},
|
||||
}
|
||||
app.Commands = []Command{command}
|
||||
|
||||
app.Run([]string{"", "cmd", "my-arg", "-a", "2", "-str", "A"})
|
||||
|
||||
var expectedIntSlice = []int{2}
|
||||
var expectedStringSlice = []string{"A"}
|
||||
|
||||
if parsedIntSlice[0] != expectedIntSlice[0] {
|
||||
t.Errorf("%v does not match %v", parsedIntSlice[0], expectedIntSlice[0])
|
||||
}
|
||||
|
||||
if parsedStringSlice[0] != expectedStringSlice[0] {
|
||||
t.Errorf("%v does not match %v", parsedIntSlice[0], expectedIntSlice[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_DefaultStdout(t *testing.T) {
|
||||
app := NewApp()
|
||||
|
||||
if app.Writer != os.Stdout {
|
||||
t.Error("Default output writer not set.")
|
||||
}
|
||||
}
|
||||
|
||||
type mockWriter struct {
|
||||
written []byte
|
||||
}
|
||||
|
||||
func (fw *mockWriter) Write(p []byte) (n int, err error) {
|
||||
if fw.written == nil {
|
||||
fw.written = p
|
||||
} else {
|
||||
fw.written = append(fw.written, p...)
|
||||
}
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (fw *mockWriter) GetWritten() (b []byte) {
|
||||
return fw.written
|
||||
}
|
||||
|
||||
func TestApp_SetStdout(t *testing.T) {
|
||||
w := &mockWriter{}
|
||||
|
||||
app := NewApp()
|
||||
app.Name = "test"
|
||||
app.Writer = w
|
||||
|
||||
err := app.Run([]string{"help"})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Run error: %s", err)
|
||||
}
|
||||
|
||||
if len(w.written) == 0 {
|
||||
t.Error("App did not write output to desired writer.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_BeforeFunc(t *testing.T) {
|
||||
beforeRun, subcommandRun := false, false
|
||||
beforeError := fmt.Errorf("fail")
|
||||
var err error
|
||||
|
||||
app := NewApp()
|
||||
|
||||
app.Before = func(c *Context) error {
|
||||
beforeRun = true
|
||||
s := c.String("opt")
|
||||
if s == "fail" {
|
||||
return beforeError
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
app.Commands = []Command{
|
||||
Command{
|
||||
Name: "sub",
|
||||
Action: func(c *Context) {
|
||||
subcommandRun = true
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Flags = []Flag{
|
||||
StringFlag{Name: "opt"},
|
||||
}
|
||||
|
||||
// run with the Before() func succeeding
|
||||
err = app.Run([]string{"command", "--opt", "succeed", "sub"})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Run error: %s", err)
|
||||
}
|
||||
|
||||
if beforeRun == false {
|
||||
t.Errorf("Before() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == false {
|
||||
t.Errorf("Subcommand not executed when expected")
|
||||
}
|
||||
|
||||
// reset
|
||||
beforeRun, subcommandRun = false, false
|
||||
|
||||
// run with the Before() func failing
|
||||
err = app.Run([]string{"command", "--opt", "fail", "sub"})
|
||||
|
||||
// should be the same error produced by the Before func
|
||||
if err != beforeError {
|
||||
t.Errorf("Run error expected, but not received")
|
||||
}
|
||||
|
||||
if beforeRun == false {
|
||||
t.Errorf("Before() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == true {
|
||||
t.Errorf("Subcommand executed when NOT expected")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestApp_AfterFunc(t *testing.T) {
|
||||
afterRun, subcommandRun := false, false
|
||||
afterError := fmt.Errorf("fail")
|
||||
var err error
|
||||
|
||||
app := NewApp()
|
||||
|
||||
app.After = func(c *Context) error {
|
||||
afterRun = true
|
||||
s := c.String("opt")
|
||||
if s == "fail" {
|
||||
return afterError
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
app.Commands = []Command{
|
||||
Command{
|
||||
Name: "sub",
|
||||
Action: func(c *Context) {
|
||||
subcommandRun = true
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Flags = []Flag{
|
||||
StringFlag{Name: "opt"},
|
||||
}
|
||||
|
||||
// run with the After() func succeeding
|
||||
err = app.Run([]string{"command", "--opt", "succeed", "sub"})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Run error: %s", err)
|
||||
}
|
||||
|
||||
if afterRun == false {
|
||||
t.Errorf("After() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == false {
|
||||
t.Errorf("Subcommand not executed when expected")
|
||||
}
|
||||
|
||||
// reset
|
||||
afterRun, subcommandRun = false, false
|
||||
|
||||
// run with the Before() func failing
|
||||
err = app.Run([]string{"command", "--opt", "fail", "sub"})
|
||||
|
||||
// should be the same error produced by the Before func
|
||||
if err != afterError {
|
||||
t.Errorf("Run error expected, but not received")
|
||||
}
|
||||
|
||||
if afterRun == false {
|
||||
t.Errorf("After() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == false {
|
||||
t.Errorf("Subcommand not executed when expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppNoHelpFlag(t *testing.T) {
|
||||
oldFlag := HelpFlag
|
||||
defer func() {
|
||||
HelpFlag = oldFlag
|
||||
}()
|
||||
|
||||
HelpFlag = BoolFlag{}
|
||||
|
||||
app := NewApp()
|
||||
err := app.Run([]string{"test", "-h"})
|
||||
|
||||
if err != flag.ErrHelp {
|
||||
t.Errorf("expected error about missing help flag, but got: %s (%T)", err, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppHelpPrinter(t *testing.T) {
|
||||
oldPrinter := HelpPrinter
|
||||
defer func() {
|
||||
HelpPrinter = oldPrinter
|
||||
}()
|
||||
|
||||
var wasCalled = false
|
||||
HelpPrinter = func(w io.Writer, template string, data interface{}) {
|
||||
wasCalled = true
|
||||
}
|
||||
|
||||
app := NewApp()
|
||||
app.Run([]string{"-h"})
|
||||
|
||||
if wasCalled == false {
|
||||
t.Errorf("Help printer expected to be called, but was not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppVersionPrinter(t *testing.T) {
|
||||
oldPrinter := VersionPrinter
|
||||
defer func() {
|
||||
VersionPrinter = oldPrinter
|
||||
}()
|
||||
|
||||
var wasCalled = false
|
||||
VersionPrinter = func(c *Context) {
|
||||
wasCalled = true
|
||||
}
|
||||
|
||||
app := NewApp()
|
||||
ctx := NewContext(app, nil, nil)
|
||||
ShowVersion(ctx)
|
||||
|
||||
if wasCalled == false {
|
||||
t.Errorf("Version printer expected to be called, but was not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppCommandNotFound(t *testing.T) {
|
||||
beforeRun, subcommandRun := false, false
|
||||
app := NewApp()
|
||||
|
||||
app.CommandNotFound = func(c *Context, command string) {
|
||||
beforeRun = true
|
||||
}
|
||||
|
||||
app.Commands = []Command{
|
||||
Command{
|
||||
Name: "bar",
|
||||
Action: func(c *Context) {
|
||||
subcommandRun = true
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run([]string{"command", "foo"})
|
||||
|
||||
expect(t, beforeRun, true)
|
||||
expect(t, subcommandRun, false)
|
||||
}
|
||||
|
||||
func TestGlobalFlag(t *testing.T) {
|
||||
var globalFlag string
|
||||
var globalFlagSet bool
|
||||
app := NewApp()
|
||||
app.Flags = []Flag{
|
||||
StringFlag{Name: "global, g", Usage: "global"},
|
||||
}
|
||||
app.Action = func(c *Context) {
|
||||
globalFlag = c.GlobalString("global")
|
||||
globalFlagSet = c.GlobalIsSet("global")
|
||||
}
|
||||
app.Run([]string{"command", "-g", "foo"})
|
||||
expect(t, globalFlag, "foo")
|
||||
expect(t, globalFlagSet, true)
|
||||
|
||||
}
|
||||
|
||||
func TestGlobalFlagsInSubcommands(t *testing.T) {
|
||||
subcommandRun := false
|
||||
parentFlag := false
|
||||
app := NewApp()
|
||||
|
||||
app.Flags = []Flag{
|
||||
BoolFlag{Name: "debug, d", Usage: "Enable debugging"},
|
||||
}
|
||||
|
||||
app.Commands = []Command{
|
||||
Command{
|
||||
Name: "foo",
|
||||
Flags: []Flag{
|
||||
BoolFlag{Name: "parent, p", Usage: "Parent flag"},
|
||||
},
|
||||
Subcommands: []Command{
|
||||
{
|
||||
Name: "bar",
|
||||
Action: func(c *Context) {
|
||||
if c.GlobalBool("debug") {
|
||||
subcommandRun = true
|
||||
}
|
||||
if c.GlobalBool("parent") {
|
||||
parentFlag = true
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run([]string{"command", "-d", "foo", "-p", "bar"})
|
||||
|
||||
expect(t, subcommandRun, true)
|
||||
expect(t, parentFlag, true)
|
||||
}
|
||||
|
||||
func TestApp_Run_CommandWithSubcommandHasHelpTopic(t *testing.T) {
|
||||
var subcommandHelpTopics = [][]string{
|
||||
{"command", "foo", "--help"},
|
||||
{"command", "foo", "-h"},
|
||||
{"command", "foo", "help"},
|
||||
}
|
||||
|
||||
for _, flagSet := range subcommandHelpTopics {
|
||||
t.Logf("==> checking with flags %v", flagSet)
|
||||
|
||||
app := NewApp()
|
||||
buf := new(bytes.Buffer)
|
||||
app.Writer = buf
|
||||
|
||||
subCmdBar := Command{
|
||||
Name: "bar",
|
||||
Usage: "does bar things",
|
||||
}
|
||||
subCmdBaz := Command{
|
||||
Name: "baz",
|
||||
Usage: "does baz things",
|
||||
}
|
||||
cmd := Command{
|
||||
Name: "foo",
|
||||
Description: "descriptive wall of text about how it does foo things",
|
||||
Subcommands: []Command{subCmdBar, subCmdBaz},
|
||||
}
|
||||
|
||||
app.Commands = []Command{cmd}
|
||||
err := app.Run(flagSet)
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
output := buf.String()
|
||||
t.Logf("output: %q\n", buf.Bytes())
|
||||
|
||||
if strings.Contains(output, "No help topic for") {
|
||||
t.Errorf("expect a help topic, got none: \n%q", output)
|
||||
}
|
||||
|
||||
for _, shouldContain := range []string{
|
||||
cmd.Name, cmd.Description,
|
||||
subCmdBar.Name, subCmdBar.Usage,
|
||||
subCmdBaz.Name, subCmdBaz.Usage,
|
||||
} {
|
||||
if !strings.Contains(output, shouldContain) {
|
||||
t.Errorf("want help to contain %q, did not: \n%q", shouldContain, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_Run_SubcommandFullPath(t *testing.T) {
|
||||
app := NewApp()
|
||||
buf := new(bytes.Buffer)
|
||||
app.Writer = buf
|
||||
app.Name = "command"
|
||||
subCmd := Command{
|
||||
Name: "bar",
|
||||
Usage: "does bar things",
|
||||
}
|
||||
cmd := Command{
|
||||
Name: "foo",
|
||||
Description: "foo commands",
|
||||
Subcommands: []Command{subCmd},
|
||||
}
|
||||
app.Commands = []Command{cmd}
|
||||
|
||||
err := app.Run([]string{"command", "foo", "bar", "--help"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
output := buf.String()
|
||||
if !strings.Contains(output, "command foo bar - does bar things") {
|
||||
t.Errorf("expected full path to subcommand: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "command foo bar [arguments...]") {
|
||||
t.Errorf("expected full path to subcommand: %s", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_Run_SubcommandHelpName(t *testing.T) {
|
||||
app := NewApp()
|
||||
buf := new(bytes.Buffer)
|
||||
app.Writer = buf
|
||||
app.Name = "command"
|
||||
subCmd := Command{
|
||||
Name: "bar",
|
||||
HelpName: "custom",
|
||||
Usage: "does bar things",
|
||||
}
|
||||
cmd := Command{
|
||||
Name: "foo",
|
||||
Description: "foo commands",
|
||||
Subcommands: []Command{subCmd},
|
||||
}
|
||||
app.Commands = []Command{cmd}
|
||||
|
||||
err := app.Run([]string{"command", "foo", "bar", "--help"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
output := buf.String()
|
||||
if !strings.Contains(output, "custom - does bar things") {
|
||||
t.Errorf("expected HelpName for subcommand: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "custom [arguments...]") {
|
||||
t.Errorf("expected HelpName to subcommand: %s", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_Run_CommandHelpName(t *testing.T) {
|
||||
app := NewApp()
|
||||
buf := new(bytes.Buffer)
|
||||
app.Writer = buf
|
||||
app.Name = "command"
|
||||
subCmd := Command{
|
||||
Name: "bar",
|
||||
Usage: "does bar things",
|
||||
}
|
||||
cmd := Command{
|
||||
Name: "foo",
|
||||
HelpName: "custom",
|
||||
Description: "foo commands",
|
||||
Subcommands: []Command{subCmd},
|
||||
}
|
||||
app.Commands = []Command{cmd}
|
||||
|
||||
err := app.Run([]string{"command", "foo", "bar", "--help"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
output := buf.String()
|
||||
if !strings.Contains(output, "command foo bar - does bar things") {
|
||||
t.Errorf("expected full path to subcommand: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "command foo bar [arguments...]") {
|
||||
t.Errorf("expected full path to subcommand: %s", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_Run_CommandSubcommandHelpName(t *testing.T) {
|
||||
app := NewApp()
|
||||
buf := new(bytes.Buffer)
|
||||
app.Writer = buf
|
||||
app.Name = "base"
|
||||
subCmd := Command{
|
||||
Name: "bar",
|
||||
HelpName: "custom",
|
||||
Usage: "does bar things",
|
||||
}
|
||||
cmd := Command{
|
||||
Name: "foo",
|
||||
Description: "foo commands",
|
||||
Subcommands: []Command{subCmd},
|
||||
}
|
||||
app.Commands = []Command{cmd}
|
||||
|
||||
err := app.Run([]string{"command", "foo", "--help"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
output := buf.String()
|
||||
if !strings.Contains(output, "base foo - foo commands") {
|
||||
t.Errorf("expected full path to subcommand: %s", output)
|
||||
}
|
||||
if !strings.Contains(output, "base foo command [command options] [arguments...]") {
|
||||
t.Errorf("expected full path to subcommand: %s", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_Run_Help(t *testing.T) {
|
||||
var helpArguments = [][]string{{"boom", "--help"}, {"boom", "-h"}, {"boom", "help"}}
|
||||
|
||||
for _, args := range helpArguments {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
t.Logf("==> checking with arguments %v", args)
|
||||
|
||||
app := NewApp()
|
||||
app.Name = "boom"
|
||||
app.Usage = "make an explosive entrance"
|
||||
app.Writer = buf
|
||||
app.Action = func(c *Context) {
|
||||
buf.WriteString("boom I say!")
|
||||
}
|
||||
|
||||
err := app.Run(args)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
output := buf.String()
|
||||
t.Logf("output: %q\n", buf.Bytes())
|
||||
|
||||
if !strings.Contains(output, "boom - make an explosive entrance") {
|
||||
t.Errorf("want help to contain %q, did not: \n%q", "boom - make an explosive entrance", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_Run_Version(t *testing.T) {
|
||||
var versionArguments = [][]string{{"boom", "--version"}, {"boom", "-v"}}
|
||||
|
||||
for _, args := range versionArguments {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
t.Logf("==> checking with arguments %v", args)
|
||||
|
||||
app := NewApp()
|
||||
app.Name = "boom"
|
||||
app.Usage = "make an explosive entrance"
|
||||
app.Version = "0.1.0"
|
||||
app.Writer = buf
|
||||
app.Action = func(c *Context) {
|
||||
buf.WriteString("boom I say!")
|
||||
}
|
||||
|
||||
err := app.Run(args)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
output := buf.String()
|
||||
t.Logf("output: %q\n", buf.Bytes())
|
||||
|
||||
if !strings.Contains(output, "0.1.0") {
|
||||
t.Errorf("want version to contain %q, did not: \n%q", "0.1.0", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_Run_DoesNotOverwriteErrorFromBefore(t *testing.T) {
|
||||
app := NewApp()
|
||||
app.Action = func(c *Context) {}
|
||||
app.Before = func(c *Context) error { return fmt.Errorf("before error") }
|
||||
app.After = func(c *Context) error { return fmt.Errorf("after error") }
|
||||
|
||||
err := app.Run([]string{"foo"})
|
||||
if err == nil {
|
||||
t.Fatalf("expected to recieve error from Run, got none")
|
||||
}
|
||||
|
||||
if !strings.Contains(err.Error(), "before error") {
|
||||
t.Errorf("expected text of error from Before method, but got none in \"%v\"", err)
|
||||
}
|
||||
if !strings.Contains(err.Error(), "after error") {
|
||||
t.Errorf("expected text of error from After method, but got none in \"%v\"", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApp_Run_SubcommandDoesNotOverwriteErrorFromBefore(t *testing.T) {
|
||||
app := NewApp()
|
||||
app.Commands = []Command{
|
||||
Command{
|
||||
Name: "bar",
|
||||
Before: func(c *Context) error { return fmt.Errorf("before error") },
|
||||
After: func(c *Context) error { return fmt.Errorf("after error") },
|
||||
},
|
||||
}
|
||||
|
||||
err := app.Run([]string{"foo", "bar"})
|
||||
if err == nil {
|
||||
t.Fatalf("expected to recieve error from Run, got none")
|
||||
}
|
||||
|
||||
if !strings.Contains(err.Error(), "before error") {
|
||||
t.Errorf("expected text of error from Before method, but got none in \"%v\"", err)
|
||||
}
|
||||
if !strings.Contains(err.Error(), "after error") {
|
||||
t.Errorf("expected text of error from After method, but got none in \"%v\"", err)
|
||||
}
|
||||
}
|
15
vendor/github.com/codegangsta/cli/autocomplete/bash_autocomplete
generated
vendored
15
vendor/github.com/codegangsta/cli/autocomplete/bash_autocomplete
generated
vendored
@ -1,15 +0,0 @@
|
||||
#! /bin/bash
|
||||
|
||||
: ${PROG:=$(basename ${BASH_SOURCE})}
|
||||
|
||||
_cli_bash_autocomplete() {
|
||||
local cur prev opts base
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
}
|
||||
|
||||
complete -F _cli_bash_autocomplete $PROG
|
5
vendor/github.com/codegangsta/cli/autocomplete/zsh_autocomplete
generated
vendored
5
vendor/github.com/codegangsta/cli/autocomplete/zsh_autocomplete
generated
vendored
@ -1,5 +0,0 @@
|
||||
autoload -U compinit && compinit
|
||||
autoload -U bashcompinit && bashcompinit
|
||||
|
||||
script_dir=$(dirname $0)
|
||||
source ${script_dir}/bash_autocomplete
|
98
vendor/github.com/codegangsta/cli/cli_test.go
generated
vendored
98
vendor/github.com/codegangsta/cli/cli_test.go
generated
vendored
@ -1,98 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
func Example() {
|
||||
app := NewApp()
|
||||
app.Name = "todo"
|
||||
app.Usage = "task list on the command line"
|
||||
app.Commands = []Command{
|
||||
{
|
||||
Name: "add",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "add a task to the list",
|
||||
Action: func(c *Context) {
|
||||
println("added task: ", c.Args().First())
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "complete",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "complete a task on the list",
|
||||
Action: func(c *Context) {
|
||||
println("completed task: ", c.Args().First())
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run(os.Args)
|
||||
}
|
||||
|
||||
func ExampleSubcommand() {
|
||||
app := NewApp()
|
||||
app.Name = "say"
|
||||
app.Commands = []Command{
|
||||
{
|
||||
Name: "hello",
|
||||
Aliases: []string{"hi"},
|
||||
Usage: "use it to see a description",
|
||||
Description: "This is how we describe hello the function",
|
||||
Subcommands: []Command{
|
||||
{
|
||||
Name: "english",
|
||||
Aliases: []string{"en"},
|
||||
Usage: "sends a greeting in english",
|
||||
Description: "greets someone in english",
|
||||
Flags: []Flag{
|
||||
StringFlag{
|
||||
Name: "name",
|
||||
Value: "Bob",
|
||||
Usage: "Name of the person to greet",
|
||||
},
|
||||
},
|
||||
Action: func(c *Context) {
|
||||
println("Hello, ", c.String("name"))
|
||||
},
|
||||
}, {
|
||||
Name: "spanish",
|
||||
Aliases: []string{"sp"},
|
||||
Usage: "sends a greeting in spanish",
|
||||
Flags: []Flag{
|
||||
StringFlag{
|
||||
Name: "surname",
|
||||
Value: "Jones",
|
||||
Usage: "Surname of the person to greet",
|
||||
},
|
||||
},
|
||||
Action: func(c *Context) {
|
||||
println("Hola, ", c.String("surname"))
|
||||
},
|
||||
}, {
|
||||
Name: "french",
|
||||
Aliases: []string{"fr"},
|
||||
Usage: "sends a greeting in french",
|
||||
Flags: []Flag{
|
||||
StringFlag{
|
||||
Name: "nickname",
|
||||
Value: "Stevie",
|
||||
Usage: "Nickname of the person to greet",
|
||||
},
|
||||
},
|
||||
Action: func(c *Context) {
|
||||
println("Bonjour, ", c.String("nickname"))
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Name: "bye",
|
||||
Usage: "says goodbye",
|
||||
Action: func(c *Context) {
|
||||
println("bye")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run(os.Args)
|
||||
}
|
54
vendor/github.com/codegangsta/cli/command.go
generated
vendored
54
vendor/github.com/codegangsta/cli/command.go
generated
vendored
@ -74,34 +74,40 @@ func (c Command) Run(ctx *Context) error {
|
||||
set := flagSet(c.Name, c.Flags)
|
||||
set.SetOutput(ioutil.Discard)
|
||||
|
||||
firstFlagIndex := -1
|
||||
terminatorIndex := -1
|
||||
for index, arg := range ctx.Args() {
|
||||
if arg == "--" {
|
||||
terminatorIndex = index
|
||||
break
|
||||
} else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 {
|
||||
firstFlagIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
if firstFlagIndex > -1 && !c.SkipFlagParsing {
|
||||
args := ctx.Args()
|
||||
regularArgs := make([]string, len(args[1:firstFlagIndex]))
|
||||
copy(regularArgs, args[1:firstFlagIndex])
|
||||
|
||||
var flagArgs []string
|
||||
if terminatorIndex > -1 {
|
||||
flagArgs = args[firstFlagIndex:terminatorIndex]
|
||||
regularArgs = append(regularArgs, args[terminatorIndex:]...)
|
||||
} else {
|
||||
flagArgs = args[firstFlagIndex:]
|
||||
if !c.SkipFlagParsing {
|
||||
firstFlagIndex := -1
|
||||
terminatorIndex := -1
|
||||
for index, arg := range ctx.Args() {
|
||||
if arg == "--" {
|
||||
terminatorIndex = index
|
||||
break
|
||||
} else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 {
|
||||
firstFlagIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
err = set.Parse(append(flagArgs, regularArgs...))
|
||||
if firstFlagIndex > -1 {
|
||||
args := ctx.Args()
|
||||
regularArgs := make([]string, len(args[1:firstFlagIndex]))
|
||||
copy(regularArgs, args[1:firstFlagIndex])
|
||||
|
||||
var flagArgs []string
|
||||
if terminatorIndex > -1 {
|
||||
flagArgs = args[firstFlagIndex:terminatorIndex]
|
||||
regularArgs = append(regularArgs, args[terminatorIndex:]...)
|
||||
} else {
|
||||
flagArgs = args[firstFlagIndex:]
|
||||
}
|
||||
|
||||
err = set.Parse(append(flagArgs, regularArgs...))
|
||||
} else {
|
||||
err = set.Parse(ctx.Args().Tail())
|
||||
}
|
||||
} else {
|
||||
err = set.Parse(ctx.Args().Tail())
|
||||
if c.SkipFlagParsing {
|
||||
err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...))
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
47
vendor/github.com/codegangsta/cli/command_test.go
generated
vendored
47
vendor/github.com/codegangsta/cli/command_test.go
generated
vendored
@ -1,47 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCommandDoNotIgnoreFlags(t *testing.T) {
|
||||
app := NewApp()
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
test := []string{"blah", "blah", "-break"}
|
||||
set.Parse(test)
|
||||
|
||||
c := NewContext(app, set, nil)
|
||||
|
||||
command := Command{
|
||||
Name: "test-cmd",
|
||||
Aliases: []string{"tc"},
|
||||
Usage: "this is for testing",
|
||||
Description: "testing",
|
||||
Action: func(_ *Context) {},
|
||||
}
|
||||
err := command.Run(c)
|
||||
|
||||
expect(t, err.Error(), "flag provided but not defined: -break")
|
||||
}
|
||||
|
||||
func TestCommandIgnoreFlags(t *testing.T) {
|
||||
app := NewApp()
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
test := []string{"blah", "blah", "-break"}
|
||||
set.Parse(test)
|
||||
|
||||
c := NewContext(app, set, nil)
|
||||
|
||||
command := Command{
|
||||
Name: "test-cmd",
|
||||
Aliases: []string{"tc"},
|
||||
Usage: "this is for testing",
|
||||
Description: "testing",
|
||||
Action: func(_ *Context) {},
|
||||
SkipFlagParsing: true,
|
||||
}
|
||||
err := command.Run(c)
|
||||
|
||||
expect(t, err, nil)
|
||||
}
|
113
vendor/github.com/codegangsta/cli/context_test.go
generated
vendored
113
vendor/github.com/codegangsta/cli/context_test.go
generated
vendored
@ -1,113 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNewContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Int("myflag", 12, "doc")
|
||||
globalSet := flag.NewFlagSet("test", 0)
|
||||
globalSet.Int("myflag", 42, "doc")
|
||||
globalCtx := NewContext(nil, globalSet, nil)
|
||||
command := Command{Name: "mycommand"}
|
||||
c := NewContext(nil, set, globalCtx)
|
||||
c.Command = command
|
||||
expect(t, c.Int("myflag"), 12)
|
||||
expect(t, c.GlobalInt("myflag"), 42)
|
||||
expect(t, c.Command.Name, "mycommand")
|
||||
}
|
||||
|
||||
func TestContext_Int(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Int("myflag", 12, "doc")
|
||||
c := NewContext(nil, set, nil)
|
||||
expect(t, c.Int("myflag"), 12)
|
||||
}
|
||||
|
||||
func TestContext_Duration(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Duration("myflag", time.Duration(12*time.Second), "doc")
|
||||
c := NewContext(nil, set, nil)
|
||||
expect(t, c.Duration("myflag"), time.Duration(12*time.Second))
|
||||
}
|
||||
|
||||
func TestContext_String(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.String("myflag", "hello world", "doc")
|
||||
c := NewContext(nil, set, nil)
|
||||
expect(t, c.String("myflag"), "hello world")
|
||||
}
|
||||
|
||||
func TestContext_Bool(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", false, "doc")
|
||||
c := NewContext(nil, set, nil)
|
||||
expect(t, c.Bool("myflag"), false)
|
||||
}
|
||||
|
||||
func TestContext_BoolT(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", true, "doc")
|
||||
c := NewContext(nil, set, nil)
|
||||
expect(t, c.BoolT("myflag"), true)
|
||||
}
|
||||
|
||||
func TestContext_Args(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", false, "doc")
|
||||
c := NewContext(nil, set, nil)
|
||||
set.Parse([]string{"--myflag", "bat", "baz"})
|
||||
expect(t, len(c.Args()), 2)
|
||||
expect(t, c.Bool("myflag"), true)
|
||||
}
|
||||
|
||||
func TestContext_IsSet(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", false, "doc")
|
||||
set.String("otherflag", "hello world", "doc")
|
||||
globalSet := flag.NewFlagSet("test", 0)
|
||||
globalSet.Bool("myflagGlobal", true, "doc")
|
||||
globalCtx := NewContext(nil, globalSet, nil)
|
||||
c := NewContext(nil, set, globalCtx)
|
||||
set.Parse([]string{"--myflag", "bat", "baz"})
|
||||
globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
|
||||
expect(t, c.IsSet("myflag"), true)
|
||||
expect(t, c.IsSet("otherflag"), false)
|
||||
expect(t, c.IsSet("bogusflag"), false)
|
||||
expect(t, c.IsSet("myflagGlobal"), false)
|
||||
}
|
||||
|
||||
func TestContext_GlobalIsSet(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", false, "doc")
|
||||
set.String("otherflag", "hello world", "doc")
|
||||
globalSet := flag.NewFlagSet("test", 0)
|
||||
globalSet.Bool("myflagGlobal", true, "doc")
|
||||
globalSet.Bool("myflagGlobalUnset", true, "doc")
|
||||
globalCtx := NewContext(nil, globalSet, nil)
|
||||
c := NewContext(nil, set, globalCtx)
|
||||
set.Parse([]string{"--myflag", "bat", "baz"})
|
||||
globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
|
||||
expect(t, c.GlobalIsSet("myflag"), false)
|
||||
expect(t, c.GlobalIsSet("otherflag"), false)
|
||||
expect(t, c.GlobalIsSet("bogusflag"), false)
|
||||
expect(t, c.GlobalIsSet("myflagGlobal"), true)
|
||||
expect(t, c.GlobalIsSet("myflagGlobalUnset"), false)
|
||||
expect(t, c.GlobalIsSet("bogusGlobal"), false)
|
||||
}
|
||||
|
||||
func TestContext_NumFlags(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", false, "doc")
|
||||
set.String("otherflag", "hello world", "doc")
|
||||
globalSet := flag.NewFlagSet("test", 0)
|
||||
globalSet.Bool("myflagGlobal", true, "doc")
|
||||
globalCtx := NewContext(nil, globalSet, nil)
|
||||
c := NewContext(nil, set, globalCtx)
|
||||
set.Parse([]string{"--myflag", "--otherflag=foo"})
|
||||
globalSet.Parse([]string{"--myflagGlobal"})
|
||||
expect(t, c.NumFlags(), 2)
|
||||
}
|
74
vendor/github.com/codegangsta/cli/flag.go
generated
vendored
74
vendor/github.com/codegangsta/cli/flag.go
generated
vendored
@ -237,9 +237,10 @@ func (f IntSliceFlag) getName() string {
|
||||
|
||||
// BoolFlag is a switch that defaults to false
|
||||
type BoolFlag struct {
|
||||
Name string
|
||||
Usage string
|
||||
EnvVar string
|
||||
Name string
|
||||
Usage string
|
||||
EnvVar string
|
||||
Destination *bool
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
@ -264,6 +265,10 @@ func (f BoolFlag) Apply(set *flag.FlagSet) {
|
||||
}
|
||||
|
||||
eachName(f.Name, func(name string) {
|
||||
if f.Destination != nil {
|
||||
set.BoolVar(f.Destination, name, val, f.Usage)
|
||||
return
|
||||
}
|
||||
set.Bool(name, val, f.Usage)
|
||||
})
|
||||
}
|
||||
@ -275,9 +280,10 @@ func (f BoolFlag) getName() string {
|
||||
// BoolTFlag this represents a boolean flag that is true by default, but can
|
||||
// still be set to false by --some-flag=false
|
||||
type BoolTFlag struct {
|
||||
Name string
|
||||
Usage string
|
||||
EnvVar string
|
||||
Name string
|
||||
Usage string
|
||||
EnvVar string
|
||||
Destination *bool
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
@ -302,6 +308,10 @@ func (f BoolTFlag) Apply(set *flag.FlagSet) {
|
||||
}
|
||||
|
||||
eachName(f.Name, func(name string) {
|
||||
if f.Destination != nil {
|
||||
set.BoolVar(f.Destination, name, val, f.Usage)
|
||||
return
|
||||
}
|
||||
set.Bool(name, val, f.Usage)
|
||||
})
|
||||
}
|
||||
@ -312,10 +322,11 @@ func (f BoolTFlag) getName() string {
|
||||
|
||||
// StringFlag represents a flag that takes as string value
|
||||
type StringFlag struct {
|
||||
Name string
|
||||
Value string
|
||||
Usage string
|
||||
EnvVar string
|
||||
Name string
|
||||
Value string
|
||||
Usage string
|
||||
EnvVar string
|
||||
Destination *string
|
||||
}
|
||||
|
||||
// String returns the usage
|
||||
@ -345,6 +356,10 @@ func (f StringFlag) Apply(set *flag.FlagSet) {
|
||||
}
|
||||
|
||||
eachName(f.Name, func(name string) {
|
||||
if f.Destination != nil {
|
||||
set.StringVar(f.Destination, name, f.Value, f.Usage)
|
||||
return
|
||||
}
|
||||
set.String(name, f.Value, f.Usage)
|
||||
})
|
||||
}
|
||||
@ -356,10 +371,11 @@ func (f StringFlag) getName() string {
|
||||
// IntFlag is a flag that takes an integer
|
||||
// Errors if the value provided cannot be parsed
|
||||
type IntFlag struct {
|
||||
Name string
|
||||
Value int
|
||||
Usage string
|
||||
EnvVar string
|
||||
Name string
|
||||
Value int
|
||||
Usage string
|
||||
EnvVar string
|
||||
Destination *int
|
||||
}
|
||||
|
||||
// String returns the usage
|
||||
@ -383,6 +399,10 @@ func (f IntFlag) Apply(set *flag.FlagSet) {
|
||||
}
|
||||
|
||||
eachName(f.Name, func(name string) {
|
||||
if f.Destination != nil {
|
||||
set.IntVar(f.Destination, name, f.Value, f.Usage)
|
||||
return
|
||||
}
|
||||
set.Int(name, f.Value, f.Usage)
|
||||
})
|
||||
}
|
||||
@ -394,10 +414,11 @@ func (f IntFlag) getName() string {
|
||||
// DurationFlag is a flag that takes a duration specified in Go's duration
|
||||
// format: https://golang.org/pkg/time/#ParseDuration
|
||||
type DurationFlag struct {
|
||||
Name string
|
||||
Value time.Duration
|
||||
Usage string
|
||||
EnvVar string
|
||||
Name string
|
||||
Value time.Duration
|
||||
Usage string
|
||||
EnvVar string
|
||||
Destination *time.Duration
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
@ -421,6 +442,10 @@ func (f DurationFlag) Apply(set *flag.FlagSet) {
|
||||
}
|
||||
|
||||
eachName(f.Name, func(name string) {
|
||||
if f.Destination != nil {
|
||||
set.DurationVar(f.Destination, name, f.Value, f.Usage)
|
||||
return
|
||||
}
|
||||
set.Duration(name, f.Value, f.Usage)
|
||||
})
|
||||
}
|
||||
@ -432,10 +457,11 @@ func (f DurationFlag) getName() string {
|
||||
// Float64Flag is a flag that takes an float value
|
||||
// Errors if the value provided cannot be parsed
|
||||
type Float64Flag struct {
|
||||
Name string
|
||||
Value float64
|
||||
Usage string
|
||||
EnvVar string
|
||||
Name string
|
||||
Value float64
|
||||
Usage string
|
||||
EnvVar string
|
||||
Destination *float64
|
||||
}
|
||||
|
||||
// String returns the usage
|
||||
@ -458,6 +484,10 @@ func (f Float64Flag) Apply(set *flag.FlagSet) {
|
||||
}
|
||||
|
||||
eachName(f.Name, func(name string) {
|
||||
if f.Destination != nil {
|
||||
set.Float64Var(f.Destination, name, f.Value, f.Usage)
|
||||
return
|
||||
}
|
||||
set.Float64(name, f.Value, f.Usage)
|
||||
})
|
||||
}
|
||||
|
740
vendor/github.com/codegangsta/cli/flag_test.go
generated
vendored
740
vendor/github.com/codegangsta/cli/flag_test.go
generated
vendored
@ -1,740 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var boolFlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
}{
|
||||
{"help", "--help\t"},
|
||||
{"h", "-h\t"},
|
||||
}
|
||||
|
||||
func TestBoolFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range boolFlagTests {
|
||||
flag := BoolFlag{Name: test.name}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%s does not match %s", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var stringFlagTests = []struct {
|
||||
name string
|
||||
value string
|
||||
expected string
|
||||
}{
|
||||
{"help", "", "--help \t"},
|
||||
{"h", "", "-h \t"},
|
||||
{"h", "", "-h \t"},
|
||||
{"test", "Something", "--test \"Something\"\t"},
|
||||
}
|
||||
|
||||
func TestStringFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range stringFlagTests {
|
||||
flag := StringFlag{Name: test.name, Value: test.value}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%s does not match %s", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_FOO", "derp")
|
||||
for _, test := range stringFlagTests {
|
||||
flag := StringFlag{Name: test.name, Value: test.value, EnvVar: "APP_FOO"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_FOO]") {
|
||||
t.Errorf("%s does not end with [$APP_FOO]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var stringSliceFlagTests = []struct {
|
||||
name string
|
||||
value *StringSlice
|
||||
expected string
|
||||
}{
|
||||
{"help", func() *StringSlice {
|
||||
s := &StringSlice{}
|
||||
s.Set("")
|
||||
return s
|
||||
}(), "--help [--help option --help option]\t"},
|
||||
{"h", func() *StringSlice {
|
||||
s := &StringSlice{}
|
||||
s.Set("")
|
||||
return s
|
||||
}(), "-h [-h option -h option]\t"},
|
||||
{"h", func() *StringSlice {
|
||||
s := &StringSlice{}
|
||||
s.Set("")
|
||||
return s
|
||||
}(), "-h [-h option -h option]\t"},
|
||||
{"test", func() *StringSlice {
|
||||
s := &StringSlice{}
|
||||
s.Set("Something")
|
||||
return s
|
||||
}(), "--test [--test option --test option]\t"},
|
||||
}
|
||||
|
||||
func TestStringSliceFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range stringSliceFlagTests {
|
||||
flag := StringSliceFlag{Name: test.name, Value: test.value}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%q does not match %q", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringSliceFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_QWWX", "11,4")
|
||||
for _, test := range stringSliceFlagTests {
|
||||
flag := StringSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_QWWX"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_QWWX]") {
|
||||
t.Errorf("%q does not end with [$APP_QWWX]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var intFlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
}{
|
||||
{"help", "--help \"0\"\t"},
|
||||
{"h", "-h \"0\"\t"},
|
||||
}
|
||||
|
||||
func TestIntFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range intFlagTests {
|
||||
flag := IntFlag{Name: test.name}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%s does not match %s", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_BAR", "2")
|
||||
for _, test := range intFlagTests {
|
||||
flag := IntFlag{Name: test.name, EnvVar: "APP_BAR"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_BAR]") {
|
||||
t.Errorf("%s does not end with [$APP_BAR]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var durationFlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
}{
|
||||
{"help", "--help \"0\"\t"},
|
||||
{"h", "-h \"0\"\t"},
|
||||
}
|
||||
|
||||
func TestDurationFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range durationFlagTests {
|
||||
flag := DurationFlag{Name: test.name}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%s does not match %s", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDurationFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_BAR", "2h3m6s")
|
||||
for _, test := range durationFlagTests {
|
||||
flag := DurationFlag{Name: test.name, EnvVar: "APP_BAR"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_BAR]") {
|
||||
t.Errorf("%s does not end with [$APP_BAR]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var intSliceFlagTests = []struct {
|
||||
name string
|
||||
value *IntSlice
|
||||
expected string
|
||||
}{
|
||||
{"help", &IntSlice{}, "--help [--help option --help option]\t"},
|
||||
{"h", &IntSlice{}, "-h [-h option -h option]\t"},
|
||||
{"h", &IntSlice{}, "-h [-h option -h option]\t"},
|
||||
{"test", func() *IntSlice {
|
||||
i := &IntSlice{}
|
||||
i.Set("9")
|
||||
return i
|
||||
}(), "--test [--test option --test option]\t"},
|
||||
}
|
||||
|
||||
func TestIntSliceFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range intSliceFlagTests {
|
||||
flag := IntSliceFlag{Name: test.name, Value: test.value}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%q does not match %q", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntSliceFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_SMURF", "42,3")
|
||||
for _, test := range intSliceFlagTests {
|
||||
flag := IntSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_SMURF"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_SMURF]") {
|
||||
t.Errorf("%q does not end with [$APP_SMURF]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var float64FlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
}{
|
||||
{"help", "--help \"0\"\t"},
|
||||
{"h", "-h \"0\"\t"},
|
||||
}
|
||||
|
||||
func TestFloat64FlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range float64FlagTests {
|
||||
flag := Float64Flag{Name: test.name}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%s does not match %s", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFloat64FlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_BAZ", "99.4")
|
||||
for _, test := range float64FlagTests {
|
||||
flag := Float64Flag{Name: test.name, EnvVar: "APP_BAZ"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_BAZ]") {
|
||||
t.Errorf("%s does not end with [$APP_BAZ]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var genericFlagTests = []struct {
|
||||
name string
|
||||
value Generic
|
||||
expected string
|
||||
}{
|
||||
{"test", &Parser{"abc", "def"}, "--test \"abc,def\"\ttest flag"},
|
||||
{"t", &Parser{"abc", "def"}, "-t \"abc,def\"\ttest flag"},
|
||||
}
|
||||
|
||||
func TestGenericFlagHelpOutput(t *testing.T) {
|
||||
|
||||
for _, test := range genericFlagTests {
|
||||
flag := GenericFlag{Name: test.name, Value: test.value, Usage: "test flag"}
|
||||
output := flag.String()
|
||||
|
||||
if output != test.expected {
|
||||
t.Errorf("%q does not match %q", output, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenericFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_ZAP", "3")
|
||||
for _, test := range genericFlagTests {
|
||||
flag := GenericFlag{Name: test.name, EnvVar: "APP_ZAP"}
|
||||
output := flag.String()
|
||||
|
||||
if !strings.HasSuffix(output, " [$APP_ZAP]") {
|
||||
t.Errorf("%s does not end with [$APP_ZAP]", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseMultiString(t *testing.T) {
|
||||
(&App{
|
||||
Flags: []Flag{
|
||||
StringFlag{Name: "serve, s"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.String("serve") != "10" {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.String("s") != "10" {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run", "-s", "10"})
|
||||
}
|
||||
|
||||
func TestParseMultiStringFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_COUNT", "20")
|
||||
(&App{
|
||||
Flags: []Flag{
|
||||
StringFlag{Name: "count, c", EnvVar: "APP_COUNT"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.String("count") != "20" {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.String("c") != "20" {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiStringFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_COUNT", "20")
|
||||
(&App{
|
||||
Flags: []Flag{
|
||||
StringFlag{Name: "count, c", EnvVar: "COMPAT_COUNT,APP_COUNT"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.String("count") != "20" {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.String("c") != "20" {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiStringSlice(t *testing.T) {
|
||||
(&App{
|
||||
Flags: []Flag{
|
||||
StringSliceFlag{Name: "serve, s", Value: &StringSlice{}},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run", "-s", "10", "-s", "20"})
|
||||
}
|
||||
|
||||
func TestParseMultiStringSliceFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_INTERVALS", "20,30,40")
|
||||
|
||||
(&App{
|
||||
Flags: []Flag{
|
||||
StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "APP_INTERVALS"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiStringSliceFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_INTERVALS", "20,30,40")
|
||||
|
||||
(&App{
|
||||
Flags: []Flag{
|
||||
StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiInt(t *testing.T) {
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
IntFlag{Name: "serve, s"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.Int("serve") != 10 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Int("s") != 10 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run", "-s", "10"})
|
||||
}
|
||||
|
||||
func TestParseMultiIntFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_TIMEOUT_SECONDS", "10")
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
IntFlag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.Int("timeout") != 10 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Int("t") != 10 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiIntFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_TIMEOUT_SECONDS", "10")
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
IntFlag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.Int("timeout") != 10 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Int("t") != 10 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiIntSlice(t *testing.T) {
|
||||
(&App{
|
||||
Flags: []Flag{
|
||||
IntSliceFlag{Name: "serve, s", Value: &IntSlice{}},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if !reflect.DeepEqual(ctx.IntSlice("serve"), []int{10, 20}) {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.IntSlice("s"), []int{10, 20}) {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run", "-s", "10", "-s", "20"})
|
||||
}
|
||||
|
||||
func TestParseMultiIntSliceFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_INTERVALS", "20,30,40")
|
||||
|
||||
(&App{
|
||||
Flags: []Flag{
|
||||
IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "APP_INTERVALS"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiIntSliceFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_INTERVALS", "20,30,40")
|
||||
|
||||
(&App{
|
||||
Flags: []Flag{
|
||||
IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}).Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiFloat64(t *testing.T) {
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
Float64Flag{Name: "serve, s"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.Float64("serve") != 10.2 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Float64("s") != 10.2 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run", "-s", "10.2"})
|
||||
}
|
||||
|
||||
func TestParseMultiFloat64FromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.Float64("timeout") != 15.5 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Float64("t") != 15.5 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiFloat64FromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
Float64Flag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.Float64("timeout") != 15.5 {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Float64("t") != 15.5 {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiBool(t *testing.T) {
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
BoolFlag{Name: "serve, s"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.Bool("serve") != true {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.Bool("s") != true {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run", "--serve"})
|
||||
}
|
||||
|
||||
func TestParseMultiBoolFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_DEBUG", "1")
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
BoolFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.Bool("debug") != true {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if ctx.Bool("d") != true {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiBoolFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_DEBUG", "1")
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
BoolFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.Bool("debug") != true {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if ctx.Bool("d") != true {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiBoolT(t *testing.T) {
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
BoolTFlag{Name: "serve, s"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.BoolT("serve") != true {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if ctx.BoolT("s") != true {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run", "--serve"})
|
||||
}
|
||||
|
||||
func TestParseMultiBoolTFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_DEBUG", "0")
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
BoolTFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.BoolT("debug") != false {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if ctx.BoolT("d") != false {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseMultiBoolTFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_DEBUG", "0")
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
BoolTFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.BoolT("debug") != false {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if ctx.BoolT("d") != false {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
type Parser [2]string
|
||||
|
||||
func (p *Parser) Set(value string) error {
|
||||
parts := strings.Split(value, ",")
|
||||
if len(parts) != 2 {
|
||||
return fmt.Errorf("invalid format")
|
||||
}
|
||||
|
||||
(*p)[0] = parts[0]
|
||||
(*p)[1] = parts[1]
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) String() string {
|
||||
return fmt.Sprintf("%s,%s", p[0], p[1])
|
||||
}
|
||||
|
||||
func TestParseGeneric(t *testing.T) {
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
GenericFlag{Name: "serve, s", Value: &Parser{}},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) {
|
||||
t.Errorf("main name not set")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) {
|
||||
t.Errorf("short name not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run", "-s", "10,20"})
|
||||
}
|
||||
|
||||
func TestParseGenericFromEnv(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_SERVE", "20,30")
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
GenericFlag{Name: "serve, s", Value: &Parser{}, EnvVar: "APP_SERVE"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"20", "30"}) {
|
||||
t.Errorf("main name not set from env")
|
||||
}
|
||||
if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"20", "30"}) {
|
||||
t.Errorf("short name not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
||||
|
||||
func TestParseGenericFromEnvCascade(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("APP_FOO", "99,2000")
|
||||
a := App{
|
||||
Flags: []Flag{
|
||||
GenericFlag{Name: "foos", Value: &Parser{}, EnvVar: "COMPAT_FOO,APP_FOO"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if !reflect.DeepEqual(ctx.Generic("foos"), &Parser{"99", "2000"}) {
|
||||
t.Errorf("value not set from env")
|
||||
}
|
||||
},
|
||||
}
|
||||
a.Run([]string{"run"})
|
||||
}
|
94
vendor/github.com/codegangsta/cli/help_test.go
generated
vendored
94
vendor/github.com/codegangsta/cli/help_test.go
generated
vendored
@ -1,94 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_ShowAppHelp_NoAuthor(t *testing.T) {
|
||||
output := new(bytes.Buffer)
|
||||
app := NewApp()
|
||||
app.Writer = output
|
||||
|
||||
c := NewContext(app, nil, nil)
|
||||
|
||||
ShowAppHelp(c)
|
||||
|
||||
if bytes.Index(output.Bytes(), []byte("AUTHOR(S):")) != -1 {
|
||||
t.Errorf("expected\n%snot to include %s", output.String(), "AUTHOR(S):")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_ShowAppHelp_NoVersion(t *testing.T) {
|
||||
output := new(bytes.Buffer)
|
||||
app := NewApp()
|
||||
app.Writer = output
|
||||
|
||||
app.Version = ""
|
||||
|
||||
c := NewContext(app, nil, nil)
|
||||
|
||||
ShowAppHelp(c)
|
||||
|
||||
if bytes.Index(output.Bytes(), []byte("VERSION:")) != -1 {
|
||||
t.Errorf("expected\n%snot to include %s", output.String(), "VERSION:")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Help_Custom_Flags(t *testing.T) {
|
||||
oldFlag := HelpFlag
|
||||
defer func() {
|
||||
HelpFlag = oldFlag
|
||||
}()
|
||||
|
||||
HelpFlag = BoolFlag{
|
||||
Name: "help, x",
|
||||
Usage: "show help",
|
||||
}
|
||||
|
||||
app := App{
|
||||
Flags: []Flag{
|
||||
BoolFlag{Name: "foo, h"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.Bool("h") != true {
|
||||
t.Errorf("custom help flag not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
output := new(bytes.Buffer)
|
||||
app.Writer = output
|
||||
app.Run([]string{"test", "-h"})
|
||||
if output.Len() > 0 {
|
||||
t.Errorf("unexpected output: %s", output.String())
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Version_Custom_Flags(t *testing.T) {
|
||||
oldFlag := VersionFlag
|
||||
defer func() {
|
||||
VersionFlag = oldFlag
|
||||
}()
|
||||
|
||||
VersionFlag = BoolFlag{
|
||||
Name: "version, V",
|
||||
Usage: "show version",
|
||||
}
|
||||
|
||||
app := App{
|
||||
Flags: []Flag{
|
||||
BoolFlag{Name: "foo, v"},
|
||||
},
|
||||
Action: func(ctx *Context) {
|
||||
if ctx.Bool("v") != true {
|
||||
t.Errorf("custom version flag not set")
|
||||
}
|
||||
},
|
||||
}
|
||||
output := new(bytes.Buffer)
|
||||
app.Writer = output
|
||||
app.Run([]string{"test", "-v"})
|
||||
if output.Len() > 0 {
|
||||
t.Errorf("unexpected output: %s", output.String())
|
||||
}
|
||||
}
|
19
vendor/github.com/codegangsta/cli/helpers_test.go
generated
vendored
19
vendor/github.com/codegangsta/cli/helpers_test.go
generated
vendored
@ -1,19 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
/* Test Helpers */
|
||||
func expect(t *testing.T, a interface{}, b interface{}) {
|
||||
if a != b {
|
||||
t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
|
||||
}
|
||||
}
|
||||
|
||||
func refute(t *testing.T, a interface{}, b interface{}) {
|
||||
if a == b {
|
||||
t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
|
||||
}
|
||||
}
|
46
vendor/github.com/docker/docker/pkg/units/duration_test.go
generated
vendored
46
vendor/github.com/docker/docker/pkg/units/duration_test.go
generated
vendored
@ -1,46 +0,0 @@
|
||||
package units
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestHumanDuration(t *testing.T) {
|
||||
// Useful duration abstractions
|
||||
day := 24 * time.Hour
|
||||
week := 7 * day
|
||||
month := 30 * day
|
||||
year := 365 * day
|
||||
|
||||
assertEquals(t, "Less than a second", HumanDuration(450*time.Millisecond))
|
||||
assertEquals(t, "47 seconds", HumanDuration(47*time.Second))
|
||||
assertEquals(t, "About a minute", HumanDuration(1*time.Minute))
|
||||
assertEquals(t, "3 minutes", HumanDuration(3*time.Minute))
|
||||
assertEquals(t, "35 minutes", HumanDuration(35*time.Minute))
|
||||
assertEquals(t, "35 minutes", HumanDuration(35*time.Minute+40*time.Second))
|
||||
assertEquals(t, "About an hour", HumanDuration(1*time.Hour))
|
||||
assertEquals(t, "About an hour", HumanDuration(1*time.Hour+45*time.Minute))
|
||||
assertEquals(t, "3 hours", HumanDuration(3*time.Hour))
|
||||
assertEquals(t, "3 hours", HumanDuration(3*time.Hour+59*time.Minute))
|
||||
assertEquals(t, "4 hours", HumanDuration(3*time.Hour+60*time.Minute))
|
||||
assertEquals(t, "24 hours", HumanDuration(24*time.Hour))
|
||||
assertEquals(t, "36 hours", HumanDuration(1*day+12*time.Hour))
|
||||
assertEquals(t, "2 days", HumanDuration(2*day))
|
||||
assertEquals(t, "7 days", HumanDuration(7*day))
|
||||
assertEquals(t, "13 days", HumanDuration(13*day+5*time.Hour))
|
||||
assertEquals(t, "2 weeks", HumanDuration(2*week))
|
||||
assertEquals(t, "2 weeks", HumanDuration(2*week+4*day))
|
||||
assertEquals(t, "3 weeks", HumanDuration(3*week))
|
||||
assertEquals(t, "4 weeks", HumanDuration(4*week))
|
||||
assertEquals(t, "4 weeks", HumanDuration(4*week+3*day))
|
||||
assertEquals(t, "4 weeks", HumanDuration(1*month))
|
||||
assertEquals(t, "6 weeks", HumanDuration(1*month+2*week))
|
||||
assertEquals(t, "8 weeks", HumanDuration(2*month))
|
||||
assertEquals(t, "3 months", HumanDuration(3*month+1*week))
|
||||
assertEquals(t, "5 months", HumanDuration(5*month+2*week))
|
||||
assertEquals(t, "13 months", HumanDuration(13*month))
|
||||
assertEquals(t, "23 months", HumanDuration(23*month))
|
||||
assertEquals(t, "24 months", HumanDuration(24*month))
|
||||
assertEquals(t, "2 years", HumanDuration(24*month+2*week))
|
||||
assertEquals(t, "3 years", HumanDuration(3*year+2*month))
|
||||
}
|
108
vendor/github.com/docker/docker/pkg/units/size_test.go
generated
vendored
108
vendor/github.com/docker/docker/pkg/units/size_test.go
generated
vendored
@ -1,108 +0,0 @@
|
||||
package units
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBytesSize(t *testing.T) {
|
||||
assertEquals(t, "1 KiB", BytesSize(1024))
|
||||
assertEquals(t, "1 MiB", BytesSize(1024*1024))
|
||||
assertEquals(t, "1 MiB", BytesSize(1048576))
|
||||
assertEquals(t, "2 MiB", BytesSize(2*MiB))
|
||||
assertEquals(t, "3.42 GiB", BytesSize(3.42*GiB))
|
||||
assertEquals(t, "5.372 TiB", BytesSize(5.372*TiB))
|
||||
assertEquals(t, "2.22 PiB", BytesSize(2.22*PiB))
|
||||
}
|
||||
|
||||
func TestHumanSize(t *testing.T) {
|
||||
assertEquals(t, "1 kB", HumanSize(1000))
|
||||
assertEquals(t, "1.024 kB", HumanSize(1024))
|
||||
assertEquals(t, "1 MB", HumanSize(1000000))
|
||||
assertEquals(t, "1.049 MB", HumanSize(1048576))
|
||||
assertEquals(t, "2 MB", HumanSize(2*MB))
|
||||
assertEquals(t, "3.42 GB", HumanSize(float64(3.42*GB)))
|
||||
assertEquals(t, "5.372 TB", HumanSize(float64(5.372*TB)))
|
||||
assertEquals(t, "2.22 PB", HumanSize(float64(2.22*PB)))
|
||||
}
|
||||
|
||||
func TestFromHumanSize(t *testing.T) {
|
||||
assertSuccessEquals(t, 32, FromHumanSize, "32")
|
||||
assertSuccessEquals(t, 32, FromHumanSize, "32b")
|
||||
assertSuccessEquals(t, 32, FromHumanSize, "32B")
|
||||
assertSuccessEquals(t, 32*KB, FromHumanSize, "32k")
|
||||
assertSuccessEquals(t, 32*KB, FromHumanSize, "32K")
|
||||
assertSuccessEquals(t, 32*KB, FromHumanSize, "32kb")
|
||||
assertSuccessEquals(t, 32*KB, FromHumanSize, "32Kb")
|
||||
assertSuccessEquals(t, 32*MB, FromHumanSize, "32Mb")
|
||||
assertSuccessEquals(t, 32*GB, FromHumanSize, "32Gb")
|
||||
assertSuccessEquals(t, 32*TB, FromHumanSize, "32Tb")
|
||||
assertSuccessEquals(t, 32*PB, FromHumanSize, "32Pb")
|
||||
|
||||
assertError(t, FromHumanSize, "")
|
||||
assertError(t, FromHumanSize, "hello")
|
||||
assertError(t, FromHumanSize, "-32")
|
||||
assertError(t, FromHumanSize, "32.3")
|
||||
assertError(t, FromHumanSize, " 32 ")
|
||||
assertError(t, FromHumanSize, "32.3Kb")
|
||||
assertError(t, FromHumanSize, "32 mb")
|
||||
assertError(t, FromHumanSize, "32m b")
|
||||
assertError(t, FromHumanSize, "32bm")
|
||||
}
|
||||
|
||||
func TestRAMInBytes(t *testing.T) {
|
||||
assertSuccessEquals(t, 32, RAMInBytes, "32")
|
||||
assertSuccessEquals(t, 32, RAMInBytes, "32b")
|
||||
assertSuccessEquals(t, 32, RAMInBytes, "32B")
|
||||
assertSuccessEquals(t, 32*KiB, RAMInBytes, "32k")
|
||||
assertSuccessEquals(t, 32*KiB, RAMInBytes, "32K")
|
||||
assertSuccessEquals(t, 32*KiB, RAMInBytes, "32kb")
|
||||
assertSuccessEquals(t, 32*KiB, RAMInBytes, "32Kb")
|
||||
assertSuccessEquals(t, 32*MiB, RAMInBytes, "32Mb")
|
||||
assertSuccessEquals(t, 32*GiB, RAMInBytes, "32Gb")
|
||||
assertSuccessEquals(t, 32*TiB, RAMInBytes, "32Tb")
|
||||
assertSuccessEquals(t, 32*PiB, RAMInBytes, "32Pb")
|
||||
assertSuccessEquals(t, 32*PiB, RAMInBytes, "32PB")
|
||||
assertSuccessEquals(t, 32*PiB, RAMInBytes, "32P")
|
||||
|
||||
assertError(t, RAMInBytes, "")
|
||||
assertError(t, RAMInBytes, "hello")
|
||||
assertError(t, RAMInBytes, "-32")
|
||||
assertError(t, RAMInBytes, "32.3")
|
||||
assertError(t, RAMInBytes, " 32 ")
|
||||
assertError(t, RAMInBytes, "32.3Kb")
|
||||
assertError(t, RAMInBytes, "32 mb")
|
||||
assertError(t, RAMInBytes, "32m b")
|
||||
assertError(t, RAMInBytes, "32bm")
|
||||
}
|
||||
|
||||
func assertEquals(t *testing.T, expected, actual interface{}) {
|
||||
if expected != actual {
|
||||
t.Errorf("Expected '%v' but got '%v'", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// func that maps to the parse function signatures as testing abstraction
|
||||
type parseFn func(string) (int64, error)
|
||||
|
||||
// Define 'String()' for pretty-print
|
||||
func (fn parseFn) String() string {
|
||||
fnName := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
|
||||
return fnName[strings.LastIndex(fnName, ".")+1:]
|
||||
}
|
||||
|
||||
func assertSuccessEquals(t *testing.T, expected int64, fn parseFn, arg string) {
|
||||
res, err := fn(arg)
|
||||
if err != nil || res != expected {
|
||||
t.Errorf("%s(\"%s\") -> expected '%d' but got '%d' with error '%v'", fn, arg, expected, res, err)
|
||||
}
|
||||
}
|
||||
|
||||
func assertError(t *testing.T, fn parseFn, arg string) {
|
||||
res, err := fn(arg)
|
||||
if err == nil && res != -1 {
|
||||
t.Errorf("%s(\"%s\") -> expected error but got '%d'", fn, arg, res)
|
||||
}
|
||||
}
|
67
vendor/github.com/docker/go-units/CONTRIBUTING.md
generated
vendored
Normal file
67
vendor/github.com/docker/go-units/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
# Contributing to go-units
|
||||
|
||||
Want to hack on go-units? Awesome! Here are instructions to get you started.
|
||||
|
||||
go-units is a part of the [Docker](https://www.docker.com) project, and follows
|
||||
the same rules and principles. If you're already familiar with the way
|
||||
Docker does things, you'll feel right at home.
|
||||
|
||||
Otherwise, go read Docker's
|
||||
[contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md),
|
||||
[issue triaging](https://github.com/docker/docker/blob/master/project/ISSUE-TRIAGE.md),
|
||||
[review process](https://github.com/docker/docker/blob/master/project/REVIEWING.md) and
|
||||
[branches and tags](https://github.com/docker/docker/blob/master/project/BRANCHES-AND-TAGS.md).
|
||||
|
||||
### Sign your work
|
||||
|
||||
The sign-off is a simple line at the end of the explanation for the patch. Your
|
||||
signature certifies that you wrote the patch or otherwise have the right to pass
|
||||
it on as an open-source patch. The rules are pretty simple: if you can certify
|
||||
the below (from [developercertificate.org](http://developercertificate.org/)):
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
|
||||
Then you just add a line to every git commit message:
|
||||
|
||||
Signed-off-by: Joe Smith <joe.smith@email.com>
|
||||
|
||||
Use your real name (sorry, no pseudonyms or anonymous contributions.)
|
||||
|
||||
If you set your `user.name` and `user.email` git configs, you can sign your
|
||||
commit automatically with `git commit -s`.
|
21
vendor/github.com/drone/drone-go/LICENSE → vendor/github.com/docker/go-units/LICENSE.code
generated
vendored
21
vendor/github.com/drone/drone-go/LICENSE → vendor/github.com/docker/go-units/LICENSE.code
generated
vendored
@ -1,6 +1,7 @@
|
||||
Apache License
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
https://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
@ -175,28 +176,16 @@ Apache License
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
Copyright 2015 Docker, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
425
vendor/github.com/docker/go-units/LICENSE.docs
generated
vendored
Normal file
425
vendor/github.com/docker/go-units/LICENSE.docs
generated
vendored
Normal file
@ -0,0 +1,425 @@
|
||||
Attribution-ShareAlike 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More_considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution-ShareAlike 4.0 International Public
|
||||
License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution-ShareAlike 4.0 International Public License ("Public
|
||||
License"). To the extent this Public License may be interpreted as a
|
||||
contract, You are granted the Licensed Rights in consideration of Your
|
||||
acceptance of these terms and conditions, and the Licensor grants You
|
||||
such rights in consideration of benefits the Licensor receives from
|
||||
making the Licensed Material available under these terms and
|
||||
conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. BY-SA Compatible License means a license listed at
|
||||
creativecommons.org/compatiblelicenses, approved by Creative
|
||||
Commons as essentially the equivalent of this Public License.
|
||||
|
||||
d. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
e. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
g. License Elements means the license attributes listed in the name
|
||||
of a Creative Commons Public License. The License Elements of this
|
||||
Public License are Attribution and ShareAlike.
|
||||
|
||||
h. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
i. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
j. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
k. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
l. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
m. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. Additional offer from the Licensor -- Adapted Material.
|
||||
Every recipient of Adapted Material from You
|
||||
automatically receives an offer from the Licensor to
|
||||
exercise the Licensed Rights in the Adapted Material
|
||||
under the conditions of the Adapter's License You apply.
|
||||
|
||||
c. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
b. ShareAlike.
|
||||
|
||||
In addition to the conditions in Section 3(a), if You Share
|
||||
Adapted Material You produce, the following conditions also apply.
|
||||
|
||||
1. The Adapter's License You apply must be a Creative Commons
|
||||
license with the same License Elements, this version or
|
||||
later, or a BY-SA Compatible License.
|
||||
|
||||
2. You must include the text of, or the URI or hyperlink to, the
|
||||
Adapter's License You apply. You may satisfy this condition
|
||||
in any reasonable manner based on the medium, means, and
|
||||
context in which You Share Adapted Material.
|
||||
|
||||
3. You may not offer or impose any additional or different terms
|
||||
or conditions on, or apply any Effective Technological
|
||||
Measures to, Adapted Material that restrict exercise of the
|
||||
rights granted under the Adapter's License You apply.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material,
|
||||
|
||||
including for purposes of Section 3(b); and
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public licenses.
|
||||
Notwithstanding, Creative Commons may elect to apply one of its public
|
||||
licenses to material it publishes and in those instances will be
|
||||
considered the "Licensor." Except for the limited purpose of indicating
|
||||
that material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the public
|
||||
licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
27
vendor/github.com/docker/go-units/MAINTAINERS
generated
vendored
Normal file
27
vendor/github.com/docker/go-units/MAINTAINERS
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# go-connections maintainers file
|
||||
#
|
||||
# This file describes who runs the docker/go-connections project and how.
|
||||
# This is a living document - if you see something out of date or missing, speak up!
|
||||
#
|
||||
# It is structured to be consumable by both humans and programs.
|
||||
# To extract its contents programmatically, use any TOML-compliant parser.
|
||||
#
|
||||
# This file is compiled into the MAINTAINERS file in docker/opensource.
|
||||
#
|
||||
[Org]
|
||||
[Org."Core maintainers"]
|
||||
people = [
|
||||
"calavera",
|
||||
]
|
||||
|
||||
[people]
|
||||
|
||||
# A reference list of all people associated with the project.
|
||||
# All other sections should refer to people by their canonical key
|
||||
# in the people section.
|
||||
|
||||
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
|
||||
[people.calavera]
|
||||
Name = "David Calavera"
|
||||
Email = "david.calavera@gmail.com"
|
||||
GitHub = "calavera"
|
18
vendor/github.com/docker/go-units/README.md
generated
vendored
Normal file
18
vendor/github.com/docker/go-units/README.md
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
[](https://godoc.org/github.com/docker/go-units)
|
||||
|
||||
# Introduction
|
||||
|
||||
go-units is a library to transform human friendly measurements into machine friendly values.
|
||||
|
||||
## Usage
|
||||
|
||||
See the [docs in godoc](https://godoc.org/github.com/docker/go-units) for examples and documentation.
|
||||
|
||||
## Copyright and license
|
||||
|
||||
Copyright © 2015 Docker, Inc. All rights reserved, except as follows. Code
|
||||
is released under the Apache 2.0 license. The README.md file, and files in the
|
||||
"docs" folder are licensed under the Creative Commons Attribution 4.0
|
||||
International License under the terms and conditions set forth in the file
|
||||
"LICENSE.docs". You may obtain a duplicate copy of the same license, titled
|
||||
CC-BY-SA-4.0, at http://creativecommons.org/licenses/by/4.0/.
|
11
vendor/github.com/docker/go-units/circle.yml
generated
vendored
Normal file
11
vendor/github.com/docker/go-units/circle.yml
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
dependencies:
|
||||
post:
|
||||
# install golint
|
||||
- go get github.com/golang/lint/golint
|
||||
|
||||
test:
|
||||
pre:
|
||||
# run analysis before tests
|
||||
- go vet ./...
|
||||
- test -z "$(golint ./... | tee /dev/stderr)"
|
||||
- test -z "$(gofmt -s -l . | tee /dev/stderr)"
|
4
vendor/github.com/docker/docker/pkg/units/duration.go → vendor/github.com/docker/go-units/duration.go
generated
vendored
4
vendor/github.com/docker/docker/pkg/units/duration.go → vendor/github.com/docker/go-units/duration.go
generated
vendored
@ -1,3 +1,5 @@
|
||||
// Package units provides helper function to parse and print size and time units
|
||||
// in human-readable format.
|
||||
package units
|
||||
|
||||
import (
|
||||
@ -6,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
// HumanDuration returns a human-readable approximation of a duration
|
||||
// (eg. "About a minute", "4 hours ago", etc.)
|
||||
// (eg. "About a minute", "4 hours ago", etc.).
|
||||
func HumanDuration(d time.Duration) string {
|
||||
if seconds := int(d.Seconds()); seconds < 1 {
|
||||
return "Less than a second"
|
10
vendor/github.com/docker/docker/pkg/units/size.go → vendor/github.com/docker/go-units/size.go
generated
vendored
10
vendor/github.com/docker/docker/pkg/units/size.go → vendor/github.com/docker/go-units/size.go
generated
vendored
@ -38,7 +38,7 @@ var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
|
||||
var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}
|
||||
|
||||
// CustomSize returns a human-readable approximation of a size
|
||||
// using custom format
|
||||
// using custom format.
|
||||
func CustomSize(format string, size float64, base float64, _map []string) string {
|
||||
i := 0
|
||||
for size >= base {
|
||||
@ -49,17 +49,19 @@ func CustomSize(format string, size float64, base float64, _map []string) string
|
||||
}
|
||||
|
||||
// HumanSize returns a human-readable approximation of a size
|
||||
// using SI standard (eg. "44kB", "17MB")
|
||||
// capped at 4 valid numbers (eg. "2.746 MB", "796 KB").
|
||||
func HumanSize(size float64) string {
|
||||
return CustomSize("%.4g %s", size, 1000.0, decimapAbbrs)
|
||||
}
|
||||
|
||||
// BytesSize returns a human-readable size in bytes, kibibytes,
|
||||
// mebibytes, gibibytes, or tebibytes (eg. "44kiB", "17MiB").
|
||||
func BytesSize(size float64) string {
|
||||
return CustomSize("%.4g %s", size, 1024.0, binaryAbbrs)
|
||||
}
|
||||
|
||||
// FromHumanSize returns an integer from a human-readable specification of a
|
||||
// size using SI standard (eg. "44kB", "17MB")
|
||||
// size using SI standard (eg. "44kB", "17MB").
|
||||
func FromHumanSize(size string) (int64, error) {
|
||||
return parseSize(size, decimalMap)
|
||||
}
|
||||
@ -72,7 +74,7 @@ func RAMInBytes(size string) (int64, error) {
|
||||
return parseSize(size, binaryMap)
|
||||
}
|
||||
|
||||
// Parses the human-readable size string into the amount it represents
|
||||
// Parses the human-readable size string into the amount it represents.
|
||||
func parseSize(sizeStr string, uMap unitMap) (int64, error) {
|
||||
matches := sizeRegex.FindStringSubmatch(sizeStr)
|
||||
if len(matches) != 3 {
|
109
vendor/github.com/docker/go-units/ulimit.go
generated
vendored
Normal file
109
vendor/github.com/docker/go-units/ulimit.go
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
package units
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Ulimit is a human friendly version of Rlimit.
|
||||
type Ulimit struct {
|
||||
Name string
|
||||
Hard int64
|
||||
Soft int64
|
||||
}
|
||||
|
||||
// Rlimit specifies the resource limits, such as max open files.
|
||||
type Rlimit struct {
|
||||
Type int `json:"type,omitempty"`
|
||||
Hard uint64 `json:"hard,omitempty"`
|
||||
Soft uint64 `json:"soft,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
// magic numbers for making the syscall
|
||||
// some of these are defined in the syscall package, but not all.
|
||||
// Also since Windows client doesn't get access to the syscall package, need to
|
||||
// define these here
|
||||
rlimitAs = 9
|
||||
rlimitCore = 4
|
||||
rlimitCPU = 0
|
||||
rlimitData = 2
|
||||
rlimitFsize = 1
|
||||
rlimitLocks = 10
|
||||
rlimitMemlock = 8
|
||||
rlimitMsgqueue = 12
|
||||
rlimitNice = 13
|
||||
rlimitNofile = 7
|
||||
rlimitNproc = 6
|
||||
rlimitRss = 5
|
||||
rlimitRtprio = 14
|
||||
rlimitRttime = 15
|
||||
rlimitSigpending = 11
|
||||
rlimitStack = 3
|
||||
)
|
||||
|
||||
var ulimitNameMapping = map[string]int{
|
||||
//"as": rlimitAs, // Disabled since this doesn't seem usable with the way Docker inits a container.
|
||||
"core": rlimitCore,
|
||||
"cpu": rlimitCPU,
|
||||
"data": rlimitData,
|
||||
"fsize": rlimitFsize,
|
||||
"locks": rlimitLocks,
|
||||
"memlock": rlimitMemlock,
|
||||
"msgqueue": rlimitMsgqueue,
|
||||
"nice": rlimitNice,
|
||||
"nofile": rlimitNofile,
|
||||
"nproc": rlimitNproc,
|
||||
"rss": rlimitRss,
|
||||
"rtprio": rlimitRtprio,
|
||||
"rttime": rlimitRttime,
|
||||
"sigpending": rlimitSigpending,
|
||||
"stack": rlimitStack,
|
||||
}
|
||||
|
||||
// ParseUlimit parses and returns a Ulimit from the specified string.
|
||||
func ParseUlimit(val string) (*Ulimit, error) {
|
||||
parts := strings.SplitN(val, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
return nil, fmt.Errorf("invalid ulimit argument: %s", val)
|
||||
}
|
||||
|
||||
if _, exists := ulimitNameMapping[parts[0]]; !exists {
|
||||
return nil, fmt.Errorf("invalid ulimit type: %s", parts[0])
|
||||
}
|
||||
|
||||
limitVals := strings.SplitN(parts[1], ":", 2)
|
||||
if len(limitVals) > 2 {
|
||||
return nil, fmt.Errorf("too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1])
|
||||
}
|
||||
|
||||
soft, err := strconv.ParseInt(limitVals[0], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hard := soft // in case no hard was set
|
||||
if len(limitVals) == 2 {
|
||||
hard, err = strconv.ParseInt(limitVals[1], 10, 64)
|
||||
}
|
||||
if soft > hard {
|
||||
return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, hard)
|
||||
}
|
||||
|
||||
return &Ulimit{Name: parts[0], Soft: soft, Hard: hard}, nil
|
||||
}
|
||||
|
||||
// GetRlimit returns the RLimit corresponding to Ulimit.
|
||||
func (u *Ulimit) GetRlimit() (*Rlimit, error) {
|
||||
t, exists := ulimitNameMapping[u.Name]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("invalid ulimit name %s", u.Name)
|
||||
}
|
||||
|
||||
return &Rlimit{Type: t, Soft: uint64(u.Soft), Hard: uint64(u.Hard)}, nil
|
||||
}
|
||||
|
||||
func (u *Ulimit) String() string {
|
||||
return fmt.Sprintf("%s=%d:%d", u.Name, u.Soft, u.Hard)
|
||||
}
|
11
vendor/github.com/drone/drone-exec/docker/docker.go
generated
vendored
11
vendor/github.com/drone/drone-exec/docker/docker.go
generated
vendored
@ -12,16 +12,17 @@ type Client struct {
|
||||
}
|
||||
|
||||
func NewClient(docker dockerclient.Client) (*Client, error) {
|
||||
|
||||
// creates an ambassador container
|
||||
conf := &dockerclient.ContainerConfig{}
|
||||
conf.HostConfig = dockerclient.HostConfig{}
|
||||
conf.HostConfig = dockerclient.HostConfig{
|
||||
MemorySwappiness: -1,
|
||||
}
|
||||
conf.Entrypoint = []string{"/bin/sleep"}
|
||||
conf.Cmd = []string{"86400"}
|
||||
conf.Image = "gliderlabs/alpine:3.1"
|
||||
conf.Volumes = map[string]struct{}{}
|
||||
conf.Volumes["/drone"] = struct{}{}
|
||||
info, err := Start(docker, conf, false)
|
||||
info, err := Start(docker, conf, nil, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -31,9 +32,9 @@ func NewClient(docker dockerclient.Client) (*Client, error) {
|
||||
|
||||
// CreateContainer creates a container and internally
|
||||
// caches its container id.
|
||||
func (c *Client) CreateContainer(conf *dockerclient.ContainerConfig, name string) (string, error) {
|
||||
func (c *Client) CreateContainer(conf *dockerclient.ContainerConfig, name string, auth *dockerclient.AuthConfig) (string, error) {
|
||||
conf.Env = append(conf.Env, "affinity:container=="+c.info.Id)
|
||||
id, err := c.Client.CreateContainer(conf, name)
|
||||
id, err := c.Client.CreateContainer(conf, name, auth)
|
||||
if err == nil {
|
||||
c.names = append(c.names, id)
|
||||
}
|
||||
|
91
vendor/github.com/drone/drone-exec/docker/stdcopy.go
generated
vendored
91
vendor/github.com/drone/drone-exec/docker/stdcopy.go
generated
vendored
@ -4,29 +4,71 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
StdWriterPrefixLen = 8
|
||||
StdWriterFdIndex = 0
|
||||
StdWriterSizeIndex = 4
|
||||
stdWriterPrefixLen = 8
|
||||
stdWriterFdIndex = 0
|
||||
stdWriterSizeIndex = 4
|
||||
|
||||
startingBufLen = 32*1024 + stdWriterPrefixLen + 1
|
||||
)
|
||||
|
||||
type StdType [StdWriterPrefixLen]byte
|
||||
// StdType prefixes type and length to standard stream.
|
||||
type StdType [stdWriterPrefixLen]byte
|
||||
|
||||
var (
|
||||
Stdin StdType = StdType{0: 0}
|
||||
Stdout StdType = StdType{0: 1}
|
||||
Stderr StdType = StdType{0: 2}
|
||||
// Stdin represents standard input stream type.
|
||||
Stdin = StdType{0: 0}
|
||||
// Stdout represents standard output stream type.
|
||||
Stdout = StdType{0: 1}
|
||||
// Stderr represents standard error steam type.
|
||||
Stderr = StdType{0: 2}
|
||||
)
|
||||
|
||||
// StdWriter is wrapper of io.Writer with extra customized info.
|
||||
type StdWriter struct {
|
||||
io.Writer
|
||||
prefix StdType
|
||||
sizeBuf []byte
|
||||
}
|
||||
|
||||
var ErrInvalidStdHeader = errors.New("Unrecognized input header")
|
||||
func (w *StdWriter) Write(buf []byte) (n int, err error) {
|
||||
var n1, n2 int
|
||||
if w == nil || w.Writer == nil {
|
||||
return 0, errors.New("Writer not instantiated")
|
||||
}
|
||||
binary.BigEndian.PutUint32(w.prefix[4:], uint32(len(buf)))
|
||||
n1, err = w.Writer.Write(w.prefix[:])
|
||||
if err != nil {
|
||||
n = n1 - stdWriterPrefixLen
|
||||
} else {
|
||||
n2, err = w.Writer.Write(buf)
|
||||
n = n1 + n2 - stdWriterPrefixLen
|
||||
}
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// NewStdWriter instantiates a new Writer.
|
||||
// Everything written to it will be encapsulated using a custom format,
|
||||
// and written to the underlying `w` stream.
|
||||
// This allows multiple write streams (e.g. stdout and stderr) to be muxed into a single connection.
|
||||
// `t` indicates the id of the stream to encapsulate.
|
||||
// It can be stdcopy.Stdin, stdcopy.Stdout, stdcopy.Stderr.
|
||||
func NewStdWriter(w io.Writer, t StdType) *StdWriter {
|
||||
return &StdWriter{
|
||||
Writer: w,
|
||||
prefix: t,
|
||||
sizeBuf: make([]byte, 4),
|
||||
}
|
||||
}
|
||||
|
||||
var errInvalidStdHeader = errors.New("Unrecognized input header")
|
||||
|
||||
// StdCopy is a modified version of io.Copy.
|
||||
//
|
||||
@ -40,7 +82,7 @@ var ErrInvalidStdHeader = errors.New("Unrecognized input header")
|
||||
// `written` will hold the total number of bytes written to `dstout` and `dsterr`.
|
||||
func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error) {
|
||||
var (
|
||||
buf = make([]byte, 32*1024+StdWriterPrefixLen+1)
|
||||
buf = make([]byte, startingBufLen)
|
||||
bufLen = len(buf)
|
||||
nr, nw int
|
||||
er, ew error
|
||||
@ -50,23 +92,25 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
|
||||
|
||||
for {
|
||||
// Make sure we have at least a full header
|
||||
for nr < StdWriterPrefixLen {
|
||||
for nr < stdWriterPrefixLen {
|
||||
var nr2 int
|
||||
nr2, er = src.Read(buf[nr:])
|
||||
nr += nr2
|
||||
if er == io.EOF {
|
||||
if nr < StdWriterPrefixLen {
|
||||
if nr < stdWriterPrefixLen {
|
||||
logrus.Debugf("Corrupted prefix: %v", buf[:nr])
|
||||
return written, nil
|
||||
}
|
||||
break
|
||||
}
|
||||
if er != nil {
|
||||
logrus.Debugf("Error reading header: %s", er)
|
||||
return 0, er
|
||||
}
|
||||
}
|
||||
|
||||
// Check the first byte to know where to write
|
||||
switch buf[StdWriterFdIndex] {
|
||||
switch buf[stdWriterFdIndex] {
|
||||
case 0:
|
||||
fallthrough
|
||||
case 1:
|
||||
@ -76,49 +120,54 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
|
||||
// Write on stderr
|
||||
out = dsterr
|
||||
default:
|
||||
return 0, ErrInvalidStdHeader
|
||||
logrus.Debugf("Error selecting output fd: (%d)", buf[stdWriterFdIndex])
|
||||
return 0, errInvalidStdHeader
|
||||
}
|
||||
|
||||
// Retrieve the size of the frame
|
||||
frameSize = int(binary.BigEndian.Uint32(buf[StdWriterSizeIndex : StdWriterSizeIndex+4]))
|
||||
frameSize = int(binary.BigEndian.Uint32(buf[stdWriterSizeIndex : stdWriterSizeIndex+4]))
|
||||
|
||||
// Check if the buffer is big enough to read the frame.
|
||||
// Extend it if necessary.
|
||||
if frameSize+StdWriterPrefixLen > bufLen {
|
||||
buf = append(buf, make([]byte, frameSize+StdWriterPrefixLen-bufLen+1)...)
|
||||
if frameSize+stdWriterPrefixLen > bufLen {
|
||||
buf = append(buf, make([]byte, frameSize+stdWriterPrefixLen-bufLen+1)...)
|
||||
bufLen = len(buf)
|
||||
}
|
||||
|
||||
// While the amount of bytes read is less than the size of the frame + header, we keep reading
|
||||
for nr < frameSize+StdWriterPrefixLen {
|
||||
for nr < frameSize+stdWriterPrefixLen {
|
||||
var nr2 int
|
||||
nr2, er = src.Read(buf[nr:])
|
||||
nr += nr2
|
||||
if er == io.EOF {
|
||||
if nr < frameSize+StdWriterPrefixLen {
|
||||
if nr < frameSize+stdWriterPrefixLen {
|
||||
logrus.Debugf("Corrupted frame: %v", buf[stdWriterPrefixLen:nr])
|
||||
return written, nil
|
||||
}
|
||||
break
|
||||
}
|
||||
if er != nil {
|
||||
logrus.Debugf("Error reading frame: %s", er)
|
||||
return 0, er
|
||||
}
|
||||
}
|
||||
|
||||
// Write the retrieved frame (without header)
|
||||
nw, ew = out.Write(buf[StdWriterPrefixLen : frameSize+StdWriterPrefixLen])
|
||||
nw, ew = out.Write(buf[stdWriterPrefixLen : frameSize+stdWriterPrefixLen])
|
||||
if ew != nil {
|
||||
logrus.Debugf("Error writing frame: %s", ew)
|
||||
return 0, ew
|
||||
}
|
||||
// If the frame has not been fully written: error
|
||||
if nw != frameSize {
|
||||
logrus.Debugf("Error Short Write: (%d on %d)", nw, frameSize)
|
||||
return 0, io.ErrShortWrite
|
||||
}
|
||||
written += int64(nw)
|
||||
|
||||
// Move the rest of the buffer to the beginning
|
||||
copy(buf, buf[frameSize+StdWriterPrefixLen:])
|
||||
copy(buf, buf[frameSize+stdWriterPrefixLen:])
|
||||
// Move the index
|
||||
nr -= frameSize + StdWriterPrefixLen
|
||||
nr -= frameSize + stdWriterPrefixLen
|
||||
}
|
||||
}
|
||||
|
100
vendor/github.com/drone/drone-exec/docker/util.go
generated
vendored
100
vendor/github.com/drone/drone-exec/docker/util.go
generated
vendored
@ -2,8 +2,8 @@ package docker
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
// "strings"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/samalba/dockerclient"
|
||||
@ -20,20 +20,18 @@ var (
|
||||
Stdout: true,
|
||||
Stderr: true,
|
||||
}
|
||||
|
||||
// options to fetch the stdout and stderr logs
|
||||
// by tailing the output.
|
||||
logOptsTail = &dockerclient.LogOptions{
|
||||
Follow: true,
|
||||
Stdout: true,
|
||||
Stderr: true,
|
||||
}
|
||||
)
|
||||
|
||||
func Run(client dockerclient.Client, conf *dockerclient.ContainerConfig, pull bool) (*dockerclient.ContainerInfo, error) {
|
||||
func Run(client dockerclient.Client, conf *dockerclient.ContainerConfig, auth *dockerclient.AuthConfig, pull bool, outw, errw io.Writer) (*dockerclient.ContainerInfo, error) {
|
||||
if outw == nil {
|
||||
outw = os.Stdout
|
||||
}
|
||||
if errw == nil {
|
||||
errw = os.Stdout
|
||||
}
|
||||
|
||||
// fetches the container information.
|
||||
info, err := Start(client, conf, pull)
|
||||
info, err := Start(client, conf, auth, pull)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -50,27 +48,60 @@ func Run(client dockerclient.Client, conf *dockerclient.ContainerConfig, pull bo
|
||||
errc := make(chan error, 1)
|
||||
infoc := make(chan *dockerclient.ContainerInfo, 1)
|
||||
go func() {
|
||||
|
||||
// blocks and waits for the container to finish
|
||||
// by streaming the logs (to /dev/null). Ideally
|
||||
// we could use the `wait` function instead
|
||||
rc, err := client.ContainerLogs(info.Id, logOptsTail)
|
||||
if err != nil {
|
||||
log.Errorf("Error tailing %s. %s\n", conf.Image, err)
|
||||
errc <- err
|
||||
return
|
||||
// options to fetch the stdout and stderr logs
|
||||
// by tailing the output.
|
||||
logOptsTail := &dockerclient.LogOptions{
|
||||
Follow: true,
|
||||
Stdout: true,
|
||||
Stderr: true,
|
||||
}
|
||||
defer rc.Close()
|
||||
StdCopy(os.Stdout, os.Stdout, rc)
|
||||
|
||||
// fetches the container information
|
||||
info, err := client.InspectContainer(info.Id)
|
||||
if err != nil {
|
||||
log.Errorf("Error getting exit code for %s. %s\n", conf.Image, err)
|
||||
errc <- err
|
||||
return
|
||||
// It's possible that the docker logs endpoint returns before the container
|
||||
// is done, we'll naively resume up to 5 times if when the logs unblocks
|
||||
// the container is still reported to be running.
|
||||
for attempts := 0; attempts < 5; attempts++ {
|
||||
if attempts > 0 {
|
||||
// When resuming the stream, only grab the last line when starting
|
||||
// the tailing.
|
||||
logOptsTail.Tail = 1
|
||||
}
|
||||
|
||||
// blocks and waits for the container to finish
|
||||
// by streaming the logs (to /dev/null). Ideally
|
||||
// we could use the `wait` function instead
|
||||
rc, err := client.ContainerLogs(info.Id, logOptsTail)
|
||||
if err != nil {
|
||||
log.Errorf("Error tailing %s. %s\n", conf.Image, err)
|
||||
errc <- err
|
||||
return
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
_, err = StdCopy(outw, errw, rc)
|
||||
if err != nil {
|
||||
log.Errorf("Error streaming docker logs for %s. %s\n", conf.Image, err)
|
||||
errc <- err
|
||||
return
|
||||
}
|
||||
|
||||
// fetches the container information
|
||||
info, err := client.InspectContainer(info.Id)
|
||||
if err != nil {
|
||||
log.Errorf("Error getting exit code for %s. %s\n", conf.Image, err)
|
||||
errc <- err
|
||||
return
|
||||
}
|
||||
|
||||
if !info.State.Running {
|
||||
// The container is no longer running, there should be no more logs to tail.
|
||||
infoc <- info
|
||||
return
|
||||
}
|
||||
|
||||
log.Debugf("Attempting to resume log tailing after %d attempts.\n", attempts)
|
||||
}
|
||||
infoc <- info
|
||||
|
||||
errc <- errors.New("Maximum number of attempts made while tailing logs.")
|
||||
}()
|
||||
|
||||
select {
|
||||
@ -81,25 +112,26 @@ func Run(client dockerclient.Client, conf *dockerclient.ContainerConfig, pull bo
|
||||
}
|
||||
}
|
||||
|
||||
func Start(client dockerclient.Client, conf *dockerclient.ContainerConfig, pull bool) (*dockerclient.ContainerInfo, error) {
|
||||
func Start(client dockerclient.Client, conf *dockerclient.ContainerConfig, auth *dockerclient.AuthConfig, pull bool) (*dockerclient.ContainerInfo, error) {
|
||||
|
||||
// force-pull the image if specified.
|
||||
if pull {
|
||||
log.Printf("Pulling image %s", conf.Image)
|
||||
client.PullImage(conf.Image, nil)
|
||||
client.PullImage(conf.Image, auth)
|
||||
}
|
||||
|
||||
// attempts to create the contianer
|
||||
id, err := client.CreateContainer(conf, "")
|
||||
id, err := client.CreateContainer(conf, "", auth)
|
||||
if err != nil {
|
||||
log.Printf("Pulling image %s", conf.Image)
|
||||
|
||||
// and pull the image and re-create if that fails
|
||||
err = client.PullImage(conf.Image, nil)
|
||||
err = client.PullImage(conf.Image, auth)
|
||||
if err != nil {
|
||||
log.Errorf("Error pulling %s. %s\n", conf.Image, err)
|
||||
return nil, err
|
||||
}
|
||||
id, err = client.CreateContainer(conf, "")
|
||||
id, err = client.CreateContainer(conf, "", auth)
|
||||
if err != nil {
|
||||
log.Errorf("Error creating %s. %s\n", conf.Image, err)
|
||||
client.RemoveContainer(id, true, true)
|
||||
|
104
vendor/github.com/drone/drone-exec/yaml/secure/secure_test.go
generated
vendored
104
vendor/github.com/drone/drone-exec/yaml/secure/secure_test.go
generated
vendored
@ -1,104 +0,0 @@
|
||||
package secure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func Test_Secure(t *testing.T) {
|
||||
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Secure yaml", func() {
|
||||
|
||||
priv, _ := decodePrivateKey(fakePriv)
|
||||
pub := priv.PublicKey
|
||||
pem := encodePrivateKey(priv)
|
||||
|
||||
g.It("Should encrypt and decrypt", func() {
|
||||
plain := checksumYaml
|
||||
encrypted, err := encrypt(plain, &pub)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
decrypted, err := decrypt(encrypted, priv)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(plain).Equal(string(decrypted))
|
||||
})
|
||||
|
||||
g.It("Should decrypt a yaml with slice parameters", func() {
|
||||
secure, err := Parse(sliceEnc, pem)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(secure.Checksum).Equal("fa4d4048a6bd1a94f2775039ecf29b812d9cfe6b")
|
||||
g.Assert(secure.Environment.Map()["FOO"]).Equal("Bar")
|
||||
g.Assert(secure.Environment.Map()["BAZ"]).Equal("BOO")
|
||||
})
|
||||
|
||||
g.It("Should decrypt a yaml with map parameters", func() {
|
||||
secure, err := Parse(mapEnc, pem)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(secure.Checksum).Equal("fa4d4048a6bd1a94f2775039ecf29b812d9cfe6b")
|
||||
g.Assert(secure.Environment.Map()["FOO"]).Equal("Bar")
|
||||
g.Assert(secure.Environment.Map()["BAZ"]).Equal("BOO")
|
||||
})
|
||||
|
||||
g.It("Should handle an empty environment map", func() {
|
||||
secure, err := Parse(checksumEnc, pem)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(secure.Checksum).Equal("fa4d4048a6bd1a94f2775039ecf29b812d9cfe6b")
|
||||
g.Assert(len(secure.Environment.Map())).Equal(0)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
var sliceYaml = `
|
||||
checksum: fa4d4048a6bd1a94f2775039ecf29b812d9cfe6b
|
||||
environment:
|
||||
- FOO=BAR
|
||||
- BAZ=BOO
|
||||
`
|
||||
|
||||
var mapYaml = `
|
||||
checksum: fa4d4048a6bd1a94f2775039ecf29b812d9cfe6b
|
||||
environment:
|
||||
FOO: BAR
|
||||
BAZ: BOO
|
||||
`
|
||||
|
||||
var checksumYaml = `
|
||||
checksum: fa4d4048a6bd1a94f2775039ecf29b812d9cfe6b
|
||||
`
|
||||
|
||||
var sliceEnc = `eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.0s31RxVuZUEqEFs79R-1iAR3nN-tt3Zp4ATvsDbBauI5SdQFGzSY_EN58jNghd1CC4RU0Y4ltwoxcwcf8e-buAwnPFlE3xHPlFilNOR-Cs9lrjmaRGbxBOq2P4RRDSlQ6ysTHNyNqHKeZHehQc57om2GAP7Ejxpdqs4OVv_ZhR07wuXw1Meisbh9Mr0DSzGot4Rcv72IqXdEGft1r6SrRasTkJNh1_fYnOSDuiCpUadLEKkA2yePVoln4MxVC4lJPTOcatDEyYvLSHLHc316KNw2hML2hkvwEy90AW_uTbhtmap7q2myRQkhvXdDVuYCEflq2qPTFf_kacgArWnq-g.kh-vFwI-mpv7LzLz.w1i3Db7p7fQAU7u7cPzbUIy0-F1A2lM9afUCC6alyna4yNv2nAcPPBEwxPVnHrn1d-LenWRpcyUgzgTfmkYCODzP_YnjVmgkau2b3sQlK2isoImDAGy5mPo.PuvJO_NeBO07oyylSEX2lw`
|
||||
|
||||
var mapEnc = `eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.HzrLexECJiBaP4ptn-uPueg4Irf4H73VcCF4UbiCs0jZur2ss8FJM3OF7ZD-eaSIMPlogpFb5PCQWfr4LMD9fae0ss7ced6Kue1q1wI_sgwUVtDC_kq11yG6qmst4yJ7WCqVnWIEitCov39qyaMsjOLtpTJIuZH3h4Jc19kIIW8Wk_v4Oqd4Yg1JklHRMfrjB3U0OA3U-MLStrzdfk9KzPk_3FQnNXILPAYQZGxh02doLP7sYlo_d8wdV6Km26br4xoW8DK1XUKLvbVE_oXnRcL95eZsvF37ADiHhKI1FfqJo31rxVTSh0HUwdNHOUldtRzyN0oAw4grt_aHGNxvdw.eaJt1GAGBl3voC64.D3IIxEGgkAMo4-UjdYtGax6WFefU5vGqOduDzvU7yOyC_flQ_5C-LrjqC1tPEK9sjdPLt8ghxjtZhCTMFjl1xX77HwAAUNBjyBZVSDaJblsOazkmPZOF.weKJmve-z7DBWMdKLASA3Q`
|
||||
|
||||
var checksumEnc = `eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.lduGCINc5DVUD6hi3UHzWNkuKLlsrXudLfrktD3gOI36J6r58DlMAGcUNLfgSAU4v0kf9L407EkB4dtqwXbkhNeihNw69BbYa94QQ1H2uW3BNQbPq-1JeeZLAU6dXmkRXZur4KGNuWls4tMqd-Z9OyRSCBzogDzMf2JGJ-eLSL63zhBCzKGwQ6yE1N6cZsS2NN0-1BEgrAk-dC76motQvcRTHmiosADrEGUAM6xy-LQSkcC8DImpXajv-AFlFv5F4BtFBg9e7MLrVishwZAFKq-lexWLRqlcf7xqgU5GVt6_3VtuoWtVIyUFP4ZnM0KFScKrG6zsd1h7G5_zSf9AMA.YaL_NLt5Ei_7BEeo.7igBRj8A-EfvsT4VafSBCi_68_lelDwcANbtePmZENuuxEaLSRyfMsawKY0Oyc9DdYCsNA.Np3a7xQRMNHK1z6Nb8oGXg`
|
||||
|
||||
var fakePriv = `
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA71FaA+otDak2rXF/4h69Tz+OxS6NOWaOc/n7dinHXnlo3Toy
|
||||
ZzvwweJGQKIOfPNBMncz+8h6oLOByFvb95Z1UEM0d+KCFCCutOeN9NNMw4fkUtSZ
|
||||
7sm6T35wQUkDOiO1YAGy27hQfT7iryhPwA8KmgZmt7toNNf+WymPR8DMwAAYeqHA
|
||||
5DIEWWsg+RLohOJ0itIk9q6Us9WYhng0sZ9+U+C87FospjKRMyAinSvKx0Uan4ap
|
||||
YGbLjDQHimWtimfT4XWCGTO1cWno378Vm/newUN6WVaeZ2CSHcWgD2fWcjFixX2A
|
||||
SvcvfuCo7yZPUPWeiYKrc5d1CC3ncocu43LhSQIDAQABAoIBAQDIbYKM+sfmxAwF
|
||||
8KOg1gvIXjuNCrK+GxU9LmSajtzpU5cuiHoEGaBGUOJzaQXnQbcds9W2ji2dfxk3
|
||||
my87SShRIyfDK9GzV7fZzIAIRhrpO1tOv713zj0aLJOJKcPpIlTZ5jJMcC4A5vTk
|
||||
q0c3W6GOY8QNJohckXT2FnVoK6GPPiaZnavkwH33cJk0j1vMsbADdKF7Jdfq9FBF
|
||||
Lx+Za7wo79MQIr68KEqsqMpmrawIf1T3TqOCNbkPCL2tu5EfoyGIItrH33SBOV/B
|
||||
HbIfe4nJYZMWXhe3kZ/xCFqiRx6/wlc5pGCwCicgHJJe/l8Y9OticDCCyJDQtD8I
|
||||
6927/j2NAoGBAPNRRY8r5ES5f8ftEktcLwh2zw08PNkcolTeqsEMbWAQspV/v+Ay
|
||||
4niEXIN3ix2yTnMgrtxRGO7zdPnMaTN8E88FsSDKQ97lm7m3jo7lZtDMz16UxGmd
|
||||
AOOuXwUtpngz7OrQ25NXhvFYLTgLoPsv3PbFbF1pwbhZqPTttTdg5so3AoGBAPvK
|
||||
ta/n7DMZd/HptrkdkxxHaGN19ZjBVIqyeORhIDznEYjv9Z90JvzRxCmUriD4fyJC
|
||||
/XSTytORa34UgmOk1XFtxWusXhnYqCTIHG/MKCy9D4ifzFzii9y/M+EnQIMb658l
|
||||
+edLyrGFla+t5NS1XAqDYjfqpUFbMvU1kVoDJ/B/AoGBANBQe3o5PMSuAD19tdT5
|
||||
Rnc7qMcPFJVZE44P2SdQaW/+u7aM2gyr5AMEZ2RS+7LgDpQ4nhyX/f3OSA75t/PR
|
||||
PfBXUi/dm8AA2pNlGNM0ihMn1j6GpaY6OiG0DzwSulxdMHBVgjgijrCgKo66Pgfw
|
||||
EYDgw4cyXR1k/ec8gJK6Dr1/AoGBANvmSY77Kdnm4E4yIxbAsX39DznuBzQFhGQt
|
||||
Qk+SU6lc1H+Xshg0ROh/+qWl5/17iOzPPLPXb0getJZEKywDBTYu/D/xJa3E/fRB
|
||||
oDQzRNLtuudDSCPG5wc/JXv53+mhNMKlU/+gvcEUPYpUgIkUavHzlI/pKbJOh86H
|
||||
ng3Su8rZAn9w/zkoJu+n7sHta/Hp6zPTbvjZ1EijZp0+RygBgiv9UjDZ6D9EGcjR
|
||||
ZiFwuc8I0g7+GRkgG2NbfqX5Cewb/nbJQpHPO31bqJrcLzU0KurYAwQVx6WGW0He
|
||||
ERIlTeOMxVo6M0OpI+rH5bOLdLLEVhNtM/4HUFi1Qy6CCMbN2t3H
|
||||
-----END RSA PRIVATE KEY-----
|
||||
`
|
33
vendor/github.com/drone/drone-exec/yaml/secure/types_test.go
generated
vendored
33
vendor/github.com/drone/drone-exec/yaml/secure/types_test.go
generated
vendored
@ -1,33 +0,0 @@
|
||||
package secure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/franela/goblin"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func Test_MapEqualSlice(t *testing.T) {
|
||||
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("MapEqualSlice", func() {
|
||||
|
||||
g.It("Should unmarshal map", func() {
|
||||
|
||||
out := &Secure{}
|
||||
err := yaml.Unmarshal([]byte(mapYaml), out)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(out.Environment.Map()["FOO"]).Equal("BAR")
|
||||
g.Assert(out.Environment.Map()["BAZ"]).Equal("BOO")
|
||||
|
||||
})
|
||||
|
||||
g.It("Should unmarshal slice", func() {
|
||||
out := &Secure{}
|
||||
err := yaml.Unmarshal([]byte(sliceYaml), out)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(out.Environment.Map()["FOO"]).Equal("BAR")
|
||||
g.Assert(out.Environment.Map()["BAZ"]).Equal("BOO")
|
||||
})
|
||||
})
|
||||
}
|
6
vendor/github.com/drone/drone-go/.drone.yml
generated
vendored
6
vendor/github.com/drone/drone-go/.drone.yml
generated
vendored
@ -1,6 +0,0 @@
|
||||
build:
|
||||
image: golang:1.5
|
||||
commands:
|
||||
- go get ./...
|
||||
- go build ./...
|
||||
- go test ./...
|
24
vendor/github.com/drone/drone-go/.gitignore
generated
vendored
24
vendor/github.com/drone/drone-go/.gitignore
generated
vendored
@ -1,24 +0,0 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
50
vendor/github.com/drone/drone-go/README.md
generated
vendored
50
vendor/github.com/drone/drone-go/README.md
generated
vendored
@ -1,50 +0,0 @@
|
||||
# drone-go
|
||||
|
||||
[](http://beta.drone.io/drone/drone-go)
|
||||
|
||||
drone-go is a Go client library for accessing the Drone [API](http://readme.drone.io/devs/api/builds/) and writing [plugins](http://readme.drone.io/plugins/).
|
||||
|
||||
Download the package using `go get`:
|
||||
|
||||
```Go
|
||||
go get "github.com/drone/drone-go/drone"
|
||||
go get "github.com/drone/drone-go/plugin"
|
||||
```
|
||||
|
||||
Import the package:
|
||||
|
||||
```Go
|
||||
import "github.com/drone/drone-go/drone"
|
||||
```
|
||||
|
||||
Create the client:
|
||||
|
||||
```Go
|
||||
const (
|
||||
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
|
||||
host = "http://drone.company.com"
|
||||
)
|
||||
|
||||
client := drone.NewClientToken(host, token)
|
||||
```
|
||||
|
||||
Get the current user:
|
||||
|
||||
```Go
|
||||
user, err := client.Self()
|
||||
fmt.Println(user)
|
||||
```
|
||||
|
||||
Get the repository list:
|
||||
|
||||
```Go
|
||||
repos, err := client.RepoList()
|
||||
fmt.Println(repos)
|
||||
```
|
||||
|
||||
Get the named repository:
|
||||
|
||||
```Go
|
||||
repo, err := client.Repo("drone", "drone-go")
|
||||
fmt.Println(repo)
|
||||
```
|
2
vendor/github.com/drone/drone-go/drone/client.go
generated
vendored
2
vendor/github.com/drone/drone-go/drone/client.go
generated
vendored
@ -58,7 +58,7 @@ func NewClientTokenTLS(uri, token string, c *tls.Config) Client {
|
||||
config := new(oauth2.Config)
|
||||
auther := config.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token})
|
||||
if c != nil {
|
||||
auther.Transport = &http.Transport{TLSClientConfig: c}
|
||||
auther.Transport.(*oauth2.Transport).Base = &http.Transport{TLSClientConfig: c}
|
||||
}
|
||||
return &client{auther, uri}
|
||||
}
|
||||
|
435
vendor/github.com/drone/drone-go/drone/mocks/client.go
generated
vendored
435
vendor/github.com/drone/drone-go/drone/mocks/client.go
generated
vendored
@ -1,435 +0,0 @@
|
||||
package mocks
|
||||
|
||||
import "github.com/drone/drone-go/drone"
|
||||
import "github.com/stretchr/testify/mock"
|
||||
|
||||
import "io"
|
||||
|
||||
type Client struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (_m *Client) Self() (*drone.User, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 *drone.User
|
||||
if rf, ok := ret.Get(0).(func() *drone.User); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.User)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) User(_a0 string) (*drone.User, error) {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 *drone.User
|
||||
if rf, ok := ret.Get(0).(func(string) *drone.User); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.User)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(_a0)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) UserList() ([]*drone.User, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 []*drone.User
|
||||
if rf, ok := ret.Get(0).(func() []*drone.User); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*drone.User)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) UserPost(_a0 *drone.User) (*drone.User, error) {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 *drone.User
|
||||
if rf, ok := ret.Get(0).(func(*drone.User) *drone.User); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.User)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*drone.User) error); ok {
|
||||
r1 = rf(_a0)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) UserPatch(_a0 *drone.User) (*drone.User, error) {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 *drone.User
|
||||
if rf, ok := ret.Get(0).(func(*drone.User) *drone.User); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.User)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*drone.User) error); ok {
|
||||
r1 = rf(_a0)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) UserDel(_a0 string) error {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
func (_m *Client) UserFeed() ([]*drone.Activity, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 []*drone.Activity
|
||||
if rf, ok := ret.Get(0).(func() []*drone.Activity); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*drone.Activity)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) Repo(_a0 string, _a1 string) (*drone.Repo, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
var r0 *drone.Repo
|
||||
if rf, ok := ret.Get(0).(func(string, string) *drone.Repo); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.Repo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) RepoList() ([]*drone.Repo, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 []*drone.Repo
|
||||
if rf, ok := ret.Get(0).(func() []*drone.Repo); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*drone.Repo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) RepoPost(_a0 string, _a1 string) (*drone.Repo, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
var r0 *drone.Repo
|
||||
if rf, ok := ret.Get(0).(func(string, string) *drone.Repo); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.Repo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) RepoPatch(_a0 *drone.Repo) (*drone.Repo, error) {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 *drone.Repo
|
||||
if rf, ok := ret.Get(0).(func(*drone.Repo) *drone.Repo); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.Repo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*drone.Repo) error); ok {
|
||||
r1 = rf(_a0)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) RepoDel(_a0 string, _a1 string) error {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
func (_m *Client) RepoKey(_a0 string, _a1 string) (*drone.Key, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
var r0 *drone.Key
|
||||
if rf, ok := ret.Get(0).(func(string, string) *drone.Key); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.Key)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) Build(_a0 string, _a1 string, _a2 int) (*drone.Build, error) {
|
||||
ret := _m.Called(_a0, _a1, _a2)
|
||||
|
||||
var r0 *drone.Build
|
||||
if rf, ok := ret.Get(0).(func(string, string, int) *drone.Build); ok {
|
||||
r0 = rf(_a0, _a1, _a2)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.Build)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string, int) error); ok {
|
||||
r1 = rf(_a0, _a1, _a2)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) BuildList(_a0 string, _a1 string) ([]*drone.Build, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
var r0 []*drone.Build
|
||||
if rf, ok := ret.Get(0).(func(string, string) []*drone.Build); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*drone.Build)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) BuildStart(_a0 string, _a1 string, _a2 int) (*drone.Build, error) {
|
||||
ret := _m.Called(_a0, _a1, _a2)
|
||||
|
||||
var r0 *drone.Build
|
||||
if rf, ok := ret.Get(0).(func(string, string, int) *drone.Build); ok {
|
||||
r0 = rf(_a0, _a1, _a2)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.Build)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string, int) error); ok {
|
||||
r1 = rf(_a0, _a1, _a2)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) BuildStop(_a0 string, _a1 string, _a2 int, _a3 int) error {
|
||||
ret := _m.Called(_a0, _a1, _a2, _a3)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, int, int) error); ok {
|
||||
r0 = rf(_a0, _a1, _a2, _a3)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
func (_m *Client) BuildLogs(_a0 string, _a1 string, _a2 int, _a3 int) (io.ReadCloser, error) {
|
||||
ret := _m.Called(_a0, _a1, _a2, _a3)
|
||||
|
||||
var r0 io.ReadCloser
|
||||
if rf, ok := ret.Get(0).(func(string, string, int, int) io.ReadCloser); ok {
|
||||
r0 = rf(_a0, _a1, _a2, _a3)
|
||||
} else {
|
||||
r0 = ret.Get(0).(io.ReadCloser)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string, int, int) error); ok {
|
||||
r1 = rf(_a0, _a1, _a2, _a3)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) Node(_a0 int64) (*drone.Node, error) {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 *drone.Node
|
||||
if rf, ok := ret.Get(0).(func(int64) *drone.Node); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.Node)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(int64) error); ok {
|
||||
r1 = rf(_a0)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) NodeList() ([]*drone.Node, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 []*drone.Node
|
||||
if rf, ok := ret.Get(0).(func() []*drone.Node); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*drone.Node)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) NodePost(_a0 *drone.Node) (*drone.Node, error) {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 *drone.Node
|
||||
if rf, ok := ret.Get(0).(func(*drone.Node) *drone.Node); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*drone.Node)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*drone.Node) error); ok {
|
||||
r1 = rf(_a0)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
func (_m *Client) NodeDel(_a0 int64) error {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(int64) error); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
64
vendor/github.com/drone/drone-go/drone/netrc_test.go
generated
vendored
64
vendor/github.com/drone/drone-go/drone/netrc_test.go
generated
vendored
@ -1,64 +0,0 @@
|
||||
package drone
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNetrcMarshaling(t *testing.T) {
|
||||
var tests = []struct {
|
||||
num int
|
||||
input string
|
||||
output string
|
||||
}{
|
||||
{
|
||||
1,
|
||||
`{"machine": "Apple 2", "login": "MeMyselfAndI", "password": "pass123"}`,
|
||||
`{"machine":"Apple 2","login":"MeMyselfAndI","password":"pass123","user":"pass123"}`,
|
||||
},
|
||||
{
|
||||
2,
|
||||
`{"machine": "Apple 2", "login": "MeMyselfAndI", "user": "pass123"}`,
|
||||
`{"machine":"Apple 2","login":"MeMyselfAndI","password":"pass123","user":"pass123"}`,
|
||||
},
|
||||
{
|
||||
3,
|
||||
`{"machine": "Apple 2", "login": "MeMyselfAndI"}`,
|
||||
`{"machine":"Apple 2","login":"MeMyselfAndI","password":"","user":""}`,
|
||||
},
|
||||
{
|
||||
4,
|
||||
`{"machine": "Apple 2", "password": "pass123"}`,
|
||||
`{"machine":"Apple 2","login":"","password":"pass123","user":"pass123"}`,
|
||||
},
|
||||
{
|
||||
5,
|
||||
`{"machine": "Apple 2", "user": "pass123"}`,
|
||||
`{"machine":"Apple 2","login":"","password":"pass123","user":"pass123"}`,
|
||||
},
|
||||
{
|
||||
6,
|
||||
`{ "login": "MeMyselfAndI", "password": "pass123"}`,
|
||||
`{"machine":"","login":"MeMyselfAndI","password":"pass123","user":"pass123"}`,
|
||||
},
|
||||
{
|
||||
7,
|
||||
`{ "login": "MeMyselfAndI", "user": "pass123"}`,
|
||||
`{"machine":"","login":"MeMyselfAndI","password":"pass123","user":"pass123"}`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
var netrc = Netrc{}
|
||||
if err := json.Unmarshal([]byte(test.input), &netrc); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bytes, err := json.Marshal(netrc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if string(bytes) != test.output {
|
||||
t.Errorf("test %d expected %q got %q", test.num, test.output, string(bytes))
|
||||
}
|
||||
}
|
||||
}
|
134
vendor/github.com/drone/drone-go/plugin/plugin.go
generated
vendored
134
vendor/github.com/drone/drone-go/plugin/plugin.go
generated
vendored
@ -1,134 +0,0 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Standard Input
|
||||
var Stdin *ParamSet
|
||||
|
||||
func init() {
|
||||
// defaults to stdin
|
||||
Stdin = NewParamSet(os.Stdin)
|
||||
|
||||
// check for params after the double dash
|
||||
// in the command string
|
||||
for i, argv := range os.Args {
|
||||
if argv == "--" {
|
||||
arg := os.Args[i+1]
|
||||
buf := bytes.NewBufferString(arg)
|
||||
Stdin = NewParamSet(buf)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this init function is deprecated, but I'm keeping it
|
||||
// around just in case it proves useful in the future.
|
||||
func deprecated_init() {
|
||||
// if piping from stdin we can just exit
|
||||
// and use the default Stdin value
|
||||
stat, _ := os.Stdin.Stat()
|
||||
if (stat.Mode() & os.ModeCharDevice) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// check for params after the double dash
|
||||
// in the command string
|
||||
for i, argv := range os.Args {
|
||||
if argv == "--" {
|
||||
arg := os.Args[i+1]
|
||||
buf := bytes.NewBufferString(arg)
|
||||
Stdin = NewParamSet(buf)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// else use the first variable in the list
|
||||
if len(os.Args) > 1 {
|
||||
buf := bytes.NewBufferString(os.Args[1])
|
||||
Stdin = NewParamSet(buf)
|
||||
}
|
||||
}
|
||||
|
||||
// ParamSet describes a parameter set.
|
||||
type ParamSet struct {
|
||||
reader io.Reader
|
||||
params map[string]interface{}
|
||||
}
|
||||
|
||||
// NewParamSet takes a io.Reader and returns a ParamSet.
|
||||
func NewParamSet(reader io.Reader) *ParamSet {
|
||||
var p = new(ParamSet)
|
||||
p.reader = reader
|
||||
p.params = map[string]interface{}{}
|
||||
return p
|
||||
}
|
||||
|
||||
// Param defines a parameter with the specified name.
|
||||
func (p ParamSet) Param(name string, value interface{}) {
|
||||
p.params[name] = value
|
||||
}
|
||||
|
||||
// Parse parses parameter definitions from the map.
|
||||
func (p ParamSet) Parse() error {
|
||||
raw := map[string]json.RawMessage{}
|
||||
err := json.NewDecoder(p.reader).Decode(&raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for key, val := range p.params {
|
||||
data, ok := raw[key]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
err := json.Unmarshal(data, val)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to unarmshal %s. %s", key, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unmarshal parses the JSON payload from the command
|
||||
// arguments and unmarshal into a value pointed to by v.
|
||||
func (p ParamSet) Unmarshal(v interface{}) error {
|
||||
return json.NewDecoder(p.reader).Decode(v)
|
||||
}
|
||||
|
||||
// Param defines a parameter with the specified name.
|
||||
func Param(name string, value interface{}) {
|
||||
Stdin.Param(name, value)
|
||||
}
|
||||
|
||||
// Parse parses parameter definitions from the map.
|
||||
func Parse() error {
|
||||
return Stdin.Parse()
|
||||
}
|
||||
|
||||
// Unmarshal parses the JSON payload from the command
|
||||
// arguments and unmarshal into a value pointed to by v.
|
||||
func Unmarshal(v interface{}) error {
|
||||
return Stdin.Unmarshal(v)
|
||||
}
|
||||
|
||||
// MustUnmarshal parses the JSON payload from the command
|
||||
// arguments and unmarshal into a value pointed to by v.
|
||||
func MustUnmarshal(v interface{}) error {
|
||||
return Stdin.Unmarshal(v)
|
||||
}
|
||||
|
||||
// MustParse parses parameter definitions from the map
|
||||
// and panics if there is a parsing error.
|
||||
func MustParse() {
|
||||
err := Parse()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
1
vendor/github.com/drone/drone-go/plugin/plugin_test.go
generated
vendored
1
vendor/github.com/drone/drone-go/plugin/plugin_test.go
generated
vendored
@ -1 +0,0 @@
|
||||
package plugin
|
163
vendor/github.com/drone/drone-go/template/template.go
generated
vendored
163
vendor/github.com/drone/drone-go/template/template.go
generated
vendored
@ -1,163 +0,0 @@
|
||||
package template
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/aymerick/raymond"
|
||||
"github.com/drone/drone-go/drone"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func init() {
|
||||
raymond.RegisterHelpers(funcs)
|
||||
}
|
||||
|
||||
// Render parses and executes a template, returning the results
|
||||
// in string format.
|
||||
func Render(template string, playload *drone.Payload) (string, error) {
|
||||
if strings.HasPrefix(template, "http") {
|
||||
resp, err := http.Get(template)
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to fetch remote template: %s", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to read remote template: %s", err)
|
||||
}
|
||||
|
||||
template = string(content)
|
||||
}
|
||||
|
||||
return raymond.Render(template, normalize(playload))
|
||||
}
|
||||
|
||||
// RenderTrim parses and executes a template, returning the results
|
||||
// in string format. The result is trimmed to remove left and right
|
||||
// padding and newlines that may be added unintentially in the
|
||||
// template markup.
|
||||
func RenderTrim(template string, playload *drone.Payload) (string, error) {
|
||||
out, err := Render(template, playload)
|
||||
return strings.Trim(out, " \n"), err
|
||||
}
|
||||
|
||||
// Write parses and executes a template, writing the results to
|
||||
// writer w.
|
||||
func Write(w io.Writer, template string, playload *drone.Payload) error {
|
||||
out, err := Render(template, playload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.WriteString(w, out)
|
||||
return err
|
||||
}
|
||||
|
||||
var funcs = map[string]interface{}{
|
||||
"uppercasefirst": uppercaseFirst,
|
||||
"uppercase": strings.ToUpper,
|
||||
"lowercase": strings.ToLower,
|
||||
"duration": toDuration,
|
||||
"datetime": toDatetime,
|
||||
"success": isSuccess,
|
||||
"failure": isFailure,
|
||||
"truncate": truncate,
|
||||
"urlencode": urlencode,
|
||||
}
|
||||
|
||||
// truncate is a helper function that truncates a string by a particular length.
|
||||
func truncate(s string, len int) string {
|
||||
if utf8.RuneCountInString(s) <= len {
|
||||
return s
|
||||
}
|
||||
runes := []rune(s)
|
||||
return string(runes[:len])
|
||||
|
||||
}
|
||||
|
||||
// uppercaseFirst is a helper function that takes a string and capitalizes
|
||||
// the first letter.
|
||||
func uppercaseFirst(s string) string {
|
||||
a := []rune(s)
|
||||
a[0] = unicode.ToUpper(a[0])
|
||||
s = string(a)
|
||||
return s
|
||||
}
|
||||
|
||||
// toDuration is a helper function that calculates a duration for a start and
|
||||
// and end time, and returns the duration in string format.
|
||||
func toDuration(started, finished float64) string {
|
||||
return fmt.Sprintln(time.Duration(finished-started) * time.Second)
|
||||
}
|
||||
|
||||
// toDatetime is a helper function that converts a unix timestamp to a string.
|
||||
func toDatetime(timestamp float64, layout, zone string) string {
|
||||
if len(zone) == 0 {
|
||||
return time.Unix(int64(timestamp), 0).Format(layout)
|
||||
}
|
||||
loc, err := time.LoadLocation(zone)
|
||||
if err != nil {
|
||||
fmt.Printf("Error parsing timezone, defaulting to local timezone. %s\n", err)
|
||||
return time.Unix(int64(timestamp), 0).Local().Format(layout)
|
||||
}
|
||||
return time.Unix(int64(timestamp), 0).In(loc).Format(layout)
|
||||
}
|
||||
|
||||
// isSuccess is a helper function that executes a block iff the status
|
||||
// is success, else it executes the else block.
|
||||
func isSuccess(conditional bool, options *raymond.Options) string {
|
||||
if !conditional {
|
||||
return options.Inverse()
|
||||
}
|
||||
|
||||
switch options.ParamStr(0) {
|
||||
case "success":
|
||||
return options.Fn()
|
||||
default:
|
||||
return options.Inverse()
|
||||
}
|
||||
}
|
||||
|
||||
// isFailure is a helper function that executes a block iff the status
|
||||
// is a form of failure, else it executes the else block.
|
||||
func isFailure(conditional bool, options *raymond.Options) string {
|
||||
if !conditional {
|
||||
return options.Inverse()
|
||||
}
|
||||
|
||||
switch options.ParamStr(0) {
|
||||
case "failure", "error", "killed":
|
||||
return options.Fn()
|
||||
default:
|
||||
return options.Inverse()
|
||||
}
|
||||
}
|
||||
|
||||
// normalize takes a Go representation of the variable, marshals
|
||||
// to json and then unmarshals to a map[string]interfacce{}. This
|
||||
// is important because it let's us use the JSON variable names
|
||||
// in our template
|
||||
func normalize(in interface{}) map[string]interface{} {
|
||||
data, _ := json.Marshal(in) // we own the types, so this should never fail
|
||||
|
||||
out := map[string]interface{}{}
|
||||
json.Unmarshal(data, &out)
|
||||
return out
|
||||
}
|
||||
|
||||
// urlencode is a helper function that encode a block
|
||||
// to url safe string.
|
||||
func urlencode(options *raymond.Options) string {
|
||||
return url.QueryEscape(options.Fn())
|
||||
}
|
104
vendor/github.com/drone/drone-go/template/template_test.go
generated
vendored
104
vendor/github.com/drone/drone-go/template/template_test.go
generated
vendored
@ -1,104 +0,0 @@
|
||||
package template
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone-go/drone"
|
||||
)
|
||||
|
||||
var tests = []struct {
|
||||
Payload *drone.Payload
|
||||
Input string
|
||||
Output string
|
||||
}{
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{
|
||||
Commit: "0a266f42a9aef9db97a005ab46f6c53890339a9c"},
|
||||
},
|
||||
"{{ truncate build.commit 8 }}",
|
||||
"0a266f42",
|
||||
},
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Number: 1}},
|
||||
"build #{{build.number}}",
|
||||
"build #1",
|
||||
},
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Status: drone.StatusSuccess}},
|
||||
"{{uppercase build.status}}",
|
||||
"SUCCESS",
|
||||
},
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Author: "Octocat"}},
|
||||
"{{lowercase build.author}}",
|
||||
"octocat",
|
||||
},
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Status: drone.StatusSuccess}},
|
||||
"{{uppercasefirst build.status}}",
|
||||
"Success",
|
||||
},
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{
|
||||
Started: 1448127131,
|
||||
Finished: 1448127505},
|
||||
},
|
||||
"{{ duration build.started_at build.finished_at }}",
|
||||
"6m14s",
|
||||
},
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Finished: 1448127505}},
|
||||
`finished at {{ datetime build.finished_at "3:04PM" "UTC" }}`,
|
||||
"finished at 5:38PM",
|
||||
},
|
||||
// verify the success if / else block works
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Status: drone.StatusSuccess}},
|
||||
"{{#success build.status}}SUCCESS{{/success}}",
|
||||
"SUCCESS",
|
||||
},
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Status: drone.StatusFailure}},
|
||||
"{{#success build.status}}SUCCESS{{/success}}",
|
||||
"",
|
||||
},
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Status: drone.StatusFailure}},
|
||||
"{{#success build.status}}SUCCESS{{else}}NOT SUCCESS{{/success}}",
|
||||
"NOT SUCCESS",
|
||||
},
|
||||
// verify the failure if / else block works
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Status: drone.StatusFailure}},
|
||||
"{{#failure build.status}}FAILURE{{/failure}}",
|
||||
"FAILURE",
|
||||
},
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Status: drone.StatusSuccess}},
|
||||
"{{#failure build.status}}FAILURE{{/failure}}",
|
||||
"",
|
||||
},
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Status: drone.StatusSuccess}},
|
||||
"{{#failure build.status}}FAILURE{{else}}NOT FAILURE{{/failure}}",
|
||||
"NOT FAILURE",
|
||||
},
|
||||
{
|
||||
&drone.Payload{Build: &drone.Build{Author: "url&unsafe=author!"}},
|
||||
"{{#urlencode}}google https://www.google.co.jp/ {{{build.author}}}{{/urlencode}}",
|
||||
"google+https%3A%2F%2Fwww.google.co.jp%2F+url%26unsafe%3Dauthor%21",
|
||||
},
|
||||
}
|
||||
|
||||
func TestTemplate(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := RenderTrim(test.Input, test.Payload)
|
||||
if err != nil {
|
||||
t.Errorf("Failed rendering template %q, got error %s.", test.Input, err)
|
||||
}
|
||||
if got != test.Output {
|
||||
t.Errorf("Wanted rendered template %q, got %q", test.Output, got)
|
||||
}
|
||||
}
|
||||
}
|
51
vendor/github.com/drone/drone/yaml/matrix/matrix_test.go
generated
vendored
51
vendor/github.com/drone/drone/yaml/matrix/matrix_test.go
generated
vendored
@ -1,51 +0,0 @@
|
||||
package matrix
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func Test_Matrix(t *testing.T) {
|
||||
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Calculate matrix", func() {
|
||||
|
||||
axis, _ := Parse(fakeMatrix)
|
||||
|
||||
g.It("Should calculate permutations", func() {
|
||||
g.Assert(len(axis)).Equal(24)
|
||||
})
|
||||
|
||||
g.It("Should not duplicate permutations", func() {
|
||||
set := map[string]bool{}
|
||||
for _, perm := range axis {
|
||||
set[perm.String()] = true
|
||||
}
|
||||
g.Assert(len(set)).Equal(24)
|
||||
})
|
||||
|
||||
g.It("Should return nil if no matrix", func() {
|
||||
axis, err := Parse("")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(axis == nil).IsTrue()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
var fakeMatrix = `
|
||||
matrix:
|
||||
go_version:
|
||||
- go1
|
||||
- go1.2
|
||||
python_version:
|
||||
- 3.2
|
||||
- 3.3
|
||||
django_version:
|
||||
- 1.7
|
||||
- 1.7.1
|
||||
- 1.7.2
|
||||
redis_version:
|
||||
- 2.6
|
||||
- 2.8
|
||||
`
|
28
vendor/github.com/fatih/color/color.go
generated
vendored
28
vendor/github.com/fatih/color/color.go
generated
vendored
@ -6,8 +6,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
// NoColor defines if the output is colorized or not. It's dynamically set to
|
||||
@ -53,6 +53,18 @@ const (
|
||||
FgWhite
|
||||
)
|
||||
|
||||
// Foreground Hi-Intensity text colors
|
||||
const (
|
||||
FgHiBlack Attribute = iota + 90
|
||||
FgHiRed
|
||||
FgHiGreen
|
||||
FgHiYellow
|
||||
FgHiBlue
|
||||
FgHiMagenta
|
||||
FgHiCyan
|
||||
FgHiWhite
|
||||
)
|
||||
|
||||
// Background text colors
|
||||
const (
|
||||
BgBlack Attribute = iota + 40
|
||||
@ -65,6 +77,18 @@ const (
|
||||
BgWhite
|
||||
)
|
||||
|
||||
// Background Hi-Intensity text colors
|
||||
const (
|
||||
BgHiBlack Attribute = iota + 100
|
||||
BgHiRed
|
||||
BgHiGreen
|
||||
BgHiYellow
|
||||
BgHiBlue
|
||||
BgHiMagenta
|
||||
BgHiCyan
|
||||
BgHiWhite
|
||||
)
|
||||
|
||||
// New returns a newly created color object.
|
||||
func New(value ...Attribute) *Color {
|
||||
c := &Color{params: make([]Attribute, 0)}
|
||||
@ -123,7 +147,7 @@ func (c *Color) prepend(value Attribute) {
|
||||
|
||||
// Output defines the standard output of the print functions. By default
|
||||
// os.Stdout is used.
|
||||
var Output = ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||
var Output = colorable.NewColorableStdout()
|
||||
|
||||
// Print formats using the default formats for its operands and writes to
|
||||
// standard output. Spaces are added between operands when neither is a
|
||||
|
212
vendor/github.com/fatih/color/color_test.go
generated
vendored
212
vendor/github.com/fatih/color/color_test.go
generated
vendored
@ -1,212 +0,0 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
// Testing colors is kinda different. First we test for given colors and their
|
||||
// escaped formatted results. Next we create some visual tests to be tested.
|
||||
// Each visual test includes the color name to be compared.
|
||||
func TestColor(t *testing.T) {
|
||||
rb := new(bytes.Buffer)
|
||||
Output = rb
|
||||
|
||||
NoColor = false
|
||||
|
||||
testColors := []struct {
|
||||
text string
|
||||
code Attribute
|
||||
}{
|
||||
{text: "black", code: FgBlack},
|
||||
{text: "red", code: FgRed},
|
||||
{text: "green", code: FgGreen},
|
||||
{text: "yellow", code: FgYellow},
|
||||
{text: "blue", code: FgBlue},
|
||||
{text: "magent", code: FgMagenta},
|
||||
{text: "cyan", code: FgCyan},
|
||||
{text: "white", code: FgWhite},
|
||||
}
|
||||
|
||||
for _, c := range testColors {
|
||||
New(c.code).Print(c.text)
|
||||
|
||||
line, _ := rb.ReadString('\n')
|
||||
scannedLine := fmt.Sprintf("%q", line)
|
||||
colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text)
|
||||
escapedForm := fmt.Sprintf("%q", colored)
|
||||
|
||||
fmt.Printf("%s\t: %s\n", c.text, line)
|
||||
|
||||
if scannedLine != escapedForm {
|
||||
t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestColorEquals(t *testing.T) {
|
||||
fgblack1 := New(FgBlack)
|
||||
fgblack2 := New(FgBlack)
|
||||
bgblack := New(BgBlack)
|
||||
fgbgblack := New(FgBlack, BgBlack)
|
||||
fgblackbgred := New(FgBlack, BgRed)
|
||||
fgred := New(FgRed)
|
||||
bgred := New(BgRed)
|
||||
|
||||
if !fgblack1.Equals(fgblack2) {
|
||||
t.Error("Two black colors are not equal")
|
||||
}
|
||||
|
||||
if fgblack1.Equals(bgblack) {
|
||||
t.Error("Fg and bg black colors are equal")
|
||||
}
|
||||
|
||||
if fgblack1.Equals(fgbgblack) {
|
||||
t.Error("Fg black equals fg/bg black color")
|
||||
}
|
||||
|
||||
if fgblack1.Equals(fgred) {
|
||||
t.Error("Fg black equals Fg red")
|
||||
}
|
||||
|
||||
if fgblack1.Equals(bgred) {
|
||||
t.Error("Fg black equals Bg red")
|
||||
}
|
||||
|
||||
if fgblack1.Equals(fgblackbgred) {
|
||||
t.Error("Fg black equals fg black bg red")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoColor(t *testing.T) {
|
||||
rb := new(bytes.Buffer)
|
||||
Output = rb
|
||||
|
||||
testColors := []struct {
|
||||
text string
|
||||
code Attribute
|
||||
}{
|
||||
{text: "black", code: FgBlack},
|
||||
{text: "red", code: FgRed},
|
||||
{text: "green", code: FgGreen},
|
||||
{text: "yellow", code: FgYellow},
|
||||
{text: "blue", code: FgBlue},
|
||||
{text: "magent", code: FgMagenta},
|
||||
{text: "cyan", code: FgCyan},
|
||||
{text: "white", code: FgWhite},
|
||||
}
|
||||
|
||||
for _, c := range testColors {
|
||||
p := New(c.code)
|
||||
p.DisableColor()
|
||||
p.Print(c.text)
|
||||
|
||||
line, _ := rb.ReadString('\n')
|
||||
if line != c.text {
|
||||
t.Errorf("Expecting %s, got '%s'\n", c.text, line)
|
||||
}
|
||||
}
|
||||
|
||||
// global check
|
||||
NoColor = true
|
||||
defer func() {
|
||||
NoColor = false
|
||||
}()
|
||||
for _, c := range testColors {
|
||||
p := New(c.code)
|
||||
p.Print(c.text)
|
||||
|
||||
line, _ := rb.ReadString('\n')
|
||||
if line != c.text {
|
||||
t.Errorf("Expecting %s, got '%s'\n", c.text, line)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestColorVisual(t *testing.T) {
|
||||
// First Visual Test
|
||||
fmt.Println("")
|
||||
Output = ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||
|
||||
New(FgRed).Printf("red\t")
|
||||
New(BgRed).Print(" ")
|
||||
New(FgRed, Bold).Println(" red")
|
||||
|
||||
New(FgGreen).Printf("green\t")
|
||||
New(BgGreen).Print(" ")
|
||||
New(FgGreen, Bold).Println(" green")
|
||||
|
||||
New(FgYellow).Printf("yellow\t")
|
||||
New(BgYellow).Print(" ")
|
||||
New(FgYellow, Bold).Println(" yellow")
|
||||
|
||||
New(FgBlue).Printf("blue\t")
|
||||
New(BgBlue).Print(" ")
|
||||
New(FgBlue, Bold).Println(" blue")
|
||||
|
||||
New(FgMagenta).Printf("magenta\t")
|
||||
New(BgMagenta).Print(" ")
|
||||
New(FgMagenta, Bold).Println(" magenta")
|
||||
|
||||
New(FgCyan).Printf("cyan\t")
|
||||
New(BgCyan).Print(" ")
|
||||
New(FgCyan, Bold).Println(" cyan")
|
||||
|
||||
New(FgWhite).Printf("white\t")
|
||||
New(BgWhite).Print(" ")
|
||||
New(FgWhite, Bold).Println(" white")
|
||||
fmt.Println("")
|
||||
|
||||
// Second Visual test
|
||||
Black("black")
|
||||
Red("red")
|
||||
Green("green")
|
||||
Yellow("yellow")
|
||||
Blue("blue")
|
||||
Magenta("magenta")
|
||||
Cyan("cyan")
|
||||
White("white")
|
||||
|
||||
// Third visual test
|
||||
fmt.Println()
|
||||
Set(FgBlue)
|
||||
fmt.Println("is this blue?")
|
||||
Unset()
|
||||
|
||||
Set(FgMagenta)
|
||||
fmt.Println("and this magenta?")
|
||||
Unset()
|
||||
|
||||
// Fourth Visual test
|
||||
fmt.Println()
|
||||
blue := New(FgBlue).PrintlnFunc()
|
||||
blue("blue text with custom print func")
|
||||
|
||||
red := New(FgRed).PrintfFunc()
|
||||
red("red text with a printf func: %d\n", 123)
|
||||
|
||||
put := New(FgYellow).SprintFunc()
|
||||
warn := New(FgRed).SprintFunc()
|
||||
|
||||
fmt.Fprintf(Output, "this is a %s and this is %s.\n", put("warning"), warn("error"))
|
||||
|
||||
info := New(FgWhite, BgGreen).SprintFunc()
|
||||
fmt.Fprintf(Output, "this %s rocks!\n", info("package"))
|
||||
|
||||
// Fifth Visual Test
|
||||
fmt.Println()
|
||||
|
||||
fmt.Fprintln(Output, BlackString("black"))
|
||||
fmt.Fprintln(Output, RedString("red"))
|
||||
fmt.Fprintln(Output, GreenString("green"))
|
||||
fmt.Fprintln(Output, YellowString("yellow"))
|
||||
fmt.Fprintln(Output, BlueString("blue"))
|
||||
fmt.Fprintln(Output, MagentaString("magenta"))
|
||||
fmt.Fprintln(Output, CyanString("cyan"))
|
||||
fmt.Fprintln(Output, WhiteString("white"))
|
||||
}
|
24
vendor/github.com/jackspirou/syscerts/.gitignore
generated
vendored
24
vendor/github.com/jackspirou/syscerts/.gitignore
generated
vendored
@ -1,24 +0,0 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
69
vendor/github.com/jackspirou/syscerts/root_darwin_test.go
generated
vendored
69
vendor/github.com/jackspirou/syscerts/root_darwin_test.go
generated
vendored
@ -1,69 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package syscerts
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSystemRoots(t *testing.T) {
|
||||
switch runtime.GOARCH {
|
||||
case "arm", "arm64":
|
||||
t.Skipf("skipping on %s/%s, no system root", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
|
||||
sysRoots := SystemRootsPool() // actual system roots
|
||||
execRoots, err := execSecurityRoots() // non-cgo roots
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read system roots: %v", err)
|
||||
}
|
||||
|
||||
for _, tt := range []*x509.CertPool{sysRoots, execRoots} {
|
||||
if tt == nil {
|
||||
t.Fatal("no system roots")
|
||||
}
|
||||
|
||||
/*
|
||||
// On Mavericks, there are 212 bundled certs; require only
|
||||
// 150 here, since this is just a sanity check, and the
|
||||
// exact number will vary over time.
|
||||
if want, have := 150, len(tt.certs); have < want {
|
||||
t.Fatalf("want at least %d system roots, have %d", want, have)
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Check that the two cert pools are roughly the same;
|
||||
// |A∩B| > max(|A|, |B|) / 2 should be a reasonably robust check.
|
||||
|
||||
/*
|
||||
isect := make(map[string]bool, len(sysRoots.certs))
|
||||
for _, c := range sysRoots.certs {
|
||||
isect[string(c.Raw)] = true
|
||||
}
|
||||
|
||||
have := 0
|
||||
for _, c := range execRoots.certs {
|
||||
if isect[string(c.Raw)] {
|
||||
have++
|
||||
}
|
||||
}
|
||||
|
||||
var want int
|
||||
if nsys, nexec := len(sysRoots.certs), len(execRoots.certs); nsys > nexec {
|
||||
want = nsys / 2
|
||||
} else {
|
||||
want = nexec / 2
|
||||
}
|
||||
|
||||
|
||||
if have < want {
|
||||
t.Errorf("insufficient overlap between cgo and non-cgo roots; want at least %d, have %d", want, have)
|
||||
}
|
||||
*/
|
||||
}
|
43
vendor/github.com/mattn/go-colorable/README.md
generated
vendored
Normal file
43
vendor/github.com/mattn/go-colorable/README.md
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
# go-colorable
|
||||
|
||||
Colorable writer for windows.
|
||||
|
||||
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.)
|
||||
This package is possible to handle escape sequence for ansi color on windows.
|
||||
|
||||
## Too Bad!
|
||||
|
||||

|
||||
|
||||
|
||||
## So Good!
|
||||
|
||||

|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true})
|
||||
logrus.SetOutput(colorable.NewColorableStdout())
|
||||
|
||||
logrus.Info("succeeded")
|
||||
logrus.Warn("not correct")
|
||||
logrus.Error("something error")
|
||||
logrus.Fatal("panic")
|
||||
```
|
||||
|
||||
You can compile above code on non-windows OSs.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ go get github.com/mattn/go-colorable
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
||||
|
||||
# Author
|
||||
|
||||
Yasuhiro Matsumoto (a.k.a mattn)
|
16
vendor/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
Normal file
16
vendor/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// +build !windows
|
||||
|
||||
package colorable
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func NewColorableStdout() io.Writer {
|
||||
return os.Stdout
|
||||
}
|
||||
|
||||
func NewColorableStderr() io.Writer {
|
||||
return os.Stderr
|
||||
}
|
665
vendor/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
Normal file
665
vendor/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
Normal file
@ -0,0 +1,665 @@
|
||||
package colorable
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
const (
|
||||
foregroundBlue = 0x1
|
||||
foregroundGreen = 0x2
|
||||
foregroundRed = 0x4
|
||||
foregroundIntensity = 0x8
|
||||
foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity)
|
||||
backgroundBlue = 0x10
|
||||
backgroundGreen = 0x20
|
||||
backgroundRed = 0x40
|
||||
backgroundIntensity = 0x80
|
||||
backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)
|
||||
)
|
||||
|
||||
type wchar uint16
|
||||
type short int16
|
||||
type dword uint32
|
||||
type word uint16
|
||||
|
||||
type coord struct {
|
||||
x short
|
||||
y short
|
||||
}
|
||||
|
||||
type smallRect struct {
|
||||
left short
|
||||
top short
|
||||
right short
|
||||
bottom short
|
||||
}
|
||||
|
||||
type consoleScreenBufferInfo struct {
|
||||
size coord
|
||||
cursorPosition coord
|
||||
attributes word
|
||||
window smallRect
|
||||
maximumWindowSize coord
|
||||
}
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||
procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
|
||||
)
|
||||
|
||||
type Writer struct {
|
||||
out io.Writer
|
||||
handle syscall.Handle
|
||||
lastbuf bytes.Buffer
|
||||
oldattr word
|
||||
}
|
||||
|
||||
func NewColorableStdout() io.Writer {
|
||||
var csbi consoleScreenBufferInfo
|
||||
out := os.Stdout
|
||||
if !isatty.IsTerminal(out.Fd()) {
|
||||
return out
|
||||
}
|
||||
handle := syscall.Handle(out.Fd())
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
return &Writer{out: out, handle: handle, oldattr: csbi.attributes}
|
||||
}
|
||||
|
||||
func NewColorableStderr() io.Writer {
|
||||
var csbi consoleScreenBufferInfo
|
||||
out := os.Stderr
|
||||
if !isatty.IsTerminal(out.Fd()) {
|
||||
return out
|
||||
}
|
||||
handle := syscall.Handle(out.Fd())
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
return &Writer{out: out, handle: handle, oldattr: csbi.attributes}
|
||||
}
|
||||
|
||||
var color256 = map[int]int{
|
||||
0: 0x000000,
|
||||
1: 0x800000,
|
||||
2: 0x008000,
|
||||
3: 0x808000,
|
||||
4: 0x000080,
|
||||
5: 0x800080,
|
||||
6: 0x008080,
|
||||
7: 0xc0c0c0,
|
||||
8: 0x808080,
|
||||
9: 0xff0000,
|
||||
10: 0x00ff00,
|
||||
11: 0xffff00,
|
||||
12: 0x0000ff,
|
||||
13: 0xff00ff,
|
||||
14: 0x00ffff,
|
||||
15: 0xffffff,
|
||||
16: 0x000000,
|
||||
17: 0x00005f,
|
||||
18: 0x000087,
|
||||
19: 0x0000af,
|
||||
20: 0x0000d7,
|
||||
21: 0x0000ff,
|
||||
22: 0x005f00,
|
||||
23: 0x005f5f,
|
||||
24: 0x005f87,
|
||||
25: 0x005faf,
|
||||
26: 0x005fd7,
|
||||
27: 0x005fff,
|
||||
28: 0x008700,
|
||||
29: 0x00875f,
|
||||
30: 0x008787,
|
||||
31: 0x0087af,
|
||||
32: 0x0087d7,
|
||||
33: 0x0087ff,
|
||||
34: 0x00af00,
|
||||
35: 0x00af5f,
|
||||
36: 0x00af87,
|
||||
37: 0x00afaf,
|
||||
38: 0x00afd7,
|
||||
39: 0x00afff,
|
||||
40: 0x00d700,
|
||||
41: 0x00d75f,
|
||||
42: 0x00d787,
|
||||
43: 0x00d7af,
|
||||
44: 0x00d7d7,
|
||||
45: 0x00d7ff,
|
||||
46: 0x00ff00,
|
||||
47: 0x00ff5f,
|
||||
48: 0x00ff87,
|
||||
49: 0x00ffaf,
|
||||
50: 0x00ffd7,
|
||||
51: 0x00ffff,
|
||||
52: 0x5f0000,
|
||||
53: 0x5f005f,
|
||||
54: 0x5f0087,
|
||||
55: 0x5f00af,
|
||||
56: 0x5f00d7,
|
||||
57: 0x5f00ff,
|
||||
58: 0x5f5f00,
|
||||
59: 0x5f5f5f,
|
||||
60: 0x5f5f87,
|
||||
61: 0x5f5faf,
|
||||
62: 0x5f5fd7,
|
||||
63: 0x5f5fff,
|
||||
64: 0x5f8700,
|
||||
65: 0x5f875f,
|
||||
66: 0x5f8787,
|
||||
67: 0x5f87af,
|
||||
68: 0x5f87d7,
|
||||
69: 0x5f87ff,
|
||||
70: 0x5faf00,
|
||||
71: 0x5faf5f,
|
||||
72: 0x5faf87,
|
||||
73: 0x5fafaf,
|
||||
74: 0x5fafd7,
|
||||
75: 0x5fafff,
|
||||
76: 0x5fd700,
|
||||
77: 0x5fd75f,
|
||||
78: 0x5fd787,
|
||||
79: 0x5fd7af,
|
||||
80: 0x5fd7d7,
|
||||
81: 0x5fd7ff,
|
||||
82: 0x5fff00,
|
||||
83: 0x5fff5f,
|
||||
84: 0x5fff87,
|
||||
85: 0x5fffaf,
|
||||
86: 0x5fffd7,
|
||||
87: 0x5fffff,
|
||||
88: 0x870000,
|
||||
89: 0x87005f,
|
||||
90: 0x870087,
|
||||
91: 0x8700af,
|
||||
92: 0x8700d7,
|
||||
93: 0x8700ff,
|
||||
94: 0x875f00,
|
||||
95: 0x875f5f,
|
||||
96: 0x875f87,
|
||||
97: 0x875faf,
|
||||
98: 0x875fd7,
|
||||
99: 0x875fff,
|
||||
100: 0x878700,
|
||||
101: 0x87875f,
|
||||
102: 0x878787,
|
||||
103: 0x8787af,
|
||||
104: 0x8787d7,
|
||||
105: 0x8787ff,
|
||||
106: 0x87af00,
|
||||
107: 0x87af5f,
|
||||
108: 0x87af87,
|
||||
109: 0x87afaf,
|
||||
110: 0x87afd7,
|
||||
111: 0x87afff,
|
||||
112: 0x87d700,
|
||||
113: 0x87d75f,
|
||||
114: 0x87d787,
|
||||
115: 0x87d7af,
|
||||
116: 0x87d7d7,
|
||||
117: 0x87d7ff,
|
||||
118: 0x87ff00,
|
||||
119: 0x87ff5f,
|
||||
120: 0x87ff87,
|
||||
121: 0x87ffaf,
|
||||
122: 0x87ffd7,
|
||||
123: 0x87ffff,
|
||||
124: 0xaf0000,
|
||||
125: 0xaf005f,
|
||||
126: 0xaf0087,
|
||||
127: 0xaf00af,
|
||||
128: 0xaf00d7,
|
||||
129: 0xaf00ff,
|
||||
130: 0xaf5f00,
|
||||
131: 0xaf5f5f,
|
||||
132: 0xaf5f87,
|
||||
133: 0xaf5faf,
|
||||
134: 0xaf5fd7,
|
||||
135: 0xaf5fff,
|
||||
136: 0xaf8700,
|
||||
137: 0xaf875f,
|
||||
138: 0xaf8787,
|
||||
139: 0xaf87af,
|
||||
140: 0xaf87d7,
|
||||
141: 0xaf87ff,
|
||||
142: 0xafaf00,
|
||||
143: 0xafaf5f,
|
||||
144: 0xafaf87,
|
||||
145: 0xafafaf,
|
||||
146: 0xafafd7,
|
||||
147: 0xafafff,
|
||||
148: 0xafd700,
|
||||
149: 0xafd75f,
|
||||
150: 0xafd787,
|
||||
151: 0xafd7af,
|
||||
152: 0xafd7d7,
|
||||
153: 0xafd7ff,
|
||||
154: 0xafff00,
|
||||
155: 0xafff5f,
|
||||
156: 0xafff87,
|
||||
157: 0xafffaf,
|
||||
158: 0xafffd7,
|
||||
159: 0xafffff,
|
||||
160: 0xd70000,
|
||||
161: 0xd7005f,
|
||||
162: 0xd70087,
|
||||
163: 0xd700af,
|
||||
164: 0xd700d7,
|
||||
165: 0xd700ff,
|
||||
166: 0xd75f00,
|
||||
167: 0xd75f5f,
|
||||
168: 0xd75f87,
|
||||
169: 0xd75faf,
|
||||
170: 0xd75fd7,
|
||||
171: 0xd75fff,
|
||||
172: 0xd78700,
|
||||
173: 0xd7875f,
|
||||
174: 0xd78787,
|
||||
175: 0xd787af,
|
||||
176: 0xd787d7,
|
||||
177: 0xd787ff,
|
||||
178: 0xd7af00,
|
||||
179: 0xd7af5f,
|
||||
180: 0xd7af87,
|
||||
181: 0xd7afaf,
|
||||
182: 0xd7afd7,
|
||||
183: 0xd7afff,
|
||||
184: 0xd7d700,
|
||||
185: 0xd7d75f,
|
||||
186: 0xd7d787,
|
||||
187: 0xd7d7af,
|
||||
188: 0xd7d7d7,
|
||||
189: 0xd7d7ff,
|
||||
190: 0xd7ff00,
|
||||
191: 0xd7ff5f,
|
||||
192: 0xd7ff87,
|
||||
193: 0xd7ffaf,
|
||||
194: 0xd7ffd7,
|
||||
195: 0xd7ffff,
|
||||
196: 0xff0000,
|
||||
197: 0xff005f,
|
||||
198: 0xff0087,
|
||||
199: 0xff00af,
|
||||
200: 0xff00d7,
|
||||
201: 0xff00ff,
|
||||
202: 0xff5f00,
|
||||
203: 0xff5f5f,
|
||||
204: 0xff5f87,
|
||||
205: 0xff5faf,
|
||||
206: 0xff5fd7,
|
||||
207: 0xff5fff,
|
||||
208: 0xff8700,
|
||||
209: 0xff875f,
|
||||
210: 0xff8787,
|
||||
211: 0xff87af,
|
||||
212: 0xff87d7,
|
||||
213: 0xff87ff,
|
||||
214: 0xffaf00,
|
||||
215: 0xffaf5f,
|
||||
216: 0xffaf87,
|
||||
217: 0xffafaf,
|
||||
218: 0xffafd7,
|
||||
219: 0xffafff,
|
||||
220: 0xffd700,
|
||||
221: 0xffd75f,
|
||||
222: 0xffd787,
|
||||
223: 0xffd7af,
|
||||
224: 0xffd7d7,
|
||||
225: 0xffd7ff,
|
||||
226: 0xffff00,
|
||||
227: 0xffff5f,
|
||||
228: 0xffff87,
|
||||
229: 0xffffaf,
|
||||
230: 0xffffd7,
|
||||
231: 0xffffff,
|
||||
232: 0x080808,
|
||||
233: 0x121212,
|
||||
234: 0x1c1c1c,
|
||||
235: 0x262626,
|
||||
236: 0x303030,
|
||||
237: 0x3a3a3a,
|
||||
238: 0x444444,
|
||||
239: 0x4e4e4e,
|
||||
240: 0x585858,
|
||||
241: 0x626262,
|
||||
242: 0x6c6c6c,
|
||||
243: 0x767676,
|
||||
244: 0x808080,
|
||||
245: 0x8a8a8a,
|
||||
246: 0x949494,
|
||||
247: 0x9e9e9e,
|
||||
248: 0xa8a8a8,
|
||||
249: 0xb2b2b2,
|
||||
250: 0xbcbcbc,
|
||||
251: 0xc6c6c6,
|
||||
252: 0xd0d0d0,
|
||||
253: 0xdadada,
|
||||
254: 0xe4e4e4,
|
||||
255: 0xeeeeee,
|
||||
}
|
||||
|
||||
func (w *Writer) Write(data []byte) (n int, err error) {
|
||||
var csbi consoleScreenBufferInfo
|
||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
|
||||
er := bytes.NewBuffer(data)
|
||||
loop:
|
||||
for {
|
||||
r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||
if r1 == 0 {
|
||||
break loop
|
||||
}
|
||||
|
||||
c1, _, err := er.ReadRune()
|
||||
if err != nil {
|
||||
break loop
|
||||
}
|
||||
if c1 != 0x1b {
|
||||
fmt.Fprint(w.out, string(c1))
|
||||
continue
|
||||
}
|
||||
c2, _, err := er.ReadRune()
|
||||
if err != nil {
|
||||
w.lastbuf.WriteRune(c1)
|
||||
break loop
|
||||
}
|
||||
if c2 != 0x5b {
|
||||
w.lastbuf.WriteRune(c1)
|
||||
w.lastbuf.WriteRune(c2)
|
||||
continue
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
var m rune
|
||||
for {
|
||||
c, _, err := er.ReadRune()
|
||||
if err != nil {
|
||||
w.lastbuf.WriteRune(c1)
|
||||
w.lastbuf.WriteRune(c2)
|
||||
w.lastbuf.Write(buf.Bytes())
|
||||
break loop
|
||||
}
|
||||
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
|
||||
m = c
|
||||
break
|
||||
}
|
||||
buf.Write([]byte(string(c)))
|
||||
}
|
||||
|
||||
switch m {
|
||||
case 'm':
|
||||
attr := csbi.attributes
|
||||
cs := buf.String()
|
||||
if cs == "" {
|
||||
procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr))
|
||||
continue
|
||||
}
|
||||
token := strings.Split(cs, ";")
|
||||
for i := 0; i < len(token); i += 1 {
|
||||
ns := token[i]
|
||||
if n, err = strconv.Atoi(ns); err == nil {
|
||||
switch {
|
||||
case n == 0 || n == 100:
|
||||
attr = w.oldattr
|
||||
case 1 <= n && n <= 5:
|
||||
attr |= foregroundIntensity
|
||||
case n == 7:
|
||||
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
|
||||
case 22 == n || n == 25 || n == 25:
|
||||
attr |= foregroundIntensity
|
||||
case n == 27:
|
||||
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
|
||||
case 30 <= n && n <= 37:
|
||||
attr = (attr & backgroundMask)
|
||||
if (n-30)&1 != 0 {
|
||||
attr |= foregroundRed
|
||||
}
|
||||
if (n-30)&2 != 0 {
|
||||
attr |= foregroundGreen
|
||||
}
|
||||
if (n-30)&4 != 0 {
|
||||
attr |= foregroundBlue
|
||||
}
|
||||
case n == 38: // set foreground color.
|
||||
if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") {
|
||||
if n256, err := strconv.Atoi(token[i+2]); err == nil {
|
||||
if n256foreAttr == nil {
|
||||
n256setup()
|
||||
}
|
||||
attr &= backgroundMask
|
||||
attr |= n256foreAttr[n256]
|
||||
i += 2
|
||||
}
|
||||
} else {
|
||||
attr = attr & (w.oldattr & backgroundMask)
|
||||
}
|
||||
case n == 39: // reset foreground color.
|
||||
attr &= backgroundMask
|
||||
attr |= w.oldattr & foregroundMask
|
||||
case 40 <= n && n <= 47:
|
||||
attr = (attr & foregroundMask)
|
||||
if (n-40)&1 != 0 {
|
||||
attr |= backgroundRed
|
||||
}
|
||||
if (n-40)&2 != 0 {
|
||||
attr |= backgroundGreen
|
||||
}
|
||||
if (n-40)&4 != 0 {
|
||||
attr |= backgroundBlue
|
||||
}
|
||||
case n == 48: // set background color.
|
||||
if i < len(token)-2 && token[i+1] == "5" {
|
||||
if n256, err := strconv.Atoi(token[i+2]); err == nil {
|
||||
if n256backAttr == nil {
|
||||
n256setup()
|
||||
}
|
||||
attr &= foregroundMask
|
||||
attr |= n256backAttr[n256]
|
||||
i += 2
|
||||
}
|
||||
} else {
|
||||
attr = attr & (w.oldattr & foregroundMask)
|
||||
}
|
||||
case n == 49: // reset foreground color.
|
||||
attr &= foregroundMask
|
||||
attr |= w.oldattr & backgroundMask
|
||||
case 90 <= n && n <= 97:
|
||||
attr = (attr & backgroundMask)
|
||||
attr |= foregroundIntensity
|
||||
if (n-90)&1 != 0 {
|
||||
attr |= foregroundRed
|
||||
}
|
||||
if (n-90)&2 != 0 {
|
||||
attr |= foregroundGreen
|
||||
}
|
||||
if (n-90)&4 != 0 {
|
||||
attr |= foregroundBlue
|
||||
}
|
||||
case 100 <= n && n <= 107:
|
||||
attr = (attr & foregroundMask)
|
||||
attr |= backgroundIntensity
|
||||
if (n-100)&1 != 0 {
|
||||
attr |= backgroundRed
|
||||
}
|
||||
if (n-100)&2 != 0 {
|
||||
attr |= backgroundGreen
|
||||
}
|
||||
if (n-100)&4 != 0 {
|
||||
attr |= backgroundBlue
|
||||
}
|
||||
}
|
||||
procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return len(data) - w.lastbuf.Len(), nil
|
||||
}
|
||||
|
||||
type consoleColor struct {
|
||||
rgb int
|
||||
red bool
|
||||
green bool
|
||||
blue bool
|
||||
intensity bool
|
||||
}
|
||||
|
||||
func (c consoleColor) foregroundAttr() (attr word) {
|
||||
if c.red {
|
||||
attr |= foregroundRed
|
||||
}
|
||||
if c.green {
|
||||
attr |= foregroundGreen
|
||||
}
|
||||
if c.blue {
|
||||
attr |= foregroundBlue
|
||||
}
|
||||
if c.intensity {
|
||||
attr |= foregroundIntensity
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c consoleColor) backgroundAttr() (attr word) {
|
||||
if c.red {
|
||||
attr |= backgroundRed
|
||||
}
|
||||
if c.green {
|
||||
attr |= backgroundGreen
|
||||
}
|
||||
if c.blue {
|
||||
attr |= backgroundBlue
|
||||
}
|
||||
if c.intensity {
|
||||
attr |= backgroundIntensity
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var color16 = []consoleColor{
|
||||
consoleColor{0x000000, false, false, false, false},
|
||||
consoleColor{0x000080, false, false, true, false},
|
||||
consoleColor{0x008000, false, true, false, false},
|
||||
consoleColor{0x008080, false, true, true, false},
|
||||
consoleColor{0x800000, true, false, false, false},
|
||||
consoleColor{0x800080, true, false, true, false},
|
||||
consoleColor{0x808000, true, true, false, false},
|
||||
consoleColor{0xc0c0c0, true, true, true, false},
|
||||
consoleColor{0x808080, false, false, false, true},
|
||||
consoleColor{0x0000ff, false, false, true, true},
|
||||
consoleColor{0x00ff00, false, true, false, true},
|
||||
consoleColor{0x00ffff, false, true, true, true},
|
||||
consoleColor{0xff0000, true, false, false, true},
|
||||
consoleColor{0xff00ff, true, false, true, true},
|
||||
consoleColor{0xffff00, true, true, false, true},
|
||||
consoleColor{0xffffff, true, true, true, true},
|
||||
}
|
||||
|
||||
type hsv struct {
|
||||
h, s, v float32
|
||||
}
|
||||
|
||||
func (a hsv) dist(b hsv) float32 {
|
||||
dh := a.h - b.h
|
||||
switch {
|
||||
case dh > 0.5:
|
||||
dh = 1 - dh
|
||||
case dh < -0.5:
|
||||
dh = -1 - dh
|
||||
}
|
||||
ds := a.s - b.s
|
||||
dv := a.v - b.v
|
||||
return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv)))
|
||||
}
|
||||
|
||||
func toHSV(rgb int) hsv {
|
||||
r, g, b := float32((rgb&0xFF0000)>>16)/256.0,
|
||||
float32((rgb&0x00FF00)>>8)/256.0,
|
||||
float32(rgb&0x0000FF)/256.0
|
||||
min, max := minmax3f(r, g, b)
|
||||
h := max - min
|
||||
if h > 0 {
|
||||
if max == r {
|
||||
h = (g - b) / h
|
||||
if h < 0 {
|
||||
h += 6
|
||||
}
|
||||
} else if max == g {
|
||||
h = 2 + (b-r)/h
|
||||
} else {
|
||||
h = 4 + (r-g)/h
|
||||
}
|
||||
}
|
||||
h /= 6.0
|
||||
s := max - min
|
||||
if max != 0 {
|
||||
s /= max
|
||||
}
|
||||
v := max
|
||||
return hsv{h: h, s: s, v: v}
|
||||
}
|
||||
|
||||
type hsvTable []hsv
|
||||
|
||||
func toHSVTable(rgbTable []consoleColor) hsvTable {
|
||||
t := make(hsvTable, len(rgbTable))
|
||||
for i, c := range rgbTable {
|
||||
t[i] = toHSV(c.rgb)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (t hsvTable) find(rgb int) consoleColor {
|
||||
hsv := toHSV(rgb)
|
||||
n := 7
|
||||
l := float32(5.0)
|
||||
for i, p := range t {
|
||||
d := hsv.dist(p)
|
||||
if d < l {
|
||||
l, n = d, i
|
||||
}
|
||||
}
|
||||
return color16[n]
|
||||
}
|
||||
|
||||
func minmax3f(a, b, c float32) (min, max float32) {
|
||||
if a < b {
|
||||
if b < c {
|
||||
return a, c
|
||||
} else if a < c {
|
||||
return a, b
|
||||
} else {
|
||||
return c, b
|
||||
}
|
||||
} else {
|
||||
if a < c {
|
||||
return b, c
|
||||
} else if b < c {
|
||||
return b, a
|
||||
} else {
|
||||
return c, a
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var n256foreAttr []word
|
||||
var n256backAttr []word
|
||||
|
||||
func n256setup() {
|
||||
n256foreAttr = make([]word, 256)
|
||||
n256backAttr = make([]word, 256)
|
||||
t := toHSVTable(color16)
|
||||
for i, rgb := range color256 {
|
||||
c := t.find(rgb)
|
||||
n256foreAttr[i] = c.foregroundAttr()
|
||||
n256backAttr[i] = c.backgroundAttr()
|
||||
}
|
||||
}
|
9
vendor/github.com/mattn/go-isatty/isatty_appengine.go
generated
vendored
Normal file
9
vendor/github.com/mattn/go-isatty/isatty_appengine.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// +build appengine
|
||||
|
||||
package isatty
|
||||
|
||||
// IsTerminal returns true if the file descriptor is terminal which
|
||||
// is always false on on appengine classic which is a sandboxed PaaS.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
return false
|
||||
}
|
1
vendor/github.com/mattn/go-isatty/isatty_bsd.go
generated
vendored
1
vendor/github.com/mattn/go-isatty/isatty_bsd.go
generated
vendored
@ -1,4 +1,5 @@
|
||||
// +build darwin freebsd openbsd netbsd
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
|
1
vendor/github.com/mattn/go-isatty/isatty_linux.go
generated
vendored
1
vendor/github.com/mattn/go-isatty/isatty_linux.go
generated
vendored
@ -1,4 +1,5 @@
|
||||
// +build linux
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
|
16
vendor/github.com/mattn/go-isatty/isatty_solaris.go
generated
vendored
Normal file
16
vendor/github.com/mattn/go-isatty/isatty_solaris.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// +build solaris
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
var termio unix.Termio
|
||||
err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio)
|
||||
return err == nil
|
||||
}
|
1
vendor/github.com/mattn/go-isatty/isatty_windows.go
generated
vendored
1
vendor/github.com/mattn/go-isatty/isatty_windows.go
generated
vendored
@ -1,4 +1,5 @@
|
||||
// +build windows
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
|
7
vendor/github.com/samalba/dockerclient/auth.go
generated
vendored
7
vendor/github.com/samalba/dockerclient/auth.go
generated
vendored
@ -8,9 +8,10 @@ import (
|
||||
|
||||
// AuthConfig hold parameters for authenticating with the docker registry
|
||||
type AuthConfig struct {
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
RegistryToken string `json:"registrytoken,omitempty"`
|
||||
}
|
||||
|
||||
// encode the auth configuration struct into base64 for the X-Registry-Auth header
|
||||
|
15
vendor/github.com/samalba/dockerclient/auth_test.go
generated
vendored
15
vendor/github.com/samalba/dockerclient/auth_test.go
generated
vendored
@ -1,15 +0,0 @@
|
||||
package dockerclient
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAuthEncode(t *testing.T) {
|
||||
a := AuthConfig{Username: "foo", Password: "password", Email: "bar@baz.com"}
|
||||
expected := "eyJ1c2VybmFtZSI6ImZvbyIsInBhc3N3b3JkIjoicGFzc3dvcmQiLCJlbWFpbCI6ImJhckBiYXouY29tIn0K"
|
||||
got, _ := a.encode()
|
||||
|
||||
if expected != got {
|
||||
t.Errorf("testAuthEncode failed. Expected [%s] got [%s]", expected, got)
|
||||
}
|
||||
}
|
302
vendor/github.com/samalba/dockerclient/dockerclient.go
generated
vendored
302
vendor/github.com/samalba/dockerclient/dockerclient.go
generated
vendored
@ -21,7 +21,9 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNotFound = errors.New("Not found")
|
||||
ErrImageNotFound = errors.New("Image not found")
|
||||
ErrNotFound = errors.New("Not found")
|
||||
ErrConnectionRefused = errors.New("Cannot connect to the docker engine endpoint")
|
||||
|
||||
defaultTimeout = 30 * time.Second
|
||||
)
|
||||
@ -99,9 +101,24 @@ func (client *DockerClient) doStreamRequest(method string, path string, in io.Re
|
||||
if !strings.Contains(err.Error(), "connection refused") && client.TLSConfig == nil {
|
||||
return nil, fmt.Errorf("%v. Are you trying to connect to a TLS-enabled daemon without TLS?", err)
|
||||
}
|
||||
if strings.Contains(err.Error(), "connection refused") {
|
||||
return nil, ErrConnectionRefused
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode == 404 {
|
||||
defer resp.Body.Close()
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
if len(data) > 0 {
|
||||
// check if is image not found error
|
||||
if strings.Index(string(data), "No such image") != -1 {
|
||||
return nil, ErrImageNotFound
|
||||
}
|
||||
return nil, errors.New(string(data))
|
||||
}
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
if resp.StatusCode >= 400 {
|
||||
@ -171,7 +188,7 @@ func (client *DockerClient) InspectContainer(id string) (*ContainerInfo, error)
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) CreateContainer(config *ContainerConfig, name string) (string, error) {
|
||||
func (client *DockerClient) CreateContainer(config *ContainerConfig, name string, auth *AuthConfig) (string, error) {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -182,14 +199,22 @@ func (client *DockerClient) CreateContainer(config *ContainerConfig, name string
|
||||
v.Set("name", name)
|
||||
uri = fmt.Sprintf("%s?%s", uri, v.Encode())
|
||||
}
|
||||
data, err = client.doRequest("POST", uri, data, nil)
|
||||
headers := map[string]string{}
|
||||
if auth != nil {
|
||||
encoded_auth, err := auth.encode()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
headers["X-Registry-Auth"] = encoded_auth
|
||||
}
|
||||
data, err = client.doRequest("POST", uri, data, headers)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
result := &RespContainersCreate{}
|
||||
err = json.Unmarshal(data, result)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", fmt.Errorf(string(data))
|
||||
}
|
||||
return result.Id, nil
|
||||
}
|
||||
@ -255,7 +280,7 @@ func (client *DockerClient) readJSONStream(stream io.ReadCloser, decode func(*js
|
||||
select {
|
||||
case <-stopChan:
|
||||
stream.Close()
|
||||
for _ = range decodeChan {
|
||||
for range decodeChan {
|
||||
}
|
||||
return
|
||||
case decodeResult := <-decodeChan:
|
||||
@ -272,6 +297,79 @@ func (client *DockerClient) readJSONStream(stream io.ReadCloser, decode func(*js
|
||||
return resultChan
|
||||
}
|
||||
|
||||
func (client *DockerClient) ExecCreate(config *ExecConfig) (string, error) {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/containers/%s/exec", APIVersion, config.Container)
|
||||
resp, err := client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var createExecResp struct {
|
||||
Id string
|
||||
}
|
||||
if err = json.Unmarshal(resp, &createExecResp); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return createExecResp.Id, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) ExecStart(id string, config *ExecConfig) error {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("/%s/exec/%s/start", APIVersion, id)
|
||||
if _, err := client.doRequest("POST", uri, data, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) ExecResize(id string, width, height int) error {
|
||||
v := url.Values{}
|
||||
|
||||
w := strconv.Itoa(width)
|
||||
h := strconv.Itoa(height)
|
||||
|
||||
v.Set("w", w)
|
||||
v.Set("h", h)
|
||||
|
||||
uri := fmt.Sprintf("/%s/exec/%s/resize?%s", APIVersion, id, v.Encode())
|
||||
if _, err := client.doRequest("POST", client.URL.String()+uri, nil, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) AttachContainer(id string, options *AttachOptions) (io.ReadCloser, error) {
|
||||
v := url.Values{}
|
||||
if options != nil {
|
||||
if options.Logs {
|
||||
v.Set("logs", "1")
|
||||
}
|
||||
if options.Stream {
|
||||
v.Set("stream", "1")
|
||||
}
|
||||
if options.Stdin {
|
||||
v.Set("stdin", "1")
|
||||
}
|
||||
if options.Stdout {
|
||||
v.Set("stdout", "1")
|
||||
}
|
||||
if options.Stderr {
|
||||
v.Set("stderr", "1")
|
||||
}
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/containers/%s/attach?%s", APIVersion, id, v.Encode())
|
||||
return client.doStreamRequest("POST", uri, nil, nil)
|
||||
}
|
||||
|
||||
func (client *DockerClient) StartContainer(id string, config *HostConfig) error {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
@ -475,6 +573,37 @@ func (client *DockerClient) Version() (*Version, error) {
|
||||
return version, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) PushImage(name string, tag string, auth *AuthConfig) error {
|
||||
v := url.Values{}
|
||||
if tag != "" {
|
||||
v.Set("tag", tag)
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/images/%s/push?%s", APIVersion, url.QueryEscape(name), v.Encode())
|
||||
req, err := http.NewRequest("POST", client.URL.String()+uri, nil)
|
||||
if auth != nil {
|
||||
if encodedAuth, err := auth.encode(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
req.Header.Add("X-Registry-Auth", encodedAuth)
|
||||
}
|
||||
}
|
||||
resp, err := client.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
var finalObj map[string]interface{}
|
||||
for decoder := json.NewDecoder(resp.Body); err == nil; err = decoder.Decode(&finalObj) {
|
||||
}
|
||||
if err != io.EOF {
|
||||
return err
|
||||
}
|
||||
if err, ok := finalObj["error"]; ok {
|
||||
return fmt.Errorf("%v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) PullImage(name string, auth *AuthConfig) error {
|
||||
v := url.Values{}
|
||||
v.Set("fromImage", name)
|
||||
@ -531,17 +660,9 @@ func (client *DockerClient) InspectImage(id string) (*ImageInfo, error) {
|
||||
}
|
||||
|
||||
func (client *DockerClient) LoadImage(reader io.Reader) error {
|
||||
data, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("/%s/images/load", APIVersion)
|
||||
_, err = client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
_, err := client.doStreamRequest("POST", uri, reader, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *DockerClient) RemoveContainer(id string, force, volumes bool) error {
|
||||
@ -576,8 +697,14 @@ func (client *DockerClient) ListImages(all bool) ([]*Image, error) {
|
||||
return images, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) RemoveImage(name string) ([]*ImageDelete, error) {
|
||||
uri := fmt.Sprintf("/%s/images/%s", APIVersion, name)
|
||||
func (client *DockerClient) RemoveImage(name string, force bool) ([]*ImageDelete, error) {
|
||||
argForce := 0
|
||||
if force {
|
||||
argForce = 1
|
||||
}
|
||||
|
||||
args := fmt.Sprintf("force=%d", argForce)
|
||||
uri := fmt.Sprintf("/%s/images/%s?%s", APIVersion, name, args)
|
||||
data, err := client.doRequest("DELETE", uri, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -606,30 +733,6 @@ func (client *DockerClient) UnpauseContainer(id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) Exec(config *ExecConfig) (string, error) {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
uri := fmt.Sprintf("/containers/%s/exec", config.Container)
|
||||
resp, err := client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var createExecResp struct {
|
||||
Id string
|
||||
}
|
||||
if err = json.Unmarshal(resp, &createExecResp); err != nil {
|
||||
return "", err
|
||||
}
|
||||
uri = fmt.Sprintf("/exec/%s/start", createExecResp.Id)
|
||||
resp, err = client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return createExecResp.Id, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) RenameContainer(oldName string, newName string) error {
|
||||
uri := fmt.Sprintf("/containers/%s/rename?name=%s", oldName, newName)
|
||||
_, err := client.doRequest("POST", uri, nil, nil)
|
||||
@ -696,6 +799,13 @@ func (client *DockerClient) BuildImage(image *BuildImage) (io.ReadCloser, error)
|
||||
v.Set("cpusetcpus", image.CpuSetCpus)
|
||||
v.Set("cpusetmems", image.CpuSetMems)
|
||||
v.Set("cgroupparent", image.CgroupParent)
|
||||
if image.BuildArgs != nil {
|
||||
buildArgsJSON, err := json.Marshal(image.BuildArgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v.Set("buildargs", string(buildArgsJSON))
|
||||
}
|
||||
|
||||
headers := make(map[string]string)
|
||||
if image.Config != nil {
|
||||
@ -712,3 +822,113 @@ func (client *DockerClient) BuildImage(image *BuildImage) (io.ReadCloser, error)
|
||||
uri := fmt.Sprintf("/%s/build?%s", APIVersion, v.Encode())
|
||||
return client.doStreamRequest("POST", uri, image.Context, headers)
|
||||
}
|
||||
|
||||
func (client *DockerClient) ListVolumes() ([]*Volume, error) {
|
||||
uri := fmt.Sprintf("/%s/volumes", APIVersion)
|
||||
data, err := client.doRequest("GET", uri, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var volumesList VolumesListResponse
|
||||
if err := json.Unmarshal(data, &volumesList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return volumesList.Volumes, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) RemoveVolume(name string) error {
|
||||
uri := fmt.Sprintf("/%s/volumes/%s", APIVersion, name)
|
||||
_, err := client.doRequest("DELETE", uri, nil, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *DockerClient) CreateVolume(request *VolumeCreateRequest) (*Volume, error) {
|
||||
data, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/volumes/create", APIVersion)
|
||||
data, err = client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
volume := &Volume{}
|
||||
err = json.Unmarshal(data, volume)
|
||||
return volume, err
|
||||
}
|
||||
|
||||
func (client *DockerClient) ListNetworks(filters string) ([]*NetworkResource, error) {
|
||||
uri := fmt.Sprintf("/%s/networks", APIVersion)
|
||||
|
||||
if filters != "" {
|
||||
uri += "&filters=" + filters
|
||||
}
|
||||
|
||||
data, err := client.doRequest("GET", uri, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []*NetworkResource{}
|
||||
err = json.Unmarshal(data, &ret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) InspectNetwork(id string) (*NetworkResource, error) {
|
||||
uri := fmt.Sprintf("/%s/networks/%s", APIVersion, id)
|
||||
|
||||
data, err := client.doRequest("GET", uri, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &NetworkResource{}
|
||||
err = json.Unmarshal(data, ret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) CreateNetwork(config *NetworkCreate) (*NetworkCreateResponse, error) {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/networks/create", APIVersion)
|
||||
data, err = client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &NetworkCreateResponse{}
|
||||
err = json.Unmarshal(data, ret)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) ConnectNetwork(id, container string) error {
|
||||
data, err := json.Marshal(NetworkConnect{Container: container})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/networks/%s/connect", APIVersion, id)
|
||||
_, err = client.doRequest("POST", uri, data, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *DockerClient) DisconnectNetwork(id, container string) error {
|
||||
data, err := json.Marshal(NetworkDisconnect{Container: container})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/networks/%s/disconnect", APIVersion, id)
|
||||
_, err = client.doRequest("POST", uri, data, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *DockerClient) RemoveNetwork(id string) error {
|
||||
uri := fmt.Sprintf("/%s/networks/%s", APIVersion, id)
|
||||
_, err := client.doRequest("DELETE", uri, nil, nil)
|
||||
return err
|
||||
}
|
||||
|
240
vendor/github.com/samalba/dockerclient/dockerclient_test.go
generated
vendored
240
vendor/github.com/samalba/dockerclient/dockerclient_test.go
generated
vendored
@ -1,240 +0,0 @@
|
||||
package dockerclient
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
)
|
||||
|
||||
func assertEqual(t *testing.T, a interface{}, b interface{}, message string) {
|
||||
if a == b {
|
||||
return
|
||||
}
|
||||
if len(message) == 0 {
|
||||
message = fmt.Sprintf("%v != %v", a, b)
|
||||
}
|
||||
t.Fatal(message)
|
||||
}
|
||||
|
||||
func testDockerClient(t *testing.T) *DockerClient {
|
||||
client, err := NewDockerClient(testHTTPServer.URL, nil)
|
||||
if err != nil {
|
||||
t.Fatal("Cannot init the docker client")
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
func TestInfo(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
info, err := client.Info()
|
||||
if err != nil {
|
||||
t.Fatal("Cannot get server info")
|
||||
}
|
||||
assertEqual(t, info.Images, int64(1), "")
|
||||
assertEqual(t, info.Containers, int64(2), "")
|
||||
}
|
||||
|
||||
func TestKillContainer(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
if err := client.KillContainer("23132acf2ac", "5"); err != nil {
|
||||
t.Fatal("cannot kill container: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWait(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
|
||||
// This provokes an error on the server.
|
||||
select {
|
||||
case wr := <-client.Wait("1234"):
|
||||
assertEqual(t, wr.ExitCode, int(-1), "")
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("Timed out!")
|
||||
}
|
||||
|
||||
// Valid case.
|
||||
select {
|
||||
case wr := <-client.Wait("valid-id"):
|
||||
assertEqual(t, wr.ExitCode, int(0), "")
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("Timed out!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPullImage(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
err := client.PullImage("busybox", nil)
|
||||
if err != nil {
|
||||
t.Fatal("unable to pull busybox")
|
||||
}
|
||||
|
||||
err = client.PullImage("haproxy", nil)
|
||||
if err != nil {
|
||||
t.Fatal("unable to pull haproxy")
|
||||
}
|
||||
|
||||
err = client.PullImage("wrongimg", nil)
|
||||
if err == nil {
|
||||
t.Fatal("should return error when it fails to pull wrongimg")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListContainers(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
containers, err := client.ListContainers(true, false, "")
|
||||
if err != nil {
|
||||
t.Fatal("cannot get containers: %s", err)
|
||||
}
|
||||
assertEqual(t, len(containers), 1, "")
|
||||
cnt := containers[0]
|
||||
assertEqual(t, cnt.SizeRw, int64(0), "")
|
||||
}
|
||||
|
||||
func TestContainerChanges(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
changes, err := client.ContainerChanges("foobar")
|
||||
if err != nil {
|
||||
t.Fatal("cannot get container changes: %s", err)
|
||||
}
|
||||
assertEqual(t, len(changes), 3, "unexpected number of changes")
|
||||
c := changes[0]
|
||||
assertEqual(t, c.Path, "/dev", "unexpected")
|
||||
assertEqual(t, c.Kind, 0, "unexpected")
|
||||
}
|
||||
|
||||
func TestListContainersWithSize(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
containers, err := client.ListContainers(true, true, "")
|
||||
if err != nil {
|
||||
t.Fatal("cannot get containers: %s", err)
|
||||
}
|
||||
assertEqual(t, len(containers), 1, "")
|
||||
cnt := containers[0]
|
||||
assertEqual(t, cnt.SizeRw, int64(123), "")
|
||||
}
|
||||
func TestListContainersWithFilters(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
containers, err := client.ListContainers(true, true, "{'id':['332375cfbc23edb921a21026314c3497674ba8bdcb2c85e0e65ebf2017f688ce']}")
|
||||
if err != nil {
|
||||
t.Fatal("cannot get containers: %s", err)
|
||||
}
|
||||
assertEqual(t, len(containers), 1, "")
|
||||
|
||||
containers, err = client.ListContainers(true, true, "{'id':['332375cfbc23edb921a21026314c3497674ba8bdcb2c85e0e65ebf2017f688cf']}")
|
||||
if err != nil {
|
||||
t.Fatal("cannot get containers: %s", err)
|
||||
}
|
||||
assertEqual(t, len(containers), 0, "")
|
||||
}
|
||||
|
||||
func TestContainerLogs(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
containerId := "foobar"
|
||||
logOptions := &LogOptions{
|
||||
Follow: true,
|
||||
Stdout: true,
|
||||
Stderr: true,
|
||||
Timestamps: true,
|
||||
Tail: 10,
|
||||
}
|
||||
logsReader, err := client.ContainerLogs(containerId, logOptions)
|
||||
if err != nil {
|
||||
t.Fatal("cannot read logs from server")
|
||||
}
|
||||
|
||||
stdoutBuffer := new(bytes.Buffer)
|
||||
stderrBuffer := new(bytes.Buffer)
|
||||
if _, err = stdcopy.StdCopy(stdoutBuffer, stderrBuffer, logsReader); err != nil {
|
||||
t.Fatal("cannot read logs from logs reader")
|
||||
}
|
||||
stdoutLogs := strings.TrimSpace(stdoutBuffer.String())
|
||||
stderrLogs := strings.TrimSpace(stderrBuffer.String())
|
||||
stdoutLogLines := strings.Split(stdoutLogs, "\n")
|
||||
stderrLogLines := strings.Split(stderrLogs, "\n")
|
||||
if len(stdoutLogLines) != 5 {
|
||||
t.Fatalf("wrong number of stdout logs: len=%d", len(stdoutLogLines))
|
||||
}
|
||||
if len(stderrLogLines) != 5 {
|
||||
t.Fatalf("wrong number of stderr logs: len=%d", len(stdoutLogLines))
|
||||
}
|
||||
for i, line := range stdoutLogLines {
|
||||
expectedSuffix := fmt.Sprintf("Z line %d", 41+2*i)
|
||||
if !strings.HasSuffix(line, expectedSuffix) {
|
||||
t.Fatalf("expected stdout log line \"%s\" to end with \"%s\"", line, expectedSuffix)
|
||||
}
|
||||
}
|
||||
for i, line := range stderrLogLines {
|
||||
expectedSuffix := fmt.Sprintf("Z line %d", 40+2*i)
|
||||
if !strings.HasSuffix(line, expectedSuffix) {
|
||||
t.Fatalf("expected stderr log line \"%s\" to end with \"%s\"", line, expectedSuffix)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonitorEvents(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
decoder := json.NewDecoder(bytes.NewBufferString(eventsResp))
|
||||
var expectedEvents []Event
|
||||
for {
|
||||
var event Event
|
||||
if err := decoder.Decode(&event); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else {
|
||||
t.Fatalf("cannot parse expected resp: %s", err.Error())
|
||||
}
|
||||
} else {
|
||||
expectedEvents = append(expectedEvents, event)
|
||||
}
|
||||
}
|
||||
|
||||
// test passing stop chan
|
||||
stopChan := make(chan struct{})
|
||||
eventInfoChan, err := client.MonitorEvents(nil, stopChan)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot get events from server: %s", err.Error())
|
||||
}
|
||||
|
||||
eventInfo := <-eventInfoChan
|
||||
if eventInfo.Error != nil || eventInfo.Event != expectedEvents[0] {
|
||||
t.Fatalf("got:\n%#v\nexpected:\n%#v", eventInfo, expectedEvents[0])
|
||||
}
|
||||
close(stopChan)
|
||||
for i := 0; i < 3; i++ {
|
||||
_, ok := <-eventInfoChan
|
||||
if i == 2 && ok {
|
||||
t.Fatalf("read more than 2 events successfully after closing stopChan")
|
||||
}
|
||||
}
|
||||
|
||||
// test when you don't pass stop chan
|
||||
eventInfoChan, err = client.MonitorEvents(nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot get events from server: %s", err.Error())
|
||||
}
|
||||
|
||||
for i, expectedEvent := range expectedEvents {
|
||||
t.Logf("on iter %d\n", i)
|
||||
eventInfo := <-eventInfoChan
|
||||
if eventInfo.Error != nil || eventInfo.Event != expectedEvent {
|
||||
t.Fatalf("index %d, got:\n%#v\nexpected:\n%#v", i, eventInfo, expectedEvent)
|
||||
}
|
||||
t.Logf("done with iter %d\n", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDockerClientInterface(t *testing.T) {
|
||||
iface := reflect.TypeOf((*Client)(nil)).Elem()
|
||||
test := testDockerClient(t)
|
||||
|
||||
if !reflect.TypeOf(test).Implements(iface) {
|
||||
t.Fatalf("DockerClient does not implement the Client interface")
|
||||
}
|
||||
}
|
245
vendor/github.com/samalba/dockerclient/engine_mock_test.go
generated
vendored
245
vendor/github.com/samalba/dockerclient/engine_mock_test.go
generated
vendored
@ -1,245 +0,0 @@
|
||||
package dockerclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/jsonlog"
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
"github.com/docker/docker/pkg/timeutils"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
var (
|
||||
testHTTPServer *httptest.Server
|
||||
)
|
||||
|
||||
func init() {
|
||||
r := mux.NewRouter()
|
||||
baseURL := "/" + APIVersion
|
||||
r.HandleFunc(baseURL+"/info", handlerGetInfo).Methods("GET")
|
||||
r.HandleFunc(baseURL+"/containers/json", handlerGetContainers).Methods("GET")
|
||||
r.HandleFunc(baseURL+"/containers/{id}/logs", handleContainerLogs).Methods("GET")
|
||||
r.HandleFunc(baseURL+"/containers/{id}/changes", handleContainerChanges).Methods("GET")
|
||||
r.HandleFunc(baseURL+"/containers/{id}/kill", handleContainerKill).Methods("POST")
|
||||
r.HandleFunc(baseURL+"/containers/{id}/wait", handleWait).Methods("POST")
|
||||
r.HandleFunc(baseURL+"/images/create", handleImagePull).Methods("POST")
|
||||
r.HandleFunc(baseURL+"/events", handleEvents).Methods("GET")
|
||||
testHTTPServer = httptest.NewServer(handlerAccessLog(r))
|
||||
}
|
||||
|
||||
func handlerAccessLog(handler http.Handler) http.Handler {
|
||||
logHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("%s \"%s %s\"", r.RemoteAddr, r.Method, r.URL)
|
||||
handler.ServeHTTP(w, r)
|
||||
}
|
||||
return http.HandlerFunc(logHandler)
|
||||
}
|
||||
|
||||
func handleContainerKill(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "{%q:%q", "Id", "421373210afd132")
|
||||
}
|
||||
|
||||
func handleWait(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
if vars["id"] == "valid-id" {
|
||||
fmt.Fprintf(w, `{"StatusCode":0}`)
|
||||
} else {
|
||||
http.Error(w, "failed", 500)
|
||||
}
|
||||
}
|
||||
|
||||
func handleImagePull(w http.ResponseWriter, r *http.Request) {
|
||||
imageName := r.URL.Query()["fromImage"][0]
|
||||
responses := []map[string]interface{}{{
|
||||
"status": fmt.Sprintf("Pulling repository mydockerregistry/%s", imageName),
|
||||
}}
|
||||
switch imageName {
|
||||
case "busybox":
|
||||
responses = append(responses, map[string]interface{}{
|
||||
"status": "Status: Image is up to date for mydockerregistry/busybox",
|
||||
})
|
||||
case "haproxy":
|
||||
fmt.Fprintf(w, haproxyPullOutput)
|
||||
return
|
||||
default:
|
||||
errorMsg := fmt.Sprintf("Error: image %s not found", imageName)
|
||||
responses = append(responses, map[string]interface{}{
|
||||
"errorDetail": map[string]interface{}{
|
||||
"message": errorMsg,
|
||||
},
|
||||
"error": errorMsg,
|
||||
})
|
||||
}
|
||||
for _, response := range responses {
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
}
|
||||
|
||||
func handleContainerLogs(w http.ResponseWriter, r *http.Request) {
|
||||
var outStream, errStream io.Writer
|
||||
outStream = ioutils.NewWriteFlusher(w)
|
||||
|
||||
// not sure how to test follow
|
||||
if err := r.ParseForm(); err != nil {
|
||||
http.Error(w, err.Error(), 500)
|
||||
}
|
||||
stdout, stderr := getBoolValue(r.Form.Get("stdout")), getBoolValue(r.Form.Get("stderr"))
|
||||
if stderr {
|
||||
errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr)
|
||||
}
|
||||
if stdout {
|
||||
outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout)
|
||||
}
|
||||
var i int
|
||||
if tail, err := strconv.Atoi(r.Form.Get("tail")); err == nil && tail > 0 {
|
||||
i = 50 - tail
|
||||
if i < 0 {
|
||||
i = 0
|
||||
}
|
||||
}
|
||||
for ; i < 50; i++ {
|
||||
line := fmt.Sprintf("line %d", i)
|
||||
if getBoolValue(r.Form.Get("timestamps")) {
|
||||
l := &jsonlog.JSONLog{Log: line, Created: time.Now().UTC()}
|
||||
line = fmt.Sprintf("%s %s", l.Created.Format(timeutils.RFC3339NanoFixed), line)
|
||||
}
|
||||
if i%2 == 0 && stderr {
|
||||
fmt.Fprintln(errStream, line)
|
||||
} else if i%2 == 1 && stdout {
|
||||
fmt.Fprintln(outStream, line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleContainerChanges(w http.ResponseWriter, r *http.Request) {
|
||||
writeHeaders(w, 200, "changes")
|
||||
body := `[
|
||||
{
|
||||
"Path": "/dev",
|
||||
"Kind": 0
|
||||
},
|
||||
{
|
||||
"Path": "/dev/kmsg",
|
||||
"Kind": 1
|
||||
},
|
||||
{
|
||||
"Path": "/test",
|
||||
"Kind": 1
|
||||
}
|
||||
]`
|
||||
w.Write([]byte(body))
|
||||
}
|
||||
|
||||
func getBoolValue(boolString string) bool {
|
||||
switch boolString {
|
||||
case "1":
|
||||
return true
|
||||
case "True":
|
||||
return true
|
||||
case "true":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func writeHeaders(w http.ResponseWriter, code int, jobName string) {
|
||||
h := w.Header()
|
||||
h.Add("Content-Type", "application/json")
|
||||
if jobName != "" {
|
||||
h.Add("Job-Name", jobName)
|
||||
}
|
||||
w.WriteHeader(code)
|
||||
}
|
||||
|
||||
func handlerGetInfo(w http.ResponseWriter, r *http.Request) {
|
||||
writeHeaders(w, 200, "info")
|
||||
body := `{
|
||||
"Containers": 2,
|
||||
"Debug": 1,
|
||||
"Driver": "aufs",
|
||||
"DriverStatus": [["Root Dir", "/mnt/sda1/var/lib/docker/aufs"],
|
||||
["Dirs", "0"]],
|
||||
"ExecutionDriver": "native-0.2",
|
||||
"IPv4Forwarding": 1,
|
||||
"Images": 1,
|
||||
"IndexServerAddress": "https://index.docker.io/v1/",
|
||||
"InitPath": "/usr/local/bin/docker",
|
||||
"InitSha1": "",
|
||||
"KernelVersion": "3.16.4-tinycore64",
|
||||
"MemoryLimit": 1,
|
||||
"NEventsListener": 0,
|
||||
"NFd": 10,
|
||||
"NGoroutines": 11,
|
||||
"OperatingSystem": "Boot2Docker 1.3.1 (TCL 5.4); master : a083df4 - Thu Jan 01 00:00:00 UTC 1970",
|
||||
"SwapLimit": 1}`
|
||||
w.Write([]byte(body))
|
||||
}
|
||||
|
||||
func handlerGetContainers(w http.ResponseWriter, r *http.Request) {
|
||||
writeHeaders(w, 200, "containers")
|
||||
body := `[
|
||||
{
|
||||
"Status": "Up 39 seconds",
|
||||
"Ports": [
|
||||
{
|
||||
"Type": "tcp",
|
||||
"PublicPort": 49163,
|
||||
"PrivatePort": 8080,
|
||||
"IP": "0.0.0.0"
|
||||
}
|
||||
],
|
||||
"Names": [
|
||||
"/trusting_heisenberg"
|
||||
],
|
||||
"Image": "foo:latest",
|
||||
"Id": "332375cfbc23edb921a21026314c3497674ba8bdcb2c85e0e65ebf2017f688ce",
|
||||
"Created": 1415720105,
|
||||
"Command": "/bin/go-run"
|
||||
}
|
||||
]`
|
||||
if v, ok := r.URL.Query()["size"]; ok {
|
||||
if v[0] == "1" {
|
||||
body = `[
|
||||
{
|
||||
"Status": "Up 39 seconds",
|
||||
"Ports": [
|
||||
{
|
||||
"Type": "tcp",
|
||||
"PublicPort": 49163,
|
||||
"PrivatePort": 8080,
|
||||
"IP": "0.0.0.0"
|
||||
}
|
||||
],
|
||||
"Names": [
|
||||
"/trusting_heisenberg"
|
||||
],
|
||||
"Image": "foo:latest",
|
||||
"Id": "332375cfbc23edb921a21026314c3497674ba8bdcb2c85e0e65ebf2017f688ce",
|
||||
"Created": 1415720105,
|
||||
"SizeRootFs": 12345,
|
||||
"SizeRW": 123,
|
||||
"Command": "/bin/go-run"
|
||||
}
|
||||
]`
|
||||
}
|
||||
}
|
||||
if v, ok := r.URL.Query()["filters"]; ok {
|
||||
if v[0] != "{'id':['332375cfbc23edb921a21026314c3497674ba8bdcb2c85e0e65ebf2017f688ce']}" {
|
||||
body = "[]"
|
||||
}
|
||||
}
|
||||
w.Write([]byte(body))
|
||||
}
|
||||
|
||||
func handleEvents(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(eventsResp))
|
||||
}
|
39
vendor/github.com/samalba/dockerclient/examples/events.go
generated
vendored
39
vendor/github.com/samalba/dockerclient/examples/events.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/samalba/dockerclient"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func eventCallback(e *dockerclient.Event, ec chan error, args ...interface{}) {
|
||||
log.Println(e)
|
||||
}
|
||||
|
||||
var (
|
||||
client *dockerclient.DockerClient
|
||||
)
|
||||
|
||||
func waitForInterrupt() {
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
|
||||
for _ = range sigChan {
|
||||
client.StopAllMonitorEvents()
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
docker, err := dockerclient.NewDockerClient(os.Getenv("DOCKER_HOST"), nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
client = docker
|
||||
|
||||
client.StartMonitorEvents(eventCallback, nil)
|
||||
|
||||
waitForInterrupt()
|
||||
}
|
43
vendor/github.com/samalba/dockerclient/examples/stats/stats.go
generated
vendored
43
vendor/github.com/samalba/dockerclient/examples/stats/stats.go
generated
vendored
@ -1,43 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/samalba/dockerclient"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func statCallback(id string, stat *dockerclient.Stats, ec chan error, args ...interface{}) {
|
||||
log.Println(stat)
|
||||
}
|
||||
|
||||
func waitForInterrupt() {
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
|
||||
for _ = range sigChan {
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
docker, err := dockerclient.NewDockerClient(os.Getenv("DOCKER_HOST"), nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
containerConfig := &dockerclient.ContainerConfig{Image: "busybox", Cmd: []string{"sh"}}
|
||||
containerId, err := docker.CreateContainer(containerConfig, "")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Start the container
|
||||
err = docker.StartContainer(containerId, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
docker.StartMonitorStats(containerId, statCallback, nil)
|
||||
|
||||
waitForInterrupt()
|
||||
}
|
19
vendor/github.com/samalba/dockerclient/interface.go
generated
vendored
19
vendor/github.com/samalba/dockerclient/interface.go
generated
vendored
@ -13,11 +13,14 @@ type Client interface {
|
||||
ListContainers(all, size bool, filters string) ([]Container, error)
|
||||
InspectContainer(id string) (*ContainerInfo, error)
|
||||
InspectImage(id string) (*ImageInfo, error)
|
||||
CreateContainer(config *ContainerConfig, name string) (string, error)
|
||||
CreateContainer(config *ContainerConfig, name string, authConfig *AuthConfig) (string, error)
|
||||
ContainerLogs(id string, options *LogOptions) (io.ReadCloser, error)
|
||||
ContainerChanges(id string) ([]*ContainerChanges, error)
|
||||
Exec(config *ExecConfig) (string, error)
|
||||
ExecCreate(config *ExecConfig) (string, error)
|
||||
ExecStart(id string, config *ExecConfig) error
|
||||
ExecResize(id string, width, height int) error
|
||||
StartContainer(id string, config *HostConfig) error
|
||||
AttachContainer(id string, options *AttachOptions) (io.ReadCloser, error)
|
||||
StopContainer(id string, timeout int) error
|
||||
RestartContainer(id string, timeout int) error
|
||||
KillContainer(id, signal string) error
|
||||
@ -34,13 +37,23 @@ type Client interface {
|
||||
TagImage(nameOrID string, repo string, tag string, force bool) error
|
||||
Version() (*Version, error)
|
||||
PullImage(name string, auth *AuthConfig) error
|
||||
PushImage(name string, tag string, auth *AuthConfig) error
|
||||
LoadImage(reader io.Reader) error
|
||||
RemoveContainer(id string, force, volumes bool) error
|
||||
ListImages(all bool) ([]*Image, error)
|
||||
RemoveImage(name string) ([]*ImageDelete, error)
|
||||
RemoveImage(name string, force bool) ([]*ImageDelete, error)
|
||||
PauseContainer(name string) error
|
||||
UnpauseContainer(name string) error
|
||||
RenameContainer(oldName string, newName string) error
|
||||
ImportImage(source string, repository string, tag string, tar io.Reader) (io.ReadCloser, error)
|
||||
BuildImage(image *BuildImage) (io.ReadCloser, error)
|
||||
ListVolumes() ([]*Volume, error)
|
||||
RemoveVolume(name string) error
|
||||
CreateVolume(request *VolumeCreateRequest) (*Volume, error)
|
||||
ListNetworks(filters string) ([]*NetworkResource, error)
|
||||
InspectNetwork(id string) (*NetworkResource, error)
|
||||
CreateNetwork(config *NetworkCreate) (*NetworkCreateResponse, error)
|
||||
ConnectNetwork(id, container string) error
|
||||
DisconnectNetwork(id, container string) error
|
||||
RemoveNetwork(id string) error
|
||||
}
|
||||
|
162
vendor/github.com/samalba/dockerclient/mockclient/mock.go
generated
vendored
162
vendor/github.com/samalba/dockerclient/mockclient/mock.go
generated
vendored
@ -1,162 +0,0 @@
|
||||
package mockclient
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/samalba/dockerclient"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
type MockClient struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func NewMockClient() *MockClient {
|
||||
return &MockClient{}
|
||||
}
|
||||
|
||||
func (client *MockClient) Info() (*dockerclient.Info, error) {
|
||||
args := client.Mock.Called()
|
||||
return args.Get(0).(*dockerclient.Info), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) ListContainers(all bool, size bool, filters string) ([]dockerclient.Container, error) {
|
||||
args := client.Mock.Called(all, size, filters)
|
||||
return args.Get(0).([]dockerclient.Container), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) InspectContainer(id string) (*dockerclient.ContainerInfo, error) {
|
||||
args := client.Mock.Called(id)
|
||||
return args.Get(0).(*dockerclient.ContainerInfo), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) InspectImage(id string) (*dockerclient.ImageInfo, error) {
|
||||
args := client.Mock.Called(id)
|
||||
return args.Get(0).(*dockerclient.ImageInfo), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) CreateContainer(config *dockerclient.ContainerConfig, name string) (string, error) {
|
||||
args := client.Mock.Called(config, name)
|
||||
return args.String(0), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) ContainerLogs(id string, options *dockerclient.LogOptions) (io.ReadCloser, error) {
|
||||
args := client.Mock.Called(id, options)
|
||||
return args.Get(0).(io.ReadCloser), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) ContainerChanges(id string) ([]*dockerclient.ContainerChanges, error) {
|
||||
args := client.Mock.Called(id)
|
||||
return args.Get(0).([]*dockerclient.ContainerChanges), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) StartContainer(id string, config *dockerclient.HostConfig) error {
|
||||
args := client.Mock.Called(id, config)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) StopContainer(id string, timeout int) error {
|
||||
args := client.Mock.Called(id, timeout)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) RestartContainer(id string, timeout int) error {
|
||||
args := client.Mock.Called(id, timeout)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) KillContainer(id, signal string) error {
|
||||
args := client.Mock.Called(id, signal)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) Wait(id string) <-chan dockerclient.WaitResult {
|
||||
args := client.Mock.Called(id)
|
||||
return args.Get(0).(<-chan dockerclient.WaitResult)
|
||||
}
|
||||
|
||||
func (client *MockClient) MonitorEvents(options *dockerclient.MonitorEventsOptions, stopChan <-chan struct{}) (<-chan dockerclient.EventOrError, error) {
|
||||
args := client.Mock.Called(options, stopChan)
|
||||
return args.Get(0).(<-chan dockerclient.EventOrError), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) StartMonitorEvents(cb dockerclient.Callback, ec chan error, args ...interface{}) {
|
||||
client.Mock.Called(cb, ec, args)
|
||||
}
|
||||
|
||||
func (client *MockClient) StopAllMonitorEvents() {
|
||||
client.Mock.Called()
|
||||
}
|
||||
|
||||
func (client *MockClient) TagImage(nameOrID string, repo string, tag string, force bool) error {
|
||||
args := client.Mock.Called(nameOrID, repo, tag, force)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) StartMonitorStats(id string, cb dockerclient.StatCallback, ec chan error, args ...interface{}) {
|
||||
client.Mock.Called(id, cb, ec, args)
|
||||
}
|
||||
|
||||
func (client *MockClient) StopAllMonitorStats() {
|
||||
client.Mock.Called()
|
||||
}
|
||||
|
||||
func (client *MockClient) Version() (*dockerclient.Version, error) {
|
||||
args := client.Mock.Called()
|
||||
return args.Get(0).(*dockerclient.Version), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) PullImage(name string, auth *dockerclient.AuthConfig) error {
|
||||
args := client.Mock.Called(name, auth)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) LoadImage(reader io.Reader) error {
|
||||
args := client.Mock.Called(reader)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) RemoveContainer(id string, force, volumes bool) error {
|
||||
args := client.Mock.Called(id, force, volumes)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) ListImages(all bool) ([]*dockerclient.Image, error) {
|
||||
args := client.Mock.Called(all)
|
||||
return args.Get(0).([]*dockerclient.Image), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) RemoveImage(name string) ([]*dockerclient.ImageDelete, error) {
|
||||
args := client.Mock.Called(name)
|
||||
return args.Get(0).([]*dockerclient.ImageDelete), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) PauseContainer(name string) error {
|
||||
args := client.Mock.Called(name)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) UnpauseContainer(name string) error {
|
||||
args := client.Mock.Called(name)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) Exec(config *dockerclient.ExecConfig) (string, error) {
|
||||
args := client.Mock.Called(config)
|
||||
return args.String(0), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) RenameContainer(oldName string, newName string) error {
|
||||
args := client.Mock.Called(oldName, newName)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) ImportImage(source string, repository string, tag string, tar io.Reader) (io.ReadCloser, error) {
|
||||
args := client.Mock.Called(source, repository, tag, tar)
|
||||
return args.Get(0).(io.ReadCloser), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) BuildImage(image *dockerclient.BuildImage) (io.ReadCloser, error) {
|
||||
args := client.Mock.Called(image)
|
||||
return args.Get(0).(io.ReadCloser), args.Error(1)
|
||||
}
|
32
vendor/github.com/samalba/dockerclient/mockclient/mock_test.go
generated
vendored
32
vendor/github.com/samalba/dockerclient/mockclient/mock_test.go
generated
vendored
@ -1,32 +0,0 @@
|
||||
package mockclient
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/samalba/dockerclient"
|
||||
)
|
||||
|
||||
func TestMock(t *testing.T) {
|
||||
mock := NewMockClient()
|
||||
mock.On("Version").Return(&dockerclient.Version{Version: "foo"}, nil).Once()
|
||||
|
||||
v, err := mock.Version()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if v.Version != "foo" {
|
||||
t.Fatal(v)
|
||||
}
|
||||
|
||||
mock.Mock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestMockInterface(t *testing.T) {
|
||||
iface := reflect.TypeOf((*dockerclient.Client)(nil)).Elem()
|
||||
mock := NewMockClient()
|
||||
|
||||
if !reflect.TypeOf(mock).Implements(iface) {
|
||||
t.Fatalf("Mock does not implement the Client interface")
|
||||
}
|
||||
}
|
200
vendor/github.com/samalba/dockerclient/types.go
generated
vendored
200
vendor/github.com/samalba/dockerclient/types.go
generated
vendored
@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/units"
|
||||
"github.com/docker/go-units"
|
||||
)
|
||||
|
||||
type ContainerConfig struct {
|
||||
@ -23,13 +23,16 @@ type ContainerConfig struct {
|
||||
Cmd []string
|
||||
Image string
|
||||
Volumes map[string]struct{}
|
||||
VolumeDriver string
|
||||
WorkingDir string
|
||||
Entrypoint []string
|
||||
NetworkDisabled bool
|
||||
MacAddress string
|
||||
OnBuild []string
|
||||
Labels map[string]string
|
||||
StopSignal string
|
||||
|
||||
// FIXME: VolumeDriver have been removed since docker 1.9
|
||||
VolumeDriver string
|
||||
|
||||
// FIXME: The following fields have been removed since API v1.18
|
||||
Memory int64
|
||||
@ -43,39 +46,46 @@ type ContainerConfig struct {
|
||||
}
|
||||
|
||||
type HostConfig struct {
|
||||
Binds []string
|
||||
ContainerIDFile string
|
||||
LxcConf []map[string]string
|
||||
Memory int64
|
||||
MemorySwap int64
|
||||
CpuShares int64
|
||||
CpuPeriod int64
|
||||
CpusetCpus string
|
||||
CpusetMems string
|
||||
CpuQuota int64
|
||||
BlkioWeight int64
|
||||
OomKillDisable bool
|
||||
Privileged bool
|
||||
PortBindings map[string][]PortBinding
|
||||
Links []string
|
||||
PublishAllPorts bool
|
||||
Dns []string
|
||||
DnsSearch []string
|
||||
ExtraHosts []string
|
||||
VolumesFrom []string
|
||||
Devices []DeviceMapping
|
||||
NetworkMode string
|
||||
IpcMode string
|
||||
PidMode string
|
||||
UTSMode string
|
||||
CapAdd []string
|
||||
CapDrop []string
|
||||
RestartPolicy RestartPolicy
|
||||
SecurityOpt []string
|
||||
ReadonlyRootfs bool
|
||||
Ulimits []Ulimit
|
||||
LogConfig LogConfig
|
||||
CgroupParent string
|
||||
Binds []string
|
||||
ContainerIDFile string
|
||||
LxcConf []map[string]string
|
||||
Memory int64
|
||||
MemoryReservation int64
|
||||
MemorySwap int64
|
||||
KernelMemory int64
|
||||
CpuShares int64
|
||||
CpuPeriod int64
|
||||
CpusetCpus string
|
||||
CpusetMems string
|
||||
CpuQuota int64
|
||||
BlkioWeight int64
|
||||
OomKillDisable bool
|
||||
MemorySwappiness int64
|
||||
Privileged bool
|
||||
PortBindings map[string][]PortBinding
|
||||
Links []string
|
||||
PublishAllPorts bool
|
||||
Dns []string
|
||||
DNSOptions []string
|
||||
DnsSearch []string
|
||||
ExtraHosts []string
|
||||
VolumesFrom []string
|
||||
Devices []DeviceMapping
|
||||
NetworkMode string
|
||||
IpcMode string
|
||||
PidMode string
|
||||
UTSMode string
|
||||
CapAdd []string
|
||||
CapDrop []string
|
||||
GroupAdd []string
|
||||
RestartPolicy RestartPolicy
|
||||
SecurityOpt []string
|
||||
ReadonlyRootfs bool
|
||||
Ulimits []Ulimit
|
||||
LogConfig LogConfig
|
||||
CgroupParent string
|
||||
ConsoleSize [2]int
|
||||
VolumeDriver string
|
||||
}
|
||||
|
||||
type DeviceMapping struct {
|
||||
@ -102,6 +112,14 @@ type LogOptions struct {
|
||||
Tail int64
|
||||
}
|
||||
|
||||
type AttachOptions struct {
|
||||
Logs bool
|
||||
Stream bool
|
||||
Stdin bool
|
||||
Stdout bool
|
||||
Stderr bool
|
||||
}
|
||||
|
||||
type MonitorEventsFilters struct {
|
||||
Event string `json:",omitempty"`
|
||||
Image string `json:",omitempty"`
|
||||
@ -234,17 +252,31 @@ type Port struct {
|
||||
Type string
|
||||
}
|
||||
|
||||
type EndpointSettings struct {
|
||||
EndpointID string
|
||||
Gateway string
|
||||
IPAddress string
|
||||
IPPrefixLen int
|
||||
IPv6Gateway string
|
||||
GlobalIPv6Address string
|
||||
GlobalIPv6PrefixLen int
|
||||
MacAddress string
|
||||
}
|
||||
|
||||
type Container struct {
|
||||
Id string
|
||||
Names []string
|
||||
Image string
|
||||
Command string
|
||||
Created int64
|
||||
Status string
|
||||
Ports []Port
|
||||
SizeRw int64
|
||||
SizeRootFs int64
|
||||
Labels map[string]string
|
||||
Id string
|
||||
Names []string
|
||||
Image string
|
||||
Command string
|
||||
Created int64
|
||||
Status string
|
||||
Ports []Port
|
||||
SizeRw int64
|
||||
SizeRootFs int64
|
||||
Labels map[string]string
|
||||
NetworkSettings struct {
|
||||
Networks map[string]EndpointSettings
|
||||
}
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
@ -272,7 +304,9 @@ type RespContainersCreate struct {
|
||||
type Image struct {
|
||||
Created int64
|
||||
Id string
|
||||
Labels map[string]string
|
||||
ParentId string
|
||||
RepoDigests []string
|
||||
RepoTags []string
|
||||
Size int64
|
||||
VirtualSize int64
|
||||
@ -441,4 +475,80 @@ type BuildImage struct {
|
||||
CpuSetCpus string
|
||||
CpuSetMems string
|
||||
CgroupParent string
|
||||
BuildArgs map[string]string
|
||||
}
|
||||
|
||||
type Volume struct {
|
||||
Name string // Name is the name of the volume
|
||||
Driver string // Driver is the Driver name used to create the volume
|
||||
Mountpoint string // Mountpoint is the location on disk of the volume
|
||||
}
|
||||
|
||||
type VolumesListResponse struct {
|
||||
Volumes []*Volume // Volumes is the list of volumes being returned
|
||||
}
|
||||
|
||||
type VolumeCreateRequest struct {
|
||||
Name string // Name is the requested name of the volume
|
||||
Driver string // Driver is the name of the driver that should be used to create the volume
|
||||
DriverOpts map[string]string // DriverOpts holds the driver specific options to use for when creating the volume.
|
||||
}
|
||||
|
||||
// IPAM represents IP Address Management
|
||||
type IPAM struct {
|
||||
Driver string
|
||||
Config []IPAMConfig
|
||||
}
|
||||
|
||||
// IPAMConfig represents IPAM configurations
|
||||
type IPAMConfig struct {
|
||||
Subnet string `json:",omitempty"`
|
||||
IPRange string `json:",omitempty"`
|
||||
Gateway string `json:",omitempty"`
|
||||
AuxAddress map[string]string `json:"AuxiliaryAddresses,omitempty"`
|
||||
}
|
||||
|
||||
// NetworkResource is the body of the "get network" http response message
|
||||
type NetworkResource struct {
|
||||
Name string
|
||||
ID string `json:"Id"`
|
||||
Scope string
|
||||
Driver string
|
||||
IPAM IPAM
|
||||
Containers map[string]EndpointResource
|
||||
Options map[string]string
|
||||
}
|
||||
|
||||
// EndpointResource contains network resources allocated and used for a container in a network
|
||||
type EndpointResource struct {
|
||||
Name string
|
||||
EndpointID string
|
||||
MacAddress string
|
||||
IPv4Address string
|
||||
IPv6Address string
|
||||
}
|
||||
|
||||
// NetworkCreate is the expected body of the "create network" http request message
|
||||
type NetworkCreate struct {
|
||||
Name string
|
||||
CheckDuplicate bool
|
||||
Driver string
|
||||
IPAM IPAM
|
||||
Options map[string]string
|
||||
}
|
||||
|
||||
// NetworkCreateResponse is the response message sent by the server for network create call
|
||||
type NetworkCreateResponse struct {
|
||||
ID string `json:"Id"`
|
||||
Warning string
|
||||
}
|
||||
|
||||
// NetworkConnect represents the data to be used to connect a container to the network
|
||||
type NetworkConnect struct {
|
||||
Container string
|
||||
}
|
||||
|
||||
// NetworkDisconnect represents the data to be used to disconnect a container from the network
|
||||
type NetworkDisconnect struct {
|
||||
Container string
|
||||
}
|
||||
|
21
vendor/github.com/shiena/ansicolor/LICENSE
generated
vendored
21
vendor/github.com/shiena/ansicolor/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) [2014] [shiena]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
100
vendor/github.com/shiena/ansicolor/README.md
generated
vendored
100
vendor/github.com/shiena/ansicolor/README.md
generated
vendored
@ -1,100 +0,0 @@
|
||||
[](https://godoc.org/github.com/shiena/ansicolor)
|
||||
|
||||
# ansicolor
|
||||
|
||||
Ansicolor library provides color console in Windows as ANSICON for Golang.
|
||||
|
||||
## Features
|
||||
|
||||
|Escape sequence|Text attributes|
|
||||
|---------------|----|
|
||||
|\x1b[0m|All attributes off(color at startup)|
|
||||
|\x1b[1m|Bold on(enable foreground intensity)|
|
||||
|\x1b[4m|Underline on|
|
||||
|\x1b[5m|Blink on(enable background intensity)|
|
||||
|\x1b[21m|Bold off(disable foreground intensity)|
|
||||
|\x1b[24m|Underline off|
|
||||
|\x1b[25m|Blink off(disable background intensity)|
|
||||
|
||||
|Escape sequence|Foreground colors|
|
||||
|---------------|----|
|
||||
|\x1b[30m|Black|
|
||||
|\x1b[31m|Red|
|
||||
|\x1b[32m|Green|
|
||||
|\x1b[33m|Yellow|
|
||||
|\x1b[34m|Blue|
|
||||
|\x1b[35m|Magenta|
|
||||
|\x1b[36m|Cyan|
|
||||
|\x1b[37m|White|
|
||||
|\x1b[39m|Default(foreground color at startup)|
|
||||
|\x1b[90m|Light Gray|
|
||||
|\x1b[91m|Light Red|
|
||||
|\x1b[92m|Light Green|
|
||||
|\x1b[93m|Light Yellow|
|
||||
|\x1b[94m|Light Blue|
|
||||
|\x1b[95m|Light Magenta|
|
||||
|\x1b[96m|Light Cyan|
|
||||
|\x1b[97m|Light White|
|
||||
|
||||
|Escape sequence|Background colors|
|
||||
|---------------|----|
|
||||
|\x1b[40m|Black|
|
||||
|\x1b[41m|Red|
|
||||
|\x1b[42m|Green|
|
||||
|\x1b[43m|Yellow|
|
||||
|\x1b[44m|Blue|
|
||||
|\x1b[45m|Magenta|
|
||||
|\x1b[46m|Cyan|
|
||||
|\x1b[47m|White|
|
||||
|\x1b[49m|Default(background color at startup)|
|
||||
|\x1b[100m|Light Gray|
|
||||
|\x1b[101m|Light Red|
|
||||
|\x1b[102m|Light Green|
|
||||
|\x1b[103m|Light Yellow|
|
||||
|\x1b[104m|Light Blue|
|
||||
|\x1b[105m|Light Magenta|
|
||||
|\x1b[106m|Light Cyan|
|
||||
|\x1b[107m|Light White|
|
||||
|
||||
## Example
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
w := ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||
text := "%sforeground %sbold%s %sbackground%s\n"
|
||||
fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[21m", "\x1b[41;32m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[21m", "\x1b[42;31m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[21m", "\x1b[43;34m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[21m", "\x1b[44;33m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[21m", "\x1b[45;36m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[21m", "\x1b[46;35m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[21m", "\x1b[47;30m", "\x1b[0m")
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
## See also:
|
||||
|
||||
- https://github.com/daviddengcn/go-colortext
|
||||
- https://github.com/adoxa/ansicon
|
||||
- https://github.com/aslakhellesoy/wac
|
||||
- https://github.com/wsxiaoys/terminal
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork it
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
4. Push to the branch (`git push origin my-new-feature`)
|
||||
5. Create new Pull Request
|
||||
|
42
vendor/github.com/shiena/ansicolor/ansicolor.go
generated
vendored
42
vendor/github.com/shiena/ansicolor/ansicolor.go
generated
vendored
@ -1,42 +0,0 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package ansicolor provides color console in Windows as ANSICON.
|
||||
package ansicolor
|
||||
|
||||
import "io"
|
||||
|
||||
type outputMode int
|
||||
|
||||
// DiscardNonColorEscSeq supports the divided color escape sequence.
|
||||
// But non-color escape sequence is not output.
|
||||
// Please use the OutputNonColorEscSeq If you want to output a non-color
|
||||
// escape sequences such as ncurses. However, it does not support the divided
|
||||
// color escape sequence.
|
||||
const (
|
||||
_ outputMode = iota
|
||||
DiscardNonColorEscSeq
|
||||
OutputNonColorEscSeq
|
||||
)
|
||||
|
||||
// NewAnsiColorWriter creates and initializes a new ansiColorWriter
|
||||
// using io.Writer w as its initial contents.
|
||||
// In the console of Windows, which change the foreground and background
|
||||
// colors of the text by the escape sequence.
|
||||
// In the console of other systems, which writes to w all text.
|
||||
func NewAnsiColorWriter(w io.Writer) io.Writer {
|
||||
return NewModeAnsiColorWriter(w, DiscardNonColorEscSeq)
|
||||
}
|
||||
|
||||
// NewModeAnsiColorWriter create and initializes a new ansiColorWriter
|
||||
// by specifying the outputMode.
|
||||
func NewModeAnsiColorWriter(w io.Writer, mode outputMode) io.Writer {
|
||||
if _, ok := w.(*ansiColorWriter); !ok {
|
||||
return &ansiColorWriter{
|
||||
w: w,
|
||||
mode: mode,
|
||||
}
|
||||
}
|
||||
return w
|
||||
}
|
27
vendor/github.com/shiena/ansicolor/ansicolor/main.go
generated
vendored
27
vendor/github.com/shiena/ansicolor/ansicolor/main.go
generated
vendored
@ -1,27 +0,0 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
|
||||
The ansicolor command colors a console text by ANSI escape sequence like wac.
|
||||
|
||||
$ go get github.com/shiena/ansicolor/ansicolor
|
||||
|
||||
See also:
|
||||
https://github.com/aslakhellesoy/wac
|
||||
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
w := ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||
io.Copy(w, os.Stdin)
|
||||
}
|
18
vendor/github.com/shiena/ansicolor/ansicolor_ansi.go
generated
vendored
18
vendor/github.com/shiena/ansicolor/ansicolor_ansi.go
generated
vendored
@ -1,18 +0,0 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !windows
|
||||
|
||||
package ansicolor
|
||||
|
||||
import "io"
|
||||
|
||||
type ansiColorWriter struct {
|
||||
w io.Writer
|
||||
mode outputMode
|
||||
}
|
||||
|
||||
func (cw *ansiColorWriter) Write(p []byte) (int, error) {
|
||||
return cw.w.Write(p)
|
||||
}
|
29
vendor/github.com/shiena/ansicolor/ansicolor_test.go
generated
vendored
29
vendor/github.com/shiena/ansicolor/ansicolor_test.go
generated
vendored
@ -1,29 +0,0 @@
|
||||
// Copyright 2015 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ansicolor_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
func TestNewAnsiColor1(t *testing.T) {
|
||||
inner := bytes.NewBufferString("")
|
||||
w := ansicolor.NewAnsiColorWriter(inner)
|
||||
if w == inner {
|
||||
t.Errorf("Get %#v, want %#v", w, inner)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewAnsiColor2(t *testing.T) {
|
||||
inner := bytes.NewBufferString("")
|
||||
w1 := ansicolor.NewAnsiColorWriter(inner)
|
||||
w2 := ansicolor.NewAnsiColorWriter(w1)
|
||||
if w1 != w2 {
|
||||
t.Errorf("Get %#v, want %#v", w1, w2)
|
||||
}
|
||||
}
|
417
vendor/github.com/shiena/ansicolor/ansicolor_windows.go
generated
vendored
417
vendor/github.com/shiena/ansicolor/ansicolor_windows.go
generated
vendored
@ -1,417 +0,0 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package ansicolor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type csiState int
|
||||
|
||||
const (
|
||||
outsideCsiCode csiState = iota
|
||||
firstCsiCode
|
||||
secondCsiCode
|
||||
)
|
||||
|
||||
type parseResult int
|
||||
|
||||
const (
|
||||
noConsole parseResult = iota
|
||||
changedColor
|
||||
unknown
|
||||
)
|
||||
|
||||
type ansiColorWriter struct {
|
||||
w io.Writer
|
||||
mode outputMode
|
||||
state csiState
|
||||
paramStartBuf bytes.Buffer
|
||||
paramBuf bytes.Buffer
|
||||
}
|
||||
|
||||
const (
|
||||
firstCsiChar byte = '\x1b'
|
||||
secondeCsiChar byte = '['
|
||||
separatorChar byte = ';'
|
||||
sgrCode byte = 'm'
|
||||
)
|
||||
|
||||
const (
|
||||
foregroundBlue = uint16(0x0001)
|
||||
foregroundGreen = uint16(0x0002)
|
||||
foregroundRed = uint16(0x0004)
|
||||
foregroundIntensity = uint16(0x0008)
|
||||
backgroundBlue = uint16(0x0010)
|
||||
backgroundGreen = uint16(0x0020)
|
||||
backgroundRed = uint16(0x0040)
|
||||
backgroundIntensity = uint16(0x0080)
|
||||
underscore = uint16(0x8000)
|
||||
|
||||
foregroundMask = foregroundBlue | foregroundGreen | foregroundRed | foregroundIntensity
|
||||
backgroundMask = backgroundBlue | backgroundGreen | backgroundRed | backgroundIntensity
|
||||
)
|
||||
|
||||
const (
|
||||
ansiReset = "0"
|
||||
ansiIntensityOn = "1"
|
||||
ansiIntensityOff = "21"
|
||||
ansiUnderlineOn = "4"
|
||||
ansiUnderlineOff = "24"
|
||||
ansiBlinkOn = "5"
|
||||
ansiBlinkOff = "25"
|
||||
|
||||
ansiForegroundBlack = "30"
|
||||
ansiForegroundRed = "31"
|
||||
ansiForegroundGreen = "32"
|
||||
ansiForegroundYellow = "33"
|
||||
ansiForegroundBlue = "34"
|
||||
ansiForegroundMagenta = "35"
|
||||
ansiForegroundCyan = "36"
|
||||
ansiForegroundWhite = "37"
|
||||
ansiForegroundDefault = "39"
|
||||
|
||||
ansiBackgroundBlack = "40"
|
||||
ansiBackgroundRed = "41"
|
||||
ansiBackgroundGreen = "42"
|
||||
ansiBackgroundYellow = "43"
|
||||
ansiBackgroundBlue = "44"
|
||||
ansiBackgroundMagenta = "45"
|
||||
ansiBackgroundCyan = "46"
|
||||
ansiBackgroundWhite = "47"
|
||||
ansiBackgroundDefault = "49"
|
||||
|
||||
ansiLightForegroundGray = "90"
|
||||
ansiLightForegroundRed = "91"
|
||||
ansiLightForegroundGreen = "92"
|
||||
ansiLightForegroundYellow = "93"
|
||||
ansiLightForegroundBlue = "94"
|
||||
ansiLightForegroundMagenta = "95"
|
||||
ansiLightForegroundCyan = "96"
|
||||
ansiLightForegroundWhite = "97"
|
||||
|
||||
ansiLightBackgroundGray = "100"
|
||||
ansiLightBackgroundRed = "101"
|
||||
ansiLightBackgroundGreen = "102"
|
||||
ansiLightBackgroundYellow = "103"
|
||||
ansiLightBackgroundBlue = "104"
|
||||
ansiLightBackgroundMagenta = "105"
|
||||
ansiLightBackgroundCyan = "106"
|
||||
ansiLightBackgroundWhite = "107"
|
||||
)
|
||||
|
||||
type drawType int
|
||||
|
||||
const (
|
||||
foreground drawType = iota
|
||||
background
|
||||
)
|
||||
|
||||
type winColor struct {
|
||||
code uint16
|
||||
drawType drawType
|
||||
}
|
||||
|
||||
var colorMap = map[string]winColor{
|
||||
ansiForegroundBlack: {0, foreground},
|
||||
ansiForegroundRed: {foregroundRed, foreground},
|
||||
ansiForegroundGreen: {foregroundGreen, foreground},
|
||||
ansiForegroundYellow: {foregroundRed | foregroundGreen, foreground},
|
||||
ansiForegroundBlue: {foregroundBlue, foreground},
|
||||
ansiForegroundMagenta: {foregroundRed | foregroundBlue, foreground},
|
||||
ansiForegroundCyan: {foregroundGreen | foregroundBlue, foreground},
|
||||
ansiForegroundWhite: {foregroundRed | foregroundGreen | foregroundBlue, foreground},
|
||||
ansiForegroundDefault: {foregroundRed | foregroundGreen | foregroundBlue, foreground},
|
||||
|
||||
ansiBackgroundBlack: {0, background},
|
||||
ansiBackgroundRed: {backgroundRed, background},
|
||||
ansiBackgroundGreen: {backgroundGreen, background},
|
||||
ansiBackgroundYellow: {backgroundRed | backgroundGreen, background},
|
||||
ansiBackgroundBlue: {backgroundBlue, background},
|
||||
ansiBackgroundMagenta: {backgroundRed | backgroundBlue, background},
|
||||
ansiBackgroundCyan: {backgroundGreen | backgroundBlue, background},
|
||||
ansiBackgroundWhite: {backgroundRed | backgroundGreen | backgroundBlue, background},
|
||||
ansiBackgroundDefault: {0, background},
|
||||
|
||||
ansiLightForegroundGray: {foregroundIntensity, foreground},
|
||||
ansiLightForegroundRed: {foregroundIntensity | foregroundRed, foreground},
|
||||
ansiLightForegroundGreen: {foregroundIntensity | foregroundGreen, foreground},
|
||||
ansiLightForegroundYellow: {foregroundIntensity | foregroundRed | foregroundGreen, foreground},
|
||||
ansiLightForegroundBlue: {foregroundIntensity | foregroundBlue, foreground},
|
||||
ansiLightForegroundMagenta: {foregroundIntensity | foregroundRed | foregroundBlue, foreground},
|
||||
ansiLightForegroundCyan: {foregroundIntensity | foregroundGreen | foregroundBlue, foreground},
|
||||
ansiLightForegroundWhite: {foregroundIntensity | foregroundRed | foregroundGreen | foregroundBlue, foreground},
|
||||
|
||||
ansiLightBackgroundGray: {backgroundIntensity, background},
|
||||
ansiLightBackgroundRed: {backgroundIntensity | backgroundRed, background},
|
||||
ansiLightBackgroundGreen: {backgroundIntensity | backgroundGreen, background},
|
||||
ansiLightBackgroundYellow: {backgroundIntensity | backgroundRed | backgroundGreen, background},
|
||||
ansiLightBackgroundBlue: {backgroundIntensity | backgroundBlue, background},
|
||||
ansiLightBackgroundMagenta: {backgroundIntensity | backgroundRed | backgroundBlue, background},
|
||||
ansiLightBackgroundCyan: {backgroundIntensity | backgroundGreen | backgroundBlue, background},
|
||||
ansiLightBackgroundWhite: {backgroundIntensity | backgroundRed | backgroundGreen | backgroundBlue, background},
|
||||
}
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
|
||||
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||
defaultAttr *textAttributes
|
||||
)
|
||||
|
||||
func init() {
|
||||
screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||
if screenInfo != nil {
|
||||
colorMap[ansiForegroundDefault] = winColor{
|
||||
screenInfo.WAttributes & (foregroundRed | foregroundGreen | foregroundBlue),
|
||||
foreground,
|
||||
}
|
||||
colorMap[ansiBackgroundDefault] = winColor{
|
||||
screenInfo.WAttributes & (backgroundRed | backgroundGreen | backgroundBlue),
|
||||
background,
|
||||
}
|
||||
defaultAttr = convertTextAttr(screenInfo.WAttributes)
|
||||
}
|
||||
}
|
||||
|
||||
type coord struct {
|
||||
X, Y int16
|
||||
}
|
||||
|
||||
type smallRect struct {
|
||||
Left, Top, Right, Bottom int16
|
||||
}
|
||||
|
||||
type consoleScreenBufferInfo struct {
|
||||
DwSize coord
|
||||
DwCursorPosition coord
|
||||
WAttributes uint16
|
||||
SrWindow smallRect
|
||||
DwMaximumWindowSize coord
|
||||
}
|
||||
|
||||
func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *consoleScreenBufferInfo {
|
||||
var csbi consoleScreenBufferInfo
|
||||
ret, _, _ := procGetConsoleScreenBufferInfo.Call(
|
||||
hConsoleOutput,
|
||||
uintptr(unsafe.Pointer(&csbi)))
|
||||
if ret == 0 {
|
||||
return nil
|
||||
}
|
||||
return &csbi
|
||||
}
|
||||
|
||||
func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool {
|
||||
ret, _, _ := procSetConsoleTextAttribute.Call(
|
||||
hConsoleOutput,
|
||||
uintptr(wAttributes))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
type textAttributes struct {
|
||||
foregroundColor uint16
|
||||
backgroundColor uint16
|
||||
foregroundIntensity uint16
|
||||
backgroundIntensity uint16
|
||||
underscore uint16
|
||||
otherAttributes uint16
|
||||
}
|
||||
|
||||
func convertTextAttr(winAttr uint16) *textAttributes {
|
||||
fgColor := winAttr & (foregroundRed | foregroundGreen | foregroundBlue)
|
||||
bgColor := winAttr & (backgroundRed | backgroundGreen | backgroundBlue)
|
||||
fgIntensity := winAttr & foregroundIntensity
|
||||
bgIntensity := winAttr & backgroundIntensity
|
||||
underline := winAttr & underscore
|
||||
otherAttributes := winAttr &^ (foregroundMask | backgroundMask | underscore)
|
||||
return &textAttributes{fgColor, bgColor, fgIntensity, bgIntensity, underline, otherAttributes}
|
||||
}
|
||||
|
||||
func convertWinAttr(textAttr *textAttributes) uint16 {
|
||||
var winAttr uint16
|
||||
winAttr |= textAttr.foregroundColor
|
||||
winAttr |= textAttr.backgroundColor
|
||||
winAttr |= textAttr.foregroundIntensity
|
||||
winAttr |= textAttr.backgroundIntensity
|
||||
winAttr |= textAttr.underscore
|
||||
winAttr |= textAttr.otherAttributes
|
||||
return winAttr
|
||||
}
|
||||
|
||||
func changeColor(param []byte) parseResult {
|
||||
screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||
if screenInfo == nil {
|
||||
return noConsole
|
||||
}
|
||||
|
||||
winAttr := convertTextAttr(screenInfo.WAttributes)
|
||||
strParam := string(param)
|
||||
if len(strParam) <= 0 {
|
||||
strParam = "0"
|
||||
}
|
||||
csiParam := strings.Split(strParam, string(separatorChar))
|
||||
for _, p := range csiParam {
|
||||
c, ok := colorMap[p]
|
||||
switch {
|
||||
case !ok:
|
||||
switch p {
|
||||
case ansiReset:
|
||||
winAttr.foregroundColor = defaultAttr.foregroundColor
|
||||
winAttr.backgroundColor = defaultAttr.backgroundColor
|
||||
winAttr.foregroundIntensity = defaultAttr.foregroundIntensity
|
||||
winAttr.backgroundIntensity = defaultAttr.backgroundIntensity
|
||||
winAttr.underscore = 0
|
||||
winAttr.otherAttributes = 0
|
||||
case ansiIntensityOn:
|
||||
winAttr.foregroundIntensity = foregroundIntensity
|
||||
case ansiIntensityOff:
|
||||
winAttr.foregroundIntensity = 0
|
||||
case ansiUnderlineOn:
|
||||
winAttr.underscore = underscore
|
||||
case ansiUnderlineOff:
|
||||
winAttr.underscore = 0
|
||||
case ansiBlinkOn:
|
||||
winAttr.backgroundIntensity = backgroundIntensity
|
||||
case ansiBlinkOff:
|
||||
winAttr.backgroundIntensity = 0
|
||||
default:
|
||||
// unknown code
|
||||
}
|
||||
case c.drawType == foreground:
|
||||
winAttr.foregroundColor = c.code
|
||||
case c.drawType == background:
|
||||
winAttr.backgroundColor = c.code
|
||||
}
|
||||
}
|
||||
winTextAttribute := convertWinAttr(winAttr)
|
||||
setConsoleTextAttribute(uintptr(syscall.Stdout), winTextAttribute)
|
||||
|
||||
return changedColor
|
||||
}
|
||||
|
||||
func parseEscapeSequence(command byte, param []byte) parseResult {
|
||||
if defaultAttr == nil {
|
||||
return noConsole
|
||||
}
|
||||
|
||||
switch command {
|
||||
case sgrCode:
|
||||
return changeColor(param)
|
||||
default:
|
||||
return unknown
|
||||
}
|
||||
}
|
||||
|
||||
func (cw *ansiColorWriter) flushBuffer() (int, error) {
|
||||
return cw.flushTo(cw.w)
|
||||
}
|
||||
|
||||
func (cw *ansiColorWriter) resetBuffer() (int, error) {
|
||||
return cw.flushTo(nil)
|
||||
}
|
||||
|
||||
func (cw *ansiColorWriter) flushTo(w io.Writer) (int, error) {
|
||||
var n1, n2 int
|
||||
var err error
|
||||
|
||||
startBytes := cw.paramStartBuf.Bytes()
|
||||
cw.paramStartBuf.Reset()
|
||||
if w != nil {
|
||||
n1, err = cw.w.Write(startBytes)
|
||||
if err != nil {
|
||||
return n1, err
|
||||
}
|
||||
} else {
|
||||
n1 = len(startBytes)
|
||||
}
|
||||
paramBytes := cw.paramBuf.Bytes()
|
||||
cw.paramBuf.Reset()
|
||||
if w != nil {
|
||||
n2, err = cw.w.Write(paramBytes)
|
||||
if err != nil {
|
||||
return n1 + n2, err
|
||||
}
|
||||
} else {
|
||||
n2 = len(paramBytes)
|
||||
}
|
||||
return n1 + n2, nil
|
||||
}
|
||||
|
||||
func isParameterChar(b byte) bool {
|
||||
return ('0' <= b && b <= '9') || b == separatorChar
|
||||
}
|
||||
|
||||
func (cw *ansiColorWriter) Write(p []byte) (int, error) {
|
||||
r, nw, first, last := 0, 0, 0, 0
|
||||
if cw.mode != DiscardNonColorEscSeq {
|
||||
cw.state = outsideCsiCode
|
||||
cw.resetBuffer()
|
||||
}
|
||||
|
||||
var err error
|
||||
for i, ch := range p {
|
||||
switch cw.state {
|
||||
case outsideCsiCode:
|
||||
if ch == firstCsiChar {
|
||||
cw.paramStartBuf.WriteByte(ch)
|
||||
cw.state = firstCsiCode
|
||||
}
|
||||
case firstCsiCode:
|
||||
switch ch {
|
||||
case firstCsiChar:
|
||||
cw.paramStartBuf.WriteByte(ch)
|
||||
break
|
||||
case secondeCsiChar:
|
||||
cw.paramStartBuf.WriteByte(ch)
|
||||
cw.state = secondCsiCode
|
||||
last = i - 1
|
||||
default:
|
||||
cw.resetBuffer()
|
||||
cw.state = outsideCsiCode
|
||||
}
|
||||
case secondCsiCode:
|
||||
if isParameterChar(ch) {
|
||||
cw.paramBuf.WriteByte(ch)
|
||||
} else {
|
||||
nw, err = cw.w.Write(p[first:last])
|
||||
r += nw
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
first = i + 1
|
||||
result := parseEscapeSequence(ch, cw.paramBuf.Bytes())
|
||||
if result == noConsole || (cw.mode == OutputNonColorEscSeq && result == unknown) {
|
||||
cw.paramBuf.WriteByte(ch)
|
||||
nw, err := cw.flushBuffer()
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
r += nw
|
||||
} else {
|
||||
n, _ := cw.resetBuffer()
|
||||
// Add one more to the size of the buffer for the last ch
|
||||
r += n + 1
|
||||
}
|
||||
|
||||
cw.state = outsideCsiCode
|
||||
}
|
||||
default:
|
||||
cw.state = outsideCsiCode
|
||||
}
|
||||
}
|
||||
|
||||
if cw.mode != DiscardNonColorEscSeq || cw.state == outsideCsiCode {
|
||||
nw, err = cw.w.Write(p[first:len(p)])
|
||||
r += nw
|
||||
}
|
||||
|
||||
return r, err
|
||||
}
|
277
vendor/github.com/shiena/ansicolor/ansicolor_windows_test.go
generated
vendored
277
vendor/github.com/shiena/ansicolor/ansicolor_windows_test.go
generated
vendored
@ -1,277 +0,0 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package ansicolor_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
. "github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
func TestWritePlanText(t *testing.T) {
|
||||
inner := bytes.NewBufferString("")
|
||||
w := ansicolor.NewAnsiColorWriter(inner)
|
||||
expected := "plain text"
|
||||
fmt.Fprintf(w, expected)
|
||||
actual := inner.String()
|
||||
if actual != expected {
|
||||
t.Errorf("Get %q, want %q", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteParseText(t *testing.T) {
|
||||
inner := bytes.NewBufferString("")
|
||||
w := ansicolor.NewAnsiColorWriter(inner)
|
||||
|
||||
inputTail := "\x1b[0mtail text"
|
||||
expectedTail := "tail text"
|
||||
fmt.Fprintf(w, inputTail)
|
||||
actualTail := inner.String()
|
||||
inner.Reset()
|
||||
if actualTail != expectedTail {
|
||||
t.Errorf("Get %q, want %q", actualTail, expectedTail)
|
||||
}
|
||||
|
||||
inputHead := "head text\x1b[0m"
|
||||
expectedHead := "head text"
|
||||
fmt.Fprintf(w, inputHead)
|
||||
actualHead := inner.String()
|
||||
inner.Reset()
|
||||
if actualHead != expectedHead {
|
||||
t.Errorf("Get %q, want %q", actualHead, expectedHead)
|
||||
}
|
||||
|
||||
inputBothEnds := "both ends \x1b[0m text"
|
||||
expectedBothEnds := "both ends text"
|
||||
fmt.Fprintf(w, inputBothEnds)
|
||||
actualBothEnds := inner.String()
|
||||
inner.Reset()
|
||||
if actualBothEnds != expectedBothEnds {
|
||||
t.Errorf("Get %q, want %q", actualBothEnds, expectedBothEnds)
|
||||
}
|
||||
|
||||
inputManyEsc := "\x1b\x1b\x1b\x1b[0m many esc"
|
||||
expectedManyEsc := "\x1b\x1b\x1b many esc"
|
||||
fmt.Fprintf(w, inputManyEsc)
|
||||
actualManyEsc := inner.String()
|
||||
inner.Reset()
|
||||
if actualManyEsc != expectedManyEsc {
|
||||
t.Errorf("Get %q, want %q", actualManyEsc, expectedManyEsc)
|
||||
}
|
||||
|
||||
expectedSplit := "split text"
|
||||
for _, ch := range "split \x1b[0m text" {
|
||||
fmt.Fprintf(w, string(ch))
|
||||
}
|
||||
actualSplit := inner.String()
|
||||
inner.Reset()
|
||||
if actualSplit != expectedSplit {
|
||||
t.Errorf("Get %q, want %q", actualSplit, expectedSplit)
|
||||
}
|
||||
}
|
||||
|
||||
type screenNotFoundError struct {
|
||||
error
|
||||
}
|
||||
|
||||
func writeAnsiColor(expectedText, colorCode string) (actualText string, actualAttributes uint16, err error) {
|
||||
inner := bytes.NewBufferString("")
|
||||
w := ansicolor.NewAnsiColorWriter(inner)
|
||||
fmt.Fprintf(w, "\x1b[%sm%s", colorCode, expectedText)
|
||||
|
||||
actualText = inner.String()
|
||||
screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||
if screenInfo != nil {
|
||||
actualAttributes = screenInfo.WAttributes
|
||||
} else {
|
||||
err = &screenNotFoundError{}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type testParam struct {
|
||||
text string
|
||||
attributes uint16
|
||||
ansiColor string
|
||||
}
|
||||
|
||||
func TestWriteAnsiColorText(t *testing.T) {
|
||||
screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||
if screenInfo == nil {
|
||||
t.Fatal("Could not get ConsoleScreenBufferInfo")
|
||||
}
|
||||
defer ChangeColor(screenInfo.WAttributes)
|
||||
defaultFgColor := screenInfo.WAttributes & uint16(0x0007)
|
||||
defaultBgColor := screenInfo.WAttributes & uint16(0x0070)
|
||||
defaultFgIntensity := screenInfo.WAttributes & uint16(0x0008)
|
||||
defaultBgIntensity := screenInfo.WAttributes & uint16(0x0080)
|
||||
|
||||
fgParam := []testParam{
|
||||
{"foreground black ", uint16(0x0000 | 0x0000), "30"},
|
||||
{"foreground red ", uint16(0x0004 | 0x0000), "31"},
|
||||
{"foreground green ", uint16(0x0002 | 0x0000), "32"},
|
||||
{"foreground yellow ", uint16(0x0006 | 0x0000), "33"},
|
||||
{"foreground blue ", uint16(0x0001 | 0x0000), "34"},
|
||||
{"foreground magenta", uint16(0x0005 | 0x0000), "35"},
|
||||
{"foreground cyan ", uint16(0x0003 | 0x0000), "36"},
|
||||
{"foreground white ", uint16(0x0007 | 0x0000), "37"},
|
||||
{"foreground default", defaultFgColor | 0x0000, "39"},
|
||||
{"foreground light gray ", uint16(0x0000 | 0x0008 | 0x0000), "90"},
|
||||
{"foreground light red ", uint16(0x0004 | 0x0008 | 0x0000), "91"},
|
||||
{"foreground light green ", uint16(0x0002 | 0x0008 | 0x0000), "92"},
|
||||
{"foreground light yellow ", uint16(0x0006 | 0x0008 | 0x0000), "93"},
|
||||
{"foreground light blue ", uint16(0x0001 | 0x0008 | 0x0000), "94"},
|
||||
{"foreground light magenta", uint16(0x0005 | 0x0008 | 0x0000), "95"},
|
||||
{"foreground light cyan ", uint16(0x0003 | 0x0008 | 0x0000), "96"},
|
||||
{"foreground light white ", uint16(0x0007 | 0x0008 | 0x0000), "97"},
|
||||
}
|
||||
|
||||
bgParam := []testParam{
|
||||
{"background black ", uint16(0x0007 | 0x0000), "40"},
|
||||
{"background red ", uint16(0x0007 | 0x0040), "41"},
|
||||
{"background green ", uint16(0x0007 | 0x0020), "42"},
|
||||
{"background yellow ", uint16(0x0007 | 0x0060), "43"},
|
||||
{"background blue ", uint16(0x0007 | 0x0010), "44"},
|
||||
{"background magenta", uint16(0x0007 | 0x0050), "45"},
|
||||
{"background cyan ", uint16(0x0007 | 0x0030), "46"},
|
||||
{"background white ", uint16(0x0007 | 0x0070), "47"},
|
||||
{"background default", uint16(0x0007) | defaultBgColor, "49"},
|
||||
{"background light gray ", uint16(0x0007 | 0x0000 | 0x0080), "100"},
|
||||
{"background light red ", uint16(0x0007 | 0x0040 | 0x0080), "101"},
|
||||
{"background light green ", uint16(0x0007 | 0x0020 | 0x0080), "102"},
|
||||
{"background light yellow ", uint16(0x0007 | 0x0060 | 0x0080), "103"},
|
||||
{"background light blue ", uint16(0x0007 | 0x0010 | 0x0080), "104"},
|
||||
{"background light magenta", uint16(0x0007 | 0x0050 | 0x0080), "105"},
|
||||
{"background light cyan ", uint16(0x0007 | 0x0030 | 0x0080), "106"},
|
||||
{"background light white ", uint16(0x0007 | 0x0070 | 0x0080), "107"},
|
||||
}
|
||||
|
||||
resetParam := []testParam{
|
||||
{"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, "0"},
|
||||
{"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, ""},
|
||||
}
|
||||
|
||||
boldParam := []testParam{
|
||||
{"bold on", uint16(0x0007 | 0x0008), "1"},
|
||||
{"bold off", uint16(0x0007), "21"},
|
||||
}
|
||||
|
||||
underscoreParam := []testParam{
|
||||
{"underscore on", uint16(0x0007 | 0x8000), "4"},
|
||||
{"underscore off", uint16(0x0007), "24"},
|
||||
}
|
||||
|
||||
blinkParam := []testParam{
|
||||
{"blink on", uint16(0x0007 | 0x0080), "5"},
|
||||
{"blink off", uint16(0x0007), "25"},
|
||||
}
|
||||
|
||||
mixedParam := []testParam{
|
||||
{"both black, bold, underline, blink", uint16(0x0000 | 0x0000 | 0x0008 | 0x8000 | 0x0080), "30;40;1;4;5"},
|
||||
{"both red, bold, underline, blink", uint16(0x0004 | 0x0040 | 0x0008 | 0x8000 | 0x0080), "31;41;1;4;5"},
|
||||
{"both green, bold, underline, blink", uint16(0x0002 | 0x0020 | 0x0008 | 0x8000 | 0x0080), "32;42;1;4;5"},
|
||||
{"both yellow, bold, underline, blink", uint16(0x0006 | 0x0060 | 0x0008 | 0x8000 | 0x0080), "33;43;1;4;5"},
|
||||
{"both blue, bold, underline, blink", uint16(0x0001 | 0x0010 | 0x0008 | 0x8000 | 0x0080), "34;44;1;4;5"},
|
||||
{"both magenta, bold, underline, blink", uint16(0x0005 | 0x0050 | 0x0008 | 0x8000 | 0x0080), "35;45;1;4;5"},
|
||||
{"both cyan, bold, underline, blink", uint16(0x0003 | 0x0030 | 0x0008 | 0x8000 | 0x0080), "36;46;1;4;5"},
|
||||
{"both white, bold, underline, blink", uint16(0x0007 | 0x0070 | 0x0008 | 0x8000 | 0x0080), "37;47;1;4;5"},
|
||||
{"both default, bold, underline, blink", uint16(defaultFgColor | defaultBgColor | 0x0008 | 0x8000 | 0x0080), "39;49;1;4;5"},
|
||||
}
|
||||
|
||||
assertTextAttribute := func(expectedText string, expectedAttributes uint16, ansiColor string) {
|
||||
actualText, actualAttributes, err := writeAnsiColor(expectedText, ansiColor)
|
||||
if actualText != expectedText {
|
||||
t.Errorf("Get %q, want %q", actualText, expectedText)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal("Could not get ConsoleScreenBufferInfo")
|
||||
}
|
||||
if actualAttributes != expectedAttributes {
|
||||
t.Errorf("Text: %q, Get 0x%04x, want 0x%04x", expectedText, actualAttributes, expectedAttributes)
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range fgParam {
|
||||
ResetColor()
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
for _, v := range bgParam {
|
||||
ChangeColor(uint16(0x0070 | 0x0007))
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
for _, v := range resetParam {
|
||||
ChangeColor(uint16(0x0000 | 0x0070 | 0x0008))
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
ResetColor()
|
||||
for _, v := range boldParam {
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
ResetColor()
|
||||
for _, v := range underscoreParam {
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
ResetColor()
|
||||
for _, v := range blinkParam {
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
for _, v := range mixedParam {
|
||||
ResetColor()
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIgnoreUnknownSequences(t *testing.T) {
|
||||
inner := bytes.NewBufferString("")
|
||||
w := ansicolor.NewModeAnsiColorWriter(inner, ansicolor.OutputNonColorEscSeq)
|
||||
|
||||
inputText := "\x1b[=decpath mode"
|
||||
expectedTail := inputText
|
||||
fmt.Fprintf(w, inputText)
|
||||
actualTail := inner.String()
|
||||
inner.Reset()
|
||||
if actualTail != expectedTail {
|
||||
t.Errorf("Get %q, want %q", actualTail, expectedTail)
|
||||
}
|
||||
|
||||
inputText = "\x1b[=tailing esc and bracket\x1b["
|
||||
expectedTail = inputText
|
||||
fmt.Fprintf(w, inputText)
|
||||
actualTail = inner.String()
|
||||
inner.Reset()
|
||||
if actualTail != expectedTail {
|
||||
t.Errorf("Get %q, want %q", actualTail, expectedTail)
|
||||
}
|
||||
|
||||
inputText = "\x1b[?tailing esc\x1b"
|
||||
expectedTail = inputText
|
||||
fmt.Fprintf(w, inputText)
|
||||
actualTail = inner.String()
|
||||
inner.Reset()
|
||||
if actualTail != expectedTail {
|
||||
t.Errorf("Get %q, want %q", actualTail, expectedTail)
|
||||
}
|
||||
|
||||
inputText = "\x1b[1h;3punended color code invalid\x1b3"
|
||||
expectedTail = inputText
|
||||
fmt.Fprintf(w, inputText)
|
||||
actualTail = inner.String()
|
||||
inner.Reset()
|
||||
if actualTail != expectedTail {
|
||||
t.Errorf("Get %q, want %q", actualTail, expectedTail)
|
||||
}
|
||||
}
|
24
vendor/github.com/shiena/ansicolor/example_test.go
generated
vendored
24
vendor/github.com/shiena/ansicolor/example_test.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ansicolor_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
func ExampleNewAnsiColorWriter() {
|
||||
w := ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||
text := "%sforeground %sbold%s %sbackground%s\n"
|
||||
fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[21m", "\x1b[41;32m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[21m", "\x1b[42;31m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[21m", "\x1b[43;34m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[21m", "\x1b[44;33m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[21m", "\x1b[45;36m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[21m", "\x1b[46;35m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[21m", "\x1b[47;30m", "\x1b[0m")
|
||||
}
|
19
vendor/github.com/shiena/ansicolor/export_test.go
generated
vendored
19
vendor/github.com/shiena/ansicolor/export_test.go
generated
vendored
@ -1,19 +0,0 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package ansicolor
|
||||
|
||||
import "syscall"
|
||||
|
||||
var GetConsoleScreenBufferInfo = getConsoleScreenBufferInfo
|
||||
|
||||
func ChangeColor(color uint16) {
|
||||
setConsoleTextAttribute(uintptr(syscall.Stdout), color)
|
||||
}
|
||||
|
||||
func ResetColor() {
|
||||
ChangeColor(uint16(0x0007))
|
||||
}
|
10
vendor/github.com/square/go-jose/README.md
generated
vendored
10
vendor/github.com/square/go-jose/README.md
generated
vendored
@ -67,13 +67,15 @@ has a list of constants.
|
||||
|
||||
See below for a table of supported key types. These are understood by the
|
||||
library, and can be passed to corresponding functions such as `NewEncrypter` or
|
||||
`NewSigner`.
|
||||
`NewSigner`. Note that if you are creating a new encrypter or signer with a
|
||||
JsonWebKey, the key id of the JsonWebKey (if present) will be added to any
|
||||
resulting messages.
|
||||
|
||||
Algorithm(s) | Corresponding types
|
||||
:------------------------- | -------------------------------
|
||||
RSA | *[rsa.PublicKey](http://golang.org/pkg/crypto/rsa/#PublicKey), *[rsa.PrivateKey](http://golang.org/pkg/crypto/rsa/#PrivateKey)
|
||||
ECDH, ECDSA | *[ecdsa.PublicKey](http://golang.org/pkg/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](http://golang.org/pkg/crypto/ecdsa/#PrivateKey)
|
||||
AES, HMAC | []byte
|
||||
RSA | *[rsa.PublicKey](http://golang.org/pkg/crypto/rsa/#PublicKey), *[rsa.PrivateKey](http://golang.org/pkg/crypto/rsa/#PrivateKey), *[jose.JsonWebKey](https://godoc.org/github.com/square/go-jose#JsonWebKey)
|
||||
ECDH, ECDSA | *[ecdsa.PublicKey](http://golang.org/pkg/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](http://golang.org/pkg/crypto/ecdsa/#PrivateKey), *[jose.JsonWebKey](https://godoc.org/github.com/square/go-jose#JsonWebKey)
|
||||
AES, HMAC | []byte, *[jose.JsonWebKey](https://godoc.org/github.com/square/go-jose#JsonWebKey)
|
||||
|
||||
## Examples
|
||||
|
||||
|
4
vendor/github.com/square/go-jose/asymmetric.go
generated
vendored
4
vendor/github.com/square/go-jose/asymmetric.go
generated
vendored
@ -252,7 +252,7 @@ func (ctx rsaDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm
|
||||
}
|
||||
|
||||
return Signature{
|
||||
signature: out,
|
||||
Signature: out,
|
||||
protected: &rawHeader{},
|
||||
}, nil
|
||||
}
|
||||
@ -454,7 +454,7 @@ func (ctx ecDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm)
|
||||
out := append(rBytesPadded, sBytesPadded...)
|
||||
|
||||
return Signature{
|
||||
signature: out,
|
||||
Signature: out,
|
||||
protected: &rawHeader{},
|
||||
}, nil
|
||||
}
|
||||
|
431
vendor/github.com/square/go-jose/asymmetric_test.go
generated
vendored
431
vendor/github.com/square/go-jose/asymmetric_test.go
generated
vendored
@ -1,431 +0,0 @@
|
||||
/*-
|
||||
* Copyright 2014 Square Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package jose
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"io"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVectorsRSA(t *testing.T) {
|
||||
// Sources:
|
||||
// http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs-rsa-cryptography-standard.htm
|
||||
// ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt
|
||||
priv := &rsa.PrivateKey{
|
||||
PublicKey: rsa.PublicKey{
|
||||
N: fromHexInt(`
|
||||
a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8
|
||||
ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0c
|
||||
bc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bd
|
||||
bf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93
|
||||
ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb`),
|
||||
E: 65537,
|
||||
},
|
||||
D: fromHexInt(`
|
||||
53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf1195
|
||||
17ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d
|
||||
4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d6
|
||||
5a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb
|
||||
04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1`),
|
||||
Primes: []*big.Int{
|
||||
fromHexInt(`
|
||||
d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262
|
||||
864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c
|
||||
2f26a471dcad212eac7ca39d`),
|
||||
fromHexInt(`
|
||||
cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb3
|
||||
3d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af
|
||||
72bfe9a030e860b0288b5d77`),
|
||||
},
|
||||
}
|
||||
|
||||
input := fromHexBytes(
|
||||
"6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34")
|
||||
|
||||
expectedPKCS := fromHexBytes(`
|
||||
50b4c14136bd198c2f3c3ed243fce036e168d56517984a263cd66492b808
|
||||
04f169d210f2b9bdfb48b12f9ea05009c77da257cc600ccefe3a6283789d
|
||||
8ea0e607ac58e2690ec4ebc10146e8cbaa5ed4d5cce6fe7b0ff9efc1eabb
|
||||
564dbf498285f449ee61dd7b42ee5b5892cb90601f30cda07bf26489310b
|
||||
cd23b528ceab3c31`)
|
||||
|
||||
expectedOAEP := fromHexBytes(`
|
||||
354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad4
|
||||
68fb21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618
|
||||
c21a535fa9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e6
|
||||
57a05a266426d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5
|
||||
210035d47ac72e8a`)
|
||||
|
||||
// Mock random reader
|
||||
randReader = bytes.NewReader(fromHexBytes(`
|
||||
017341ae3875d5f87101f8cc4fa9b9bc156bb04628fccdb2f4f11e905bd3
|
||||
a155d376f593bd7304210874eba08a5e22bcccb4c9d3882a93a54db022f5
|
||||
03d16338b6b7ce16dc7f4bbf9a96b59772d6606e9747c7649bf9e083db98
|
||||
1884a954ab3c6f18b776ea21069d69776a33e96bad48e1dda0a5ef`))
|
||||
defer resetRandReader()
|
||||
|
||||
// RSA-PKCS1v1.5 encrypt
|
||||
enc := new(rsaEncrypterVerifier)
|
||||
enc.publicKey = &priv.PublicKey
|
||||
encryptedPKCS, err := enc.encrypt(input, RSA1_5)
|
||||
if err != nil {
|
||||
t.Error("Encryption failed:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(encryptedPKCS, expectedPKCS) != 0 {
|
||||
t.Error("Output does not match expected value (PKCS1v1.5)")
|
||||
}
|
||||
|
||||
// RSA-OAEP encrypt
|
||||
encryptedOAEP, err := enc.encrypt(input, RSA_OAEP)
|
||||
if err != nil {
|
||||
t.Error("Encryption failed:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(encryptedOAEP, expectedOAEP) != 0 {
|
||||
t.Error("Output does not match expected value (OAEP)")
|
||||
}
|
||||
|
||||
// Need fake cipher for PKCS1v1.5 decrypt
|
||||
resetRandReader()
|
||||
aes := newAESGCM(len(input))
|
||||
|
||||
keygen := randomKeyGenerator{
|
||||
size: aes.keySize(),
|
||||
}
|
||||
|
||||
// RSA-PKCS1v1.5 decrypt
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = priv
|
||||
decryptedPKCS, err := dec.decrypt(encryptedPKCS, RSA1_5, keygen)
|
||||
if err != nil {
|
||||
t.Error("Decryption failed:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(input, decryptedPKCS) != 0 {
|
||||
t.Error("Output does not match expected value (PKCS1v1.5)")
|
||||
}
|
||||
|
||||
// RSA-OAEP decrypt
|
||||
decryptedOAEP, err := dec.decrypt(encryptedOAEP, RSA_OAEP, keygen)
|
||||
if err != nil {
|
||||
t.Error("decryption failed:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(input, decryptedOAEP) != 0 {
|
||||
t.Error("output does not match expected value (OAEP)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidAlgorithmsRSA(t *testing.T) {
|
||||
_, err := newRSARecipient("XYZ", nil)
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
_, err = newRSASigner("XYZ", nil)
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
enc := new(rsaEncrypterVerifier)
|
||||
enc.publicKey = &rsaTestKey.PublicKey
|
||||
_, err = enc.encryptKey([]byte{}, "XYZ")
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
err = enc.verifyPayload([]byte{}, []byte{}, "XYZ")
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = rsaTestKey
|
||||
_, err = dec.decrypt(make([]byte, 256), "XYZ", randomKeyGenerator{size: 16})
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
_, err = dec.signPayload([]byte{}, "XYZ")
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
type failingKeyGenerator struct{}
|
||||
|
||||
func (ctx failingKeyGenerator) keySize() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (ctx failingKeyGenerator) genKey() ([]byte, rawHeader, error) {
|
||||
return nil, rawHeader{}, errors.New("failed to generate key")
|
||||
}
|
||||
|
||||
func TestPKCSKeyGeneratorFailure(t *testing.T) {
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = rsaTestKey
|
||||
generator := failingKeyGenerator{}
|
||||
_, err := dec.decrypt(make([]byte, 256), RSA1_5, generator)
|
||||
if err != ErrCryptoFailure {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidAlgorithmsEC(t *testing.T) {
|
||||
_, err := newECDHRecipient("XYZ", nil)
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
_, err = newECDSASigner("XYZ", nil)
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
enc := new(ecEncrypterVerifier)
|
||||
enc.publicKey = &ecTestKey256.PublicKey
|
||||
_, err = enc.encryptKey([]byte{}, "XYZ")
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidECKeyGen(t *testing.T) {
|
||||
gen := ecKeyGenerator{
|
||||
size: 16,
|
||||
algID: "A128GCM",
|
||||
publicKey: &ecTestKey256.PublicKey,
|
||||
}
|
||||
|
||||
if gen.keySize() != 16 {
|
||||
t.Error("ec key generator reported incorrect key size")
|
||||
}
|
||||
|
||||
_, _, err := gen.genKey()
|
||||
if err != nil {
|
||||
t.Error("ec key generator failed to generate key", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidECDecrypt(t *testing.T) {
|
||||
dec := ecDecrypterSigner{
|
||||
privateKey: ecTestKey256,
|
||||
}
|
||||
|
||||
generator := randomKeyGenerator{size: 16}
|
||||
|
||||
// Missing epk header
|
||||
headers := rawHeader{
|
||||
Alg: string(ECDH_ES),
|
||||
}
|
||||
|
||||
_, err := dec.decryptKey(headers, nil, generator)
|
||||
if err == nil {
|
||||
t.Error("ec decrypter accepted object with missing epk header")
|
||||
}
|
||||
|
||||
// Invalid epk header
|
||||
headers.Epk = &JsonWebKey{}
|
||||
|
||||
_, err = dec.decryptKey(headers, nil, generator)
|
||||
if err == nil {
|
||||
t.Error("ec decrypter accepted object with invalid epk header")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecryptWithIncorrectSize(t *testing.T) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = priv
|
||||
aes := newAESGCM(16)
|
||||
|
||||
keygen := randomKeyGenerator{
|
||||
size: aes.keySize(),
|
||||
}
|
||||
|
||||
payload := make([]byte, 254)
|
||||
_, err = dec.decrypt(payload, RSA1_5, keygen)
|
||||
if err == nil {
|
||||
t.Error("Invalid payload size should return error")
|
||||
}
|
||||
|
||||
payload = make([]byte, 257)
|
||||
_, err = dec.decrypt(payload, RSA1_5, keygen)
|
||||
if err == nil {
|
||||
t.Error("Invalid payload size should return error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPKCSDecryptNeverFails(t *testing.T) {
|
||||
// We don't want RSA-PKCS1 v1.5 decryption to ever fail, in order to prevent
|
||||
// side-channel timing attacks (Bleichenbacher attack in particular).
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = priv
|
||||
aes := newAESGCM(16)
|
||||
|
||||
keygen := randomKeyGenerator{
|
||||
size: aes.keySize(),
|
||||
}
|
||||
|
||||
for i := 1; i < 50; i++ {
|
||||
payload := make([]byte, 256)
|
||||
_, err := io.ReadFull(rand.Reader, payload)
|
||||
if err != nil {
|
||||
t.Error("Unable to get random data:", err)
|
||||
return
|
||||
}
|
||||
_, err = dec.decrypt(payload, RSA1_5, keygen)
|
||||
if err != nil {
|
||||
t.Error("PKCS1v1.5 decrypt should never fail:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPKCSDecryptWithValidPayloads(b *testing.B) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
enc := new(rsaEncrypterVerifier)
|
||||
enc.publicKey = &priv.PublicKey
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = priv
|
||||
aes := newAESGCM(32)
|
||||
|
||||
b.StopTimer()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
plaintext := make([]byte, 32)
|
||||
_, err = io.ReadFull(rand.Reader, plaintext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ciphertext, err := enc.encrypt(plaintext, RSA1_5)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
keygen := randomKeyGenerator{
|
||||
size: aes.keySize(),
|
||||
}
|
||||
|
||||
b.StartTimer()
|
||||
_, err = dec.decrypt(ciphertext, RSA1_5, keygen)
|
||||
b.StopTimer()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPKCSDecryptWithInvalidPayloads(b *testing.B) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
enc := new(rsaEncrypterVerifier)
|
||||
enc.publicKey = &priv.PublicKey
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = priv
|
||||
aes := newAESGCM(16)
|
||||
|
||||
keygen := randomKeyGenerator{
|
||||
size: aes.keySize(),
|
||||
}
|
||||
|
||||
b.StopTimer()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
plaintext := make([]byte, 16)
|
||||
_, err = io.ReadFull(rand.Reader, plaintext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ciphertext, err := enc.encrypt(plaintext, RSA1_5)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Do some simple scrambling
|
||||
ciphertext[128] ^= 0xFF
|
||||
|
||||
b.StartTimer()
|
||||
_, err = dec.decrypt(ciphertext, RSA1_5, keygen)
|
||||
b.StopTimer()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidEllipticCurve(t *testing.T) {
|
||||
signer256 := ecDecrypterSigner{privateKey: ecTestKey256}
|
||||
signer384 := ecDecrypterSigner{privateKey: ecTestKey384}
|
||||
signer521 := ecDecrypterSigner{privateKey: ecTestKey521}
|
||||
|
||||
_, err := signer256.signPayload([]byte{}, ES384)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES384 signature with P-256 key")
|
||||
}
|
||||
_, err = signer256.signPayload([]byte{}, ES512)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES512 signature with P-256 key")
|
||||
}
|
||||
_, err = signer384.signPayload([]byte{}, ES256)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES256 signature with P-384 key")
|
||||
}
|
||||
_, err = signer384.signPayload([]byte{}, ES512)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES512 signature with P-384 key")
|
||||
}
|
||||
_, err = signer521.signPayload([]byte{}, ES256)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES256 signature with P-521 key")
|
||||
}
|
||||
_, err = signer521.signPayload([]byte{}, ES384)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES384 signature with P-521 key")
|
||||
}
|
||||
}
|
498
vendor/github.com/square/go-jose/cipher/cbc_hmac_test.go
generated
vendored
498
vendor/github.com/square/go-jose/cipher/cbc_hmac_test.go
generated
vendored
@ -1,498 +0,0 @@
|
||||
/*-
|
||||
* Copyright 2014 Square Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package josecipher
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInvalidInputs(t *testing.T) {
|
||||
key := []byte{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
}
|
||||
|
||||
nonce := []byte{
|
||||
92, 80, 104, 49, 133, 25, 161, 215, 173, 101, 219, 211, 136, 91, 210, 145}
|
||||
|
||||
aead, _ := NewCBCHMAC(key, aes.NewCipher)
|
||||
ciphertext := aead.Seal(nil, nonce, []byte("plaintext"), []byte("aad"))
|
||||
|
||||
// Changed AAD, must fail
|
||||
_, err := aead.Open(nil, nonce, ciphertext, []byte("INVALID"))
|
||||
if err == nil {
|
||||
t.Error("must detect invalid aad")
|
||||
}
|
||||
|
||||
// Empty ciphertext, must fail
|
||||
_, err = aead.Open(nil, nonce, []byte{}, []byte("aad"))
|
||||
if err == nil {
|
||||
t.Error("must detect invalid/empty ciphertext")
|
||||
}
|
||||
|
||||
// Corrupt ciphertext, must fail
|
||||
corrupt := make([]byte, len(ciphertext))
|
||||
copy(corrupt, ciphertext)
|
||||
corrupt[0] ^= 0xFF
|
||||
|
||||
_, err = aead.Open(nil, nonce, corrupt, []byte("aad"))
|
||||
if err == nil {
|
||||
t.Error("must detect corrupt ciphertext")
|
||||
}
|
||||
|
||||
// Corrupt authtag, must fail
|
||||
copy(corrupt, ciphertext)
|
||||
corrupt[len(ciphertext)-1] ^= 0xFF
|
||||
|
||||
_, err = aead.Open(nil, nonce, corrupt, []byte("aad"))
|
||||
if err == nil {
|
||||
t.Error("must detect corrupt authtag")
|
||||
}
|
||||
|
||||
// Truncated data, must fail
|
||||
_, err = aead.Open(nil, nonce, ciphertext[:10], []byte("aad"))
|
||||
if err == nil {
|
||||
t.Error("must detect corrupt authtag")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVectorsAESCBC128(t *testing.T) {
|
||||
// Source: http://tools.ietf.org/html/draft-ietf-jose-json-web-encryption-29#appendix-A.2
|
||||
plaintext := []byte{
|
||||
76, 105, 118, 101, 32, 108, 111, 110, 103, 32, 97, 110, 100, 32,
|
||||
112, 114, 111, 115, 112, 101, 114, 46}
|
||||
|
||||
aad := []byte{
|
||||
101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 48, 69,
|
||||
120, 88, 122, 85, 105, 76, 67, 74, 108, 98, 109, 77, 105, 79, 105,
|
||||
74, 66, 77, 84, 73, 52, 81, 48, 74, 68, 76, 85, 104, 84, 77, 106, 85,
|
||||
50, 73, 110, 48}
|
||||
|
||||
expectedCiphertext := []byte{
|
||||
40, 57, 83, 181, 119, 33, 133, 148, 198, 185, 243, 24, 152, 230, 6,
|
||||
75, 129, 223, 127, 19, 210, 82, 183, 230, 168, 33, 215, 104, 143,
|
||||
112, 56, 102}
|
||||
|
||||
expectedAuthtag := []byte{
|
||||
246, 17, 244, 190, 4, 95, 98, 3, 231, 0, 115, 157, 242, 203, 100,
|
||||
191}
|
||||
|
||||
key := []byte{
|
||||
4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106, 206,
|
||||
107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156, 44, 207}
|
||||
|
||||
nonce := []byte{
|
||||
3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111, 116, 104, 101}
|
||||
|
||||
enc, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
out := enc.Seal(nil, nonce, plaintext, aad)
|
||||
if err != nil {
|
||||
t.Error("Unable to encrypt:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(out[:len(out)-16], expectedCiphertext) != 0 {
|
||||
t.Error("Ciphertext did not match")
|
||||
}
|
||||
if bytes.Compare(out[len(out)-16:], expectedAuthtag) != 0 {
|
||||
t.Error("Auth tag did not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVectorsAESCBC256(t *testing.T) {
|
||||
// Source: https://tools.ietf.org/html/draft-mcgrew-aead-aes-cbc-hmac-sha2-05#section-5.4
|
||||
plaintext := []byte{
|
||||
0x41, 0x20, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20,
|
||||
0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75,
|
||||
0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x63, 0x72, 0x65,
|
||||
0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62,
|
||||
0x65, 0x20, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x61, 0x6c, 0x6c, 0x20, 0x69,
|
||||
0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x66,
|
||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x65, 0x6d, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f,
|
||||
0x75, 0x74, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x69, 0x65, 0x6e, 0x63, 0x65}
|
||||
|
||||
aad := []byte{
|
||||
0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63,
|
||||
0x69, 0x70, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x65, 0x20,
|
||||
0x4b, 0x65, 0x72, 0x63, 0x6b, 0x68, 0x6f, 0x66, 0x66, 0x73}
|
||||
|
||||
expectedCiphertext := []byte{
|
||||
0x4a, 0xff, 0xaa, 0xad, 0xb7, 0x8c, 0x31, 0xc5, 0xda, 0x4b, 0x1b, 0x59, 0x0d, 0x10, 0xff, 0xbd,
|
||||
0x3d, 0xd8, 0xd5, 0xd3, 0x02, 0x42, 0x35, 0x26, 0x91, 0x2d, 0xa0, 0x37, 0xec, 0xbc, 0xc7, 0xbd,
|
||||
0x82, 0x2c, 0x30, 0x1d, 0xd6, 0x7c, 0x37, 0x3b, 0xcc, 0xb5, 0x84, 0xad, 0x3e, 0x92, 0x79, 0xc2,
|
||||
0xe6, 0xd1, 0x2a, 0x13, 0x74, 0xb7, 0x7f, 0x07, 0x75, 0x53, 0xdf, 0x82, 0x94, 0x10, 0x44, 0x6b,
|
||||
0x36, 0xeb, 0xd9, 0x70, 0x66, 0x29, 0x6a, 0xe6, 0x42, 0x7e, 0xa7, 0x5c, 0x2e, 0x08, 0x46, 0xa1,
|
||||
0x1a, 0x09, 0xcc, 0xf5, 0x37, 0x0d, 0xc8, 0x0b, 0xfe, 0xcb, 0xad, 0x28, 0xc7, 0x3f, 0x09, 0xb3,
|
||||
0xa3, 0xb7, 0x5e, 0x66, 0x2a, 0x25, 0x94, 0x41, 0x0a, 0xe4, 0x96, 0xb2, 0xe2, 0xe6, 0x60, 0x9e,
|
||||
0x31, 0xe6, 0xe0, 0x2c, 0xc8, 0x37, 0xf0, 0x53, 0xd2, 0x1f, 0x37, 0xff, 0x4f, 0x51, 0x95, 0x0b,
|
||||
0xbe, 0x26, 0x38, 0xd0, 0x9d, 0xd7, 0xa4, 0x93, 0x09, 0x30, 0x80, 0x6d, 0x07, 0x03, 0xb1, 0xf6}
|
||||
|
||||
expectedAuthtag := []byte{
|
||||
0x4d, 0xd3, 0xb4, 0xc0, 0x88, 0xa7, 0xf4, 0x5c, 0x21, 0x68, 0x39, 0x64, 0x5b, 0x20, 0x12, 0xbf,
|
||||
0x2e, 0x62, 0x69, 0xa8, 0xc5, 0x6a, 0x81, 0x6d, 0xbc, 0x1b, 0x26, 0x77, 0x61, 0x95, 0x5b, 0xc5}
|
||||
|
||||
key := []byte{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}
|
||||
|
||||
nonce := []byte{
|
||||
0x1a, 0xf3, 0x8c, 0x2d, 0xc2, 0xb9, 0x6f, 0xfd, 0xd8, 0x66, 0x94, 0x09, 0x23, 0x41, 0xbc, 0x04}
|
||||
|
||||
enc, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
out := enc.Seal(nil, nonce, plaintext, aad)
|
||||
if err != nil {
|
||||
t.Error("Unable to encrypt:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(out[:len(out)-32], expectedCiphertext) != 0 {
|
||||
t.Error("Ciphertext did not match, got", out[:len(out)-32], "wanted", expectedCiphertext)
|
||||
}
|
||||
if bytes.Compare(out[len(out)-32:], expectedAuthtag) != 0 {
|
||||
t.Error("Auth tag did not match, got", out[len(out)-32:], "wanted", expectedAuthtag)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAESCBCRoundtrip(t *testing.T) {
|
||||
key128 := []byte{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||
|
||||
key192 := []byte{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7}
|
||||
|
||||
key256 := []byte{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||
|
||||
nonce := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||
|
||||
RunRoundtrip(t, key128, nonce)
|
||||
RunRoundtrip(t, key192, nonce)
|
||||
RunRoundtrip(t, key256, nonce)
|
||||
}
|
||||
|
||||
func RunRoundtrip(t *testing.T, key, nonce []byte) {
|
||||
aead, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if aead.NonceSize() != len(nonce) {
|
||||
panic("invalid nonce")
|
||||
}
|
||||
|
||||
// Test pre-existing data in dst buffer
|
||||
dst := []byte{15, 15, 15, 15}
|
||||
plaintext := []byte{0, 0, 0, 0}
|
||||
aad := []byte{4, 3, 2, 1}
|
||||
|
||||
result := aead.Seal(dst, nonce, plaintext, aad)
|
||||
if bytes.Compare(dst, result[:4]) != 0 {
|
||||
t.Error("Existing data in dst not preserved")
|
||||
}
|
||||
|
||||
// Test pre-existing (empty) dst buffer with sufficient capacity
|
||||
dst = make([]byte, 256)[:0]
|
||||
result, err = aead.Open(dst, nonce, result[4:], aad)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if bytes.Compare(result, plaintext) != 0 {
|
||||
t.Error("Plaintext does not match output")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAESCBCOverhead(t *testing.T) {
|
||||
aead, err := NewCBCHMAC(make([]byte, 32), aes.NewCipher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if aead.Overhead() != 32 {
|
||||
t.Error("CBC-HMAC reports incorrect overhead value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPadding(t *testing.T) {
|
||||
for i := 0; i < 256; i++ {
|
||||
slice := make([]byte, i)
|
||||
padded := padBuffer(slice, 16)
|
||||
if len(padded)%16 != 0 {
|
||||
t.Error("failed to pad slice properly", i)
|
||||
return
|
||||
}
|
||||
unpadded, err := unpadBuffer(padded, 16)
|
||||
if err != nil || len(unpadded) != i {
|
||||
t.Error("failed to unpad slice properly", i)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidKey(t *testing.T) {
|
||||
key := make([]byte, 30)
|
||||
_, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
if err == nil {
|
||||
t.Error("should not be able to instantiate CBC-HMAC with invalid key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTruncatedCiphertext(t *testing.T) {
|
||||
key := make([]byte, 32)
|
||||
nonce := make([]byte, 16)
|
||||
data := make([]byte, 32)
|
||||
|
||||
io.ReadFull(rand.Reader, key)
|
||||
io.ReadFull(rand.Reader, nonce)
|
||||
|
||||
aead, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ctx := aead.(*cbcAEAD)
|
||||
ct := aead.Seal(nil, nonce, data, nil)
|
||||
|
||||
// Truncated ciphertext, but with correct auth tag
|
||||
truncated, tail := resize(ct[:len(ct)-ctx.authtagBytes-2], len(ct)-2)
|
||||
copy(tail, ctx.computeAuthTag(nil, nonce, truncated[:len(truncated)-ctx.authtagBytes]))
|
||||
|
||||
// Open should fail
|
||||
_, err = aead.Open(nil, nonce, truncated, nil)
|
||||
if err == nil {
|
||||
t.Error("open on truncated ciphertext should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidPaddingOpen(t *testing.T) {
|
||||
key := make([]byte, 32)
|
||||
nonce := make([]byte, 16)
|
||||
|
||||
// Plaintext with invalid padding
|
||||
plaintext := padBuffer(make([]byte, 28), aes.BlockSize)
|
||||
plaintext[len(plaintext)-1] = 0xFF
|
||||
|
||||
io.ReadFull(rand.Reader, key)
|
||||
io.ReadFull(rand.Reader, nonce)
|
||||
|
||||
block, _ := aes.NewCipher(key)
|
||||
cbc := cipher.NewCBCEncrypter(block, nonce)
|
||||
buffer := append([]byte{}, plaintext...)
|
||||
cbc.CryptBlocks(buffer, buffer)
|
||||
|
||||
aead, _ := NewCBCHMAC(key, aes.NewCipher)
|
||||
ctx := aead.(*cbcAEAD)
|
||||
|
||||
// Mutated ciphertext, but with correct auth tag
|
||||
size := len(buffer)
|
||||
ciphertext, tail := resize(buffer, size+(len(key)/2))
|
||||
copy(tail, ctx.computeAuthTag(nil, nonce, ciphertext[:size]))
|
||||
|
||||
// Open should fail (b/c of invalid padding, even though tag matches)
|
||||
_, err := aead.Open(nil, nonce, ciphertext, nil)
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid padding") {
|
||||
t.Error("no or unexpected error on open with invalid padding:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidPadding(t *testing.T) {
|
||||
for i := 0; i < 256; i++ {
|
||||
slice := make([]byte, i)
|
||||
padded := padBuffer(slice, 16)
|
||||
if len(padded)%16 != 0 {
|
||||
t.Error("failed to pad slice properly", i)
|
||||
return
|
||||
}
|
||||
|
||||
paddingBytes := 16 - (i % 16)
|
||||
|
||||
// Mutate padding for testing
|
||||
for j := 1; j <= paddingBytes; j++ {
|
||||
mutated := make([]byte, len(padded))
|
||||
copy(mutated, padded)
|
||||
mutated[len(mutated)-j] ^= 0xFF
|
||||
|
||||
_, err := unpadBuffer(mutated, 16)
|
||||
if err == nil {
|
||||
t.Error("unpad on invalid padding should fail", i)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Test truncated padding
|
||||
_, err := unpadBuffer(padded[:len(padded)-1], 16)
|
||||
if err == nil {
|
||||
t.Error("unpad on truncated padding should fail", i)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestZeroLengthPadding(t *testing.T) {
|
||||
data := make([]byte, 16)
|
||||
data, err := unpadBuffer(data, 16)
|
||||
if err == nil {
|
||||
t.Error("padding with 0x00 should never be valid")
|
||||
}
|
||||
}
|
||||
|
||||
func benchEncryptCBCHMAC(b *testing.B, keySize, chunkSize int) {
|
||||
key := make([]byte, keySize*2)
|
||||
nonce := make([]byte, 16)
|
||||
|
||||
io.ReadFull(rand.Reader, key)
|
||||
io.ReadFull(rand.Reader, nonce)
|
||||
|
||||
chunk := make([]byte, chunkSize)
|
||||
|
||||
aead, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
b.SetBytes(int64(chunkSize))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
aead.Seal(nil, nonce, chunk, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func benchDecryptCBCHMAC(b *testing.B, keySize, chunkSize int) {
|
||||
key := make([]byte, keySize*2)
|
||||
nonce := make([]byte, 16)
|
||||
|
||||
io.ReadFull(rand.Reader, key)
|
||||
io.ReadFull(rand.Reader, nonce)
|
||||
|
||||
chunk := make([]byte, chunkSize)
|
||||
|
||||
aead, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
out := aead.Seal(nil, nonce, chunk, nil)
|
||||
|
||||
b.SetBytes(int64(chunkSize))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
aead.Open(nil, nonce, out, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES128_CBCHMAC_1k(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 16, 1024)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES128_CBCHMAC_64k(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 16, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES128_CBCHMAC_1MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 16, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES128_CBCHMAC_64MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 16, 67108864)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES128_CBCHMAC_1k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 16, 1024)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES128_CBCHMAC_64k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 16, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES128_CBCHMAC_1MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 16, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES128_CBCHMAC_64MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 16, 67108864)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES192_CBCHMAC_64k(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 24, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES192_CBCHMAC_1MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 24, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES192_CBCHMAC_64MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 24, 67108864)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES192_CBCHMAC_1k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 24, 1024)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES192_CBCHMAC_64k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 24, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES192_CBCHMAC_1MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 24, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES192_CBCHMAC_64MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 24, 67108864)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES256_CBCHMAC_64k(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 32, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES256_CBCHMAC_1MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 32, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES256_CBCHMAC_64MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 32, 67108864)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES256_CBCHMAC_1k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 32, 1032)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES256_CBCHMAC_64k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 32, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES256_CBCHMAC_1MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 32, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES256_CBCHMAC_64MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 32, 67108864)
|
||||
}
|
148
vendor/github.com/square/go-jose/cipher/concat_kdf_test.go
generated
vendored
148
vendor/github.com/square/go-jose/cipher/concat_kdf_test.go
generated
vendored
@ -1,148 +0,0 @@
|
||||
/*-
|
||||
* Copyright 2014 Square Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package josecipher
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Taken from: https://tools.ietf.org/id/draft-ietf-jose-json-web-algorithms-38.txt
|
||||
func TestVectorConcatKDF(t *testing.T) {
|
||||
z := []byte{
|
||||
158, 86, 217, 29, 129, 113, 53, 211, 114, 131, 66, 131, 191, 132,
|
||||
38, 156, 251, 49, 110, 163, 218, 128, 106, 72, 246, 218, 167, 121,
|
||||
140, 254, 144, 196}
|
||||
|
||||
algID := []byte{0, 0, 0, 7, 65, 49, 50, 56, 71, 67, 77}
|
||||
|
||||
ptyUInfo := []byte{0, 0, 0, 5, 65, 108, 105, 99, 101}
|
||||
ptyVInfo := []byte{0, 0, 0, 3, 66, 111, 98}
|
||||
|
||||
supPubInfo := []byte{0, 0, 0, 128}
|
||||
supPrivInfo := []byte{}
|
||||
|
||||
expected := []byte{
|
||||
86, 170, 141, 234, 248, 35, 109, 32, 92, 34, 40, 205, 113, 167, 16, 26}
|
||||
|
||||
ckdf := NewConcatKDF(crypto.SHA256, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo)
|
||||
|
||||
out0 := make([]byte, 9)
|
||||
out1 := make([]byte, 7)
|
||||
|
||||
read0, err := ckdf.Read(out0)
|
||||
if err != nil {
|
||||
t.Error("error when reading from concat kdf reader", err)
|
||||
return
|
||||
}
|
||||
|
||||
read1, err := ckdf.Read(out1)
|
||||
if err != nil {
|
||||
t.Error("error when reading from concat kdf reader", err)
|
||||
return
|
||||
}
|
||||
|
||||
if read0+read1 != len(out0)+len(out1) {
|
||||
t.Error("did not receive enough bytes from concat kdf reader")
|
||||
return
|
||||
}
|
||||
|
||||
out := []byte{}
|
||||
out = append(out, out0...)
|
||||
out = append(out, out1...)
|
||||
|
||||
if bytes.Compare(out, expected) != 0 {
|
||||
t.Error("did not receive expected output from concat kdf reader")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
z := []byte{
|
||||
158, 86, 217, 29, 129, 113, 53, 211, 114, 131, 66, 131, 191, 132,
|
||||
38, 156, 251, 49, 110, 163, 218, 128, 106, 72, 246, 218, 167, 121,
|
||||
140, 254, 144, 196}
|
||||
|
||||
algID := []byte{1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}
|
||||
|
||||
ptyUInfo := []byte{1, 2, 3, 4}
|
||||
ptyVInfo := []byte{4, 3, 2, 1}
|
||||
|
||||
supPubInfo := []byte{}
|
||||
supPrivInfo := []byte{}
|
||||
|
||||
outputs := [][]byte{}
|
||||
|
||||
// Read the same amount of data in different chunk sizes
|
||||
for i := 10; i <= 100; i++ {
|
||||
out := make([]byte, 1024)
|
||||
reader := NewConcatKDF(crypto.SHA256, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo)
|
||||
|
||||
for j := 0; j < 1024/i; j++ {
|
||||
_, _ = reader.Read(out[j*i:])
|
||||
}
|
||||
|
||||
outputs = append(outputs, out)
|
||||
}
|
||||
|
||||
for i := range outputs {
|
||||
if bytes.Compare(outputs[i], outputs[i%len(outputs)]) != 0 {
|
||||
t.Error("not all outputs from KDF matched")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkKDF(b *testing.B, total int) {
|
||||
z := []byte{
|
||||
158, 86, 217, 29, 129, 113, 53, 211, 114, 131, 66, 131, 191, 132,
|
||||
38, 156, 251, 49, 110, 163, 218, 128, 106, 72, 246, 218, 167, 121,
|
||||
140, 254, 144, 196}
|
||||
|
||||
algID := []byte{1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}
|
||||
|
||||
ptyUInfo := []byte{1, 2, 3, 4}
|
||||
ptyVInfo := []byte{4, 3, 2, 1}
|
||||
|
||||
supPubInfo := []byte{}
|
||||
supPrivInfo := []byte{}
|
||||
|
||||
out := make([]byte, total)
|
||||
reader := NewConcatKDF(crypto.SHA256, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo)
|
||||
|
||||
b.ResetTimer()
|
||||
b.SetBytes(int64(total))
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = reader.Read(out)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkConcatKDF_1k(b *testing.B) {
|
||||
benchmarkKDF(b, 1024)
|
||||
}
|
||||
|
||||
func BenchmarkConcatKDF_64k(b *testing.B) {
|
||||
benchmarkKDF(b, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkConcatKDF_1MB(b *testing.B) {
|
||||
benchmarkKDF(b, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkConcatKDF_64MB(b *testing.B) {
|
||||
benchmarkKDF(b, 67108864)
|
||||
}
|
98
vendor/github.com/square/go-jose/cipher/ecdh_es_test.go
generated
vendored
98
vendor/github.com/square/go-jose/cipher/ecdh_es_test.go
generated
vendored
@ -1,98 +0,0 @@
|
||||
/*-
|
||||
* Copyright 2014 Square Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package josecipher
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"encoding/base64"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Example keys from JWA, Appendix C
|
||||
var aliceKey = &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
X: fromBase64Int("gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0="),
|
||||
Y: fromBase64Int("SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps="),
|
||||
},
|
||||
D: fromBase64Int("0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo="),
|
||||
}
|
||||
|
||||
var bobKey = &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
X: fromBase64Int("weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ="),
|
||||
Y: fromBase64Int("e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck="),
|
||||
},
|
||||
D: fromBase64Int("VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw="),
|
||||
}
|
||||
|
||||
// Build big int from base64-encoded string. Strips whitespace (for testing).
|
||||
func fromBase64Int(data string) *big.Int {
|
||||
val, err := base64.URLEncoding.DecodeString(data)
|
||||
if err != nil {
|
||||
panic("Invalid test data")
|
||||
}
|
||||
return new(big.Int).SetBytes(val)
|
||||
}
|
||||
|
||||
func TestVectorECDHES(t *testing.T) {
|
||||
apuData := []byte("Alice")
|
||||
apvData := []byte("Bob")
|
||||
|
||||
expected := []byte{
|
||||
86, 170, 141, 234, 248, 35, 109, 32, 92, 34, 40, 205, 113, 167, 16, 26}
|
||||
|
||||
output := DeriveECDHES("A128GCM", apuData, apvData, bobKey, &aliceKey.PublicKey, 16)
|
||||
|
||||
if bytes.Compare(output, expected) != 0 {
|
||||
t.Error("output did not match what we expect, got", output, "wanted", expected)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkECDHES_128(b *testing.B) {
|
||||
apuData := []byte("APU")
|
||||
apvData := []byte("APV")
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
DeriveECDHES("ID", apuData, apvData, bobKey, &aliceKey.PublicKey, 16)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkECDHES_192(b *testing.B) {
|
||||
apuData := []byte("APU")
|
||||
apvData := []byte("APV")
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
DeriveECDHES("ID", apuData, apvData, bobKey, &aliceKey.PublicKey, 24)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkECDHES_256(b *testing.B) {
|
||||
apuData := []byte("APU")
|
||||
apvData := []byte("APV")
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
DeriveECDHES("ID", apuData, apvData, bobKey, &aliceKey.PublicKey, 32)
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user