<commit_before>package main

import (
	"context"
	"fmt"
	"log"
	"sync"
	"time"

	cacheutil "github.com/heptio/developer-dash/internal/cache/util"
	"github.com/heptio/developer-dash/pkg/plugin"
	"github.com/heptio/developer-dash/pkg/plugin/api"
	"github.com/heptio/developer-dash/pkg/view/component"
	"github.com/heptio/developer-dash/pkg/view/flexlayout"
	"github.com/pkg/errors"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
)

type stub struct {
	apiClient api.Service
	mu        sync.Mutex
}

var _ plugin.Service = (*stub)(nil)

func (s *stub) Register(apiAddress string) (plugin.Metadata, error) {
	s.mu.Lock()
	defer s.mu.Unlock()

	client, err := api.NewClient(apiAddress)
	if err != nil {
		return plugin.Metadata{}, errors.Wrap(err, "create api client")
	}

	s.apiClient = client

	podGVK := schema.GroupVersionKind{Version: "v1", Kind: "Pod"}

	log.Println("the dashboard plugin api is at", apiAddress)

	return plugin.Metadata{
		Name:        "plugin-name",
		Description: "a description",
		Capabilities: plugin.Capabilities{
			SupportsPrinterConfig: []schema.GroupVersionKind{podGVK},
			SupportsPrinterStatus: []schema.GroupVersionKind{podGVK},
			SupportsPrinterItems:  []schema.GroupVersionKind{podGVK},
			SupportsObjectStatus:  []schema.GroupVersionKind{podGVK},
			SupportsTab:           []schema.GroupVersionKind{podGVK},
		},
	}, nil
}

func (s *stub) Print(object runtime.Object) (plugin.PrintResponse, error) {
	if object == nil {
		return plugin.PrintResponse{}, errors.Errorf("object is nil")
	}

	ctx := context.Background()
	key, err := cacheutil.KeyFromObject(object)
	if err != nil {
		return plugin.PrintResponse{}, err
	}
	u, err := s.apiClient.Get(ctx, key)
	if err != nil {
		return plugin.PrintResponse{}, err
	}

	log.Printf("loaded object from cache: %v", u)

	msg := fmt.Sprintf("update from plugin at %s", time.Now().Format(time.RFC3339))

	return plugin.PrintResponse{
		Config: []component.SummarySection{
			{Header: "from-plugin", Content: component.NewText(msg)},
		},
		Status: []component.SummarySection{
			{Header: "from-plugin", Content: component.NewText(msg)},
		},
		Items: []component.FlexLayoutItem{
			{
				Width: component.WidthHalf,
				View:  component.NewText("item 1 from plugin"),
			},
			{
				Width: component.WidthFull,
				View:  component.NewText("item 2 from plugin"),
			},
		},
	}, nil
}

func (s *stub) PrintTab(object runtime.Object) (*component.Tab, error) {
	if object == nil {
		return nil, errors.New("object is nil")
	}

	layout := flexlayout.New()
	section := layout.AddSection()
	err := section.Add(component.NewText("content from a plugin"), component.WidthHalf)
	if err != nil {
		return nil, err
	}

	tab := component.Tab{
		Name:     "PluginStub",
		Contents: *layout.ToComponent("Plugin"),
	}

	return &tab, nil
}

func main() {
	log.Print("plugin is starting")
	plugin.Serve(&stub{})
}
<commit_msg>Fix pluginstub example<commit_after>package main

import (
	"context"
	"fmt"
	"log"
	"sync"
	"time"

	"github.com/heptio/developer-dash/pkg/objectstoreutil"
	"github.com/heptio/developer-dash/pkg/plugin"
	"github.com/heptio/developer-dash/pkg/plugin/api"
	"github.com/heptio/developer-dash/pkg/view/component"
	"github.com/heptio/developer-dash/pkg/view/flexlayout"
	"github.com/pkg/errors"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
)

type stub struct {
	apiClient api.Service
	mu        sync.Mutex
}

var _ plugin.Service = (*stub)(nil)

func (s *stub) Register(apiAddress string) (plugin.Metadata, error) {
	s.mu.Lock()
	defer s.mu.Unlock()

	client, err := api.NewClient(apiAddress)
	if err != nil {
		return plugin.Metadata{}, errors.Wrap(err, "create api client")
	}

	s.apiClient = client

	podGVK := schema.GroupVersionKind{Version: "v1", Kind: "Pod"}

	log.Println("the dashboard plugin api is at", apiAddress)

	return plugin.Metadata{
		Name:        "plugin-name",
		Description: "a description",
		Capabilities: plugin.Capabilities{
			SupportsPrinterConfig: []schema.GroupVersionKind{podGVK},
			SupportsPrinterStatus: []schema.GroupVersionKind{podGVK},
			SupportsPrinterItems:  []schema.GroupVersionKind{podGVK},
			SupportsObjectStatus:  []schema.GroupVersionKind{podGVK},
			SupportsTab:           []schema.GroupVersionKind{podGVK},
		},
	}, nil
}

func (s *stub) Print(object runtime.Object) (plugin.PrintResponse, error) {
	if object == nil {
		return plugin.PrintResponse{}, errors.Errorf("object is nil")
	}

	ctx := context.Background()
	key, err := objectstoreutil.KeyFromObject(object)
	if err != nil {
		return plugin.PrintResponse{}, err
	}
	u, err := s.apiClient.Get(ctx, key)
	if err != nil {
		return plugin.PrintResponse{}, err
	}

	log.Printf("loaded object from objectstore: %v", u)

	msg := fmt.Sprintf("update from plugin at %s", time.Now().Format(time.RFC3339))

	return plugin.PrintResponse{
		Config: []component.SummarySection{
			{Header: "from-plugin", Content: component.NewText(msg)},
		},
		Status: []component.SummarySection{
			{Header: "from-plugin", Content: component.NewText(msg)},
		},
		Items: []component.FlexLayoutItem{
			{
				Width: component.WidthHalf,
				View:  component.NewText("item 1 from plugin"),
			},
			{
				Width: component.WidthFull,
				View:  component.NewText("item 2 from plugin"),
			},
		},
	}, nil
}

func (s *stub) PrintTab(object runtime.Object) (*component.Tab, error) {
	if object == nil {
		return nil, errors.New("object is nil")
	}

	layout := flexlayout.New()
	section := layout.AddSection()
	err := section.Add(component.NewText("content from a plugin"), component.WidthHalf)
	if err != nil {
		return nil, err
	}

	tab := component.Tab{
		Name:     "PluginStub",
		Contents: *layout.ToComponent("Plugin"),
	}

	return &tab, nil
}

func main() {
	log.Print("plugin is starting")
	plugin.Serve(&stub{})
}
<|endoftext|>


<commit_before>package main

import (
	"os/exec"
	"reflect"
	"strings"
	"testing"
)

func setup_monitoringCalls() {
	monitoringCalls = map[monitoringResult]string{
		monitorOk:       `printf "somehost.example.com;%(event);0;%(message)\n" |/usr/sbin/send_nsca -H nagios.example.com -d ";"`,
		monitorWarning:  `printf "somehost.example.com;%(event);1;%(message)\n" |/usr/sbin/send_nsca -H nagios.example.com -d ";"`,
		monitorCritical: `printf "somehost.example.com;%(event);2;%(message)\n" |/usr/sbin/send_nsca -H nagios.example.com -d ";"`,
		monitorUnknown:  `printf "somehost.example.com;%(event);3;%(message)\n" |/usr/sbin/send_nsca -H nagios.example.com -d ";"`,
	}
}

func TestMonitorOk(t *testing.T) {
	oldCalls := monitoringCalls
	oldEvent := monitoringEvent
	oldCommander := commander
	defer func() {
		monitoringCalls = oldCalls
		monitoringEvent = oldEvent
		commander = oldCommander
	}()

	setup_monitoringCalls()
	monitoringEvent = "tests"
	ce := &mockCommanderExecutor{
		want: `/bin/sh -c printf "somehost.example.com;tests;0;OK\n" |/usr/sbin/send_nsca -H nagios.example.com -d ";"`,
	}

	commander = Commander(ce)
	monitor(monitorOk, "OK")
	if ce.got != ce.want {
		t.Errorf("got '%v', want '%v'", ce.got, ce.want)
	} else {
		t.Logf("got '%v', want '%v'", ce.got, ce.want)
	}
}

func TestNoMonitoring(t *testing.T) {
	oldCalls := monitoringCalls
	oldEvent := monitoringEvent
	oldCommander := commander
	oldOpts := opts
	defer func() {
		monitoringCalls = oldCalls
		monitoringEvent = oldEvent
		commander = oldCommander
		opts = oldOpts
	}()

	setup_monitoringCalls()
	opts.NoMonitoring = true
	monitoringEvent = "tests"
	ce := &mockCommanderExecutor{}

	commander = Commander(ce)
	monitor(monitorOk, "OK")
	if ce.got != ce.want {
		t.Errorf("got '%v', want '%v'", ce.got, ce.want)
	} else {
		t.Logf("got '%v', want '%v'", ce.got, ce.want)
	}
}

var escapeTest = [...]string{
	// stuff bash interprets, space
	"# & ; ` | * ? ~ < > ^ ( ) [ ] { } $ \x0a \\ ' \" %",

	// stuff bash interprets, no space
	"#&;`|*?~<>^()[]{}$\x0a\\'\"%",

	// printf codes:
	"% \\ (used to form %.0#-*+d, or \\ \a \b \f \n \r \t \v \" \062 \062 \x32 \u0032 and \U00000032)",
}

func TestShellEscaping(t *testing.T) {
	oldCalls := monitoringCalls
	oldEvent := monitoringEvent
	oldCommander := commander
	oldOpts := opts
	defer func() {
		monitoringCalls = oldCalls
		monitoringEvent = oldEvent
		commander = oldCommander
		opts = oldOpts
	}()

	monitoringCalls = map[monitoringResult]string{
		monitorOk: `printf "somehost.example.com;%(event);0;%(message)\n" | cat`,
	}
	opts.NoMonitoring = false
	monitoringEvent = "escape"

	for i, sample := range escapeTest {
		ce := &capturingCommanderExecutor{
			want: "somehost.example.com;escape;0;" + sample + "\n",
		}

		commander = Commander(ce)

		monitor(monitorOk, sample)
		if !reflect.DeepEqual(ce.err, ce.xfail) {
			t.Errorf("%d: got error '%v', want '%v'", i, ce.err, ce.xfail)
		} else if ce.err != nil {
			t.Logf("%d: got expected error '%v'", i, ce.err)
		}

		if ce.got != ce.want {
			t.Errorf("%d: got %q, want %q", i, ce.got, ce.want)
		} else {
			t.Logf("%d: ok", i)
		}
	}
}

// mock infrastructure for os.exec Command and run
type mockCommanderExecutor struct {
	got, want string
	xfail     error
}

func (e *mockCommanderExecutor) Command(name string, args ...string) Executor {
	cmd := []string{name}
	cmd = append(cmd, args...)
	e.got = strings.Join(cmd, " ")
	return e
}

func (e *mockCommanderExecutor) Run() error { return e.xfail }

//  version of executor capturing output and stderr
type capturingCommanderExecutor struct {
	got, want  string
	err, xfail error
	cmd        *exec.Cmd
}

func (e *capturingCommanderExecutor) Command(name string, args ...string) Executor {
	e.cmd = exec.Command(name, args...)
	return e
}

func (e *capturingCommanderExecutor) Run() error {
	res, err := e.cmd.CombinedOutput()
	if res != nil {
		e.got = string(res)
	} else {
		e.got = ""
	}
	e.err = err
	return err
}
<commit_msg>fix shell escaping tests<commit_after>package main

import (
	"os/exec"
	"reflect"
	"strings"
	"testing"
)

func setup_monitoringCalls() {
	monitoringCalls = map[monitoringResult]string{
		monitorOk:       `printf "somehost.example.com;%(event);0;%(message)\n" |/usr/sbin/send_nsca -H nagios.example.com -d ";"`,
		monitorWarning:  `printf "somehost.example.com;%(event);1;%(message)\n" |/usr/sbin/send_nsca -H nagios.example.com -d ";"`,
		monitorCritical: `printf "somehost.example.com;%(event);2;%(message)\n" |/usr/sbin/send_nsca -H nagios.example.com -d ";"`,
		monitorUnknown:  `printf "somehost.example.com;%(event);3;%(message)\n" |/usr/sbin/send_nsca -H nagios.example.com -d ";"`,
	}
}

func TestMonitorOk(t *testing.T) {
	oldCalls := monitoringCalls
	oldEvent := monitoringEvent
	oldCommander := commander
	defer func() {
		monitoringCalls = oldCalls
		monitoringEvent = oldEvent
		commander = oldCommander
	}()

	setup_monitoringCalls()
	monitoringEvent = "tests"
	ce := &mockCommanderExecutor{
		want: `/bin/sh -c printf "somehost.example.com;tests;0;OK\n" |/usr/sbin/send_nsca -H nagios.example.com -d ";"`,
	}

	commander = Commander(ce)
	monitor(monitorOk, "OK")
	if ce.got != ce.want {
		t.Errorf("got '%v', want '%v'", ce.got, ce.want)
	} else {
		t.Logf("got '%v', want '%v'", ce.got, ce.want)
	}
}

func TestNoMonitoring(t *testing.T) {
	oldCalls := monitoringCalls
	oldEvent := monitoringEvent
	oldCommander := commander
	oldOpts := opts
	defer func() {
		monitoringCalls = oldCalls
		monitoringEvent = oldEvent
		commander = oldCommander
		opts = oldOpts
	}()

	setup_monitoringCalls()
	opts.NoMonitoring = true
	monitoringEvent = "tests"
	ce := &mockCommanderExecutor{}

	commander = Commander(ce)
	monitor(monitorOk, "OK")
	if ce.got != ce.want {
		t.Errorf("got '%v', want '%v'", ce.got, ce.want)
	} else {
		t.Logf("got '%v', want '%v'", ce.got, ce.want)
	}
}

var escapeTest = [...]string{
	// stuff bash interprets, space
	"# & ; ` | * ? ~ < > ^ ( ) [ ] { } $ \x0a ' \" %",

	// stuff bash interprets, no space
	"#&;`|*?~<>^()[]{}$\x0a'\"%",

	// printf codes:
	"% (used to form %.0#-*+d, or \a \b \f \n \r \t \v \" \062 \062 \x32 \u0032 and \U00000032)",

	// extra case (bash and dash bet to differ here in certain cases)
	"\\",
}

func TestShellEscaping(t *testing.T) {
	oldCalls := monitoringCalls
	oldEvent := monitoringEvent
	oldCommander := commander
	oldOpts := opts
	defer func() {
		monitoringCalls = oldCalls
		monitoringEvent = oldEvent
		commander = oldCommander
		opts = oldOpts
	}()

	monitoringCalls = map[monitoringResult]string{
		monitorOk: `printf "somehost.example.com;%(event);0;%(message) \n" | cat`,
	}
	opts.NoMonitoring = false
	monitoringEvent = "escape"

	for i, sample := range escapeTest {
		ce := &capturingCommanderExecutor{
			want: "somehost.example.com;escape;0;" + sample + " \n",
		}

		commander = Commander(ce)

		monitor(monitorOk, sample)
		if !reflect.DeepEqual(ce.err, ce.xfail) {
			t.Errorf("%d: got error '%v', want '%v'", i, ce.err, ce.xfail)
		} else if ce.err != nil {
			t.Logf("%d: got expected error '%v'", i, ce.err)
		}

		if ce.got != ce.want {
			t.Errorf("%d: got %q, want %q", i, ce.got, ce.want)
		} else {
			t.Logf("%d: ok", i)
		}
	}
}

// mock infrastructure for os.exec Command and run
type mockCommanderExecutor struct {
	got, want string
	xfail     error
}

func (e *mockCommanderExecutor) Command(name string, args ...string) Executor {
	cmd := []string{name}
	cmd = append(cmd, args...)
	e.got = strings.Join(cmd, " ")
	return e
}

func (e *mockCommanderExecutor) Run() error { return e.xfail }

//  version of executor capturing output and stderr
type capturingCommanderExecutor struct {
	got, want  string
	err, xfail error
	cmd        *exec.Cmd
}

func (e *capturingCommanderExecutor) Command(name string, args ...string) Executor {
	e.cmd = exec.Command(name, args...)
	return e
}

func (e *capturingCommanderExecutor) Run() error {
	res, err := e.cmd.CombinedOutput()
	if res != nil {
		e.got = string(res)
	} else {
		e.got = ""
	}
	e.err = err
	return err
}
<|endoftext|>


<commit_before>package strings

import (
	"github.com/PuerkitoBio/gred/cmd"
	"github.com/PuerkitoBio/gred/srv"
	"github.com/PuerkitoBio/gred/vals"
)

func init() {
	cmd.Register("append", append_)
	cmd.Register("decr", decr)
	cmd.Register("decrby", decrby)
	cmd.Register("get", get)
	cmd.Register("getrange", getrange)
	//cmd.Register("substr", getrange) // alias
	cmd.Register("getset", getset)
	cmd.Register("incr", incr)
	cmd.Register("incrby", incrby)
	cmd.Register("incrbyfloat", incrbyfloat)
	cmd.Register("set", set)
	cmd.Register("setrange", setrange)
	cmd.Register("strlen", strlen)
}

var append_ = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 2,
		MaxArgs: 2,
	},
	srv.NoKeyCreateString,
	appendFn)

func appendFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		return v.Append(args[1]), nil
	}
	return nil, cmd.ErrInvalidValType
}

var decr = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 1,
		MaxArgs: 1,
	},
	srv.NoKeyCreateStringInt,
	decrFn)

func decrFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.IncString); ok {
		val, ok := v.Decr()
		if ok {
			return val, nil
		}
		return nil, cmd.ErrNotInteger
	}
	return nil, cmd.ErrInvalidValType
}

var decrby = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs:    2,
		MaxArgs:    2,
		IntIndices: []int{1},
	},
	srv.NoKeyCreateStringInt,
	decrbyFn)

func decrbyFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.IncString); ok {
		val, ok := v.DecrBy(ints[0])
		if ok {
			return val, nil
		}
		return nil, cmd.ErrNotInteger
	}
	return nil, cmd.ErrInvalidValType
}

var get = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 1,
		MaxArgs: 1,
	},
	srv.NoKeyNone,
	getFn)

func getFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	if k == nil {
		return nil, nil
	}

	k.RLock()
	defer k.RUnlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		return v.Get(), nil
	}
	return nil, cmd.ErrInvalidValType
}

var getrange = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs:    3,
		MaxArgs:    3,
		IntIndices: []int{1, 2},
	},
	srv.NoKeyDefaultVal,
	getrangeFn)

func getrangeFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.RLock()
	defer k.RUnlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		return v.GetRange(ints[0], ints[1]), nil
	}
	return nil, cmd.ErrInvalidValType
}

var getset = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 2,
		MaxArgs: 2,
	},
	srv.NoKeyCreateString,
	getsetFn)

func getsetFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		k.Abort()
		return v.GetSet(args[1]), nil
	}
	return nil, cmd.ErrInvalidValType
}

var incr = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 1,
		MaxArgs: 1,
	},
	srv.NoKeyCreateStringInt,
	incrFn)

func incrFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.IncString); ok {
		val, ok := v.Incr()
		if ok {
			return val, nil
		}
		return nil, cmd.ErrNotInteger
	}
	return nil, cmd.ErrInvalidValType
}

var incrby = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs:    2,
		MaxArgs:    2,
		IntIndices: []int{1},
	},
	srv.NoKeyCreateStringInt,
	incrbyFn)

func incrbyFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.IncString); ok {
		val, ok := v.IncrBy(ints[0])
		if ok {
			return val, nil
		}
		return nil, cmd.ErrNotInteger
	}
	return nil, cmd.ErrInvalidValType
}

var incrbyfloat = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs:      2,
		MaxArgs:      2,
		FloatIndices: []int{1},
	},
	srv.NoKeyCreateStringInt,
	incrbyfloatFn)

func incrbyfloatFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.IncString); ok {
		val, ok := v.IncrByFloat(floats[0])
		if ok {
			return val, nil
		}
		return nil, cmd.ErrNotFloat
	}
	return nil, cmd.ErrInvalidValType
}

// TODO : This doesn't handle the extra optional args (EX, NX, PX)
var set = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 2,
		MaxArgs: 2,
	},
	srv.NoKeyCreateString,
	setFn)

func setFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		k.Abort()
		v.Set(args[1])
		return cmd.OKVal, nil
	}
	return nil, cmd.ErrInvalidValType
}

var setrange = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs:    3,
		MaxArgs:    3,
		IntIndices: []int{1},
		ValidateFn: func(args []string, ints []int64, floats []float64) error {
			if ints[0] < 0 {
				return cmd.ErrOfsOutOfRange
			}
			return nil
		},
	},
	srv.NoKeyDefaultVal,
	setrangeFn)

func setrangeFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		return v.SetRange(ints[0], args[2]), nil
	}
	return nil, cmd.ErrInvalidValType
}

var strlen = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 1,
		MaxArgs: 1,
	},
	srv.NoKeyDefaultVal,
	strlenFn)

func strlenFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.RLock()
	defer k.RUnlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		return v.StrLen(), nil
	}
	return nil, cmd.ErrInvalidValType
}
<commit_msg>make lint happy<commit_after>package strings

import (
	"github.com/PuerkitoBio/gred/cmd"
	"github.com/PuerkitoBio/gred/srv"
	"github.com/PuerkitoBio/gred/vals"
)

func init() {
	cmd.Register("append", appendƒ)
	cmd.Register("decr", decr)
	cmd.Register("decrby", decrby)
	cmd.Register("get", get)
	cmd.Register("getrange", getrange)
	//cmd.Register("substr", getrange) // alias
	cmd.Register("getset", getset)
	cmd.Register("incr", incr)
	cmd.Register("incrby", incrby)
	cmd.Register("incrbyfloat", incrbyfloat)
	cmd.Register("set", set)
	cmd.Register("setrange", setrange)
	cmd.Register("strlen", strlen)
}

var appendƒ = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 2,
		MaxArgs: 2,
	},
	srv.NoKeyCreateString,
	appendFn)

func appendFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		return v.Append(args[1]), nil
	}
	return nil, cmd.ErrInvalidValType
}

var decr = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 1,
		MaxArgs: 1,
	},
	srv.NoKeyCreateStringInt,
	decrFn)

func decrFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.IncString); ok {
		val, ok := v.Decr()
		if ok {
			return val, nil
		}
		return nil, cmd.ErrNotInteger
	}
	return nil, cmd.ErrInvalidValType
}

var decrby = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs:    2,
		MaxArgs:    2,
		IntIndices: []int{1},
	},
	srv.NoKeyCreateStringInt,
	decrbyFn)

func decrbyFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.IncString); ok {
		val, ok := v.DecrBy(ints[0])
		if ok {
			return val, nil
		}
		return nil, cmd.ErrNotInteger
	}
	return nil, cmd.ErrInvalidValType
}

var get = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 1,
		MaxArgs: 1,
	},
	srv.NoKeyNone,
	getFn)

func getFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	if k == nil {
		return nil, nil
	}

	k.RLock()
	defer k.RUnlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		return v.Get(), nil
	}
	return nil, cmd.ErrInvalidValType
}

var getrange = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs:    3,
		MaxArgs:    3,
		IntIndices: []int{1, 2},
	},
	srv.NoKeyDefaultVal,
	getrangeFn)

func getrangeFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.RLock()
	defer k.RUnlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		return v.GetRange(ints[0], ints[1]), nil
	}
	return nil, cmd.ErrInvalidValType
}

var getset = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 2,
		MaxArgs: 2,
	},
	srv.NoKeyCreateString,
	getsetFn)

func getsetFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		k.Abort()
		return v.GetSet(args[1]), nil
	}
	return nil, cmd.ErrInvalidValType
}

var incr = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 1,
		MaxArgs: 1,
	},
	srv.NoKeyCreateStringInt,
	incrFn)

func incrFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.IncString); ok {
		val, ok := v.Incr()
		if ok {
			return val, nil
		}
		return nil, cmd.ErrNotInteger
	}
	return nil, cmd.ErrInvalidValType
}

var incrby = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs:    2,
		MaxArgs:    2,
		IntIndices: []int{1},
	},
	srv.NoKeyCreateStringInt,
	incrbyFn)

func incrbyFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.IncString); ok {
		val, ok := v.IncrBy(ints[0])
		if ok {
			return val, nil
		}
		return nil, cmd.ErrNotInteger
	}
	return nil, cmd.ErrInvalidValType
}

var incrbyfloat = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs:      2,
		MaxArgs:      2,
		FloatIndices: []int{1},
	},
	srv.NoKeyCreateStringInt,
	incrbyfloatFn)

func incrbyfloatFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.IncString); ok {
		val, ok := v.IncrByFloat(floats[0])
		if ok {
			return val, nil
		}
		return nil, cmd.ErrNotFloat
	}
	return nil, cmd.ErrInvalidValType
}

// TODO : This doesn't handle the extra optional args (EX, NX, PX)
var set = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 2,
		MaxArgs: 2,
	},
	srv.NoKeyCreateString,
	setFn)

func setFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		k.Abort()
		v.Set(args[1])
		return cmd.OKVal, nil
	}
	return nil, cmd.ErrInvalidValType
}

var setrange = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs:    3,
		MaxArgs:    3,
		IntIndices: []int{1},
		ValidateFn: func(args []string, ints []int64, floats []float64) error {
			if ints[0] < 0 {
				return cmd.ErrOfsOutOfRange
			}
			return nil
		},
	},
	srv.NoKeyDefaultVal,
	setrangeFn)

func setrangeFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.Lock()
	defer k.Unlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		return v.SetRange(ints[0], args[2]), nil
	}
	return nil, cmd.ErrInvalidValType
}

var strlen = cmd.NewSingleKeyCmd(
	&cmd.ArgDef{
		MinArgs: 1,
		MaxArgs: 1,
	},
	srv.NoKeyDefaultVal,
	strlenFn)

func strlenFn(k srv.Key, args []string, ints []int64, floats []float64) (interface{}, error) {
	k.RLock()
	defer k.RUnlock()

	v := k.Val()
	if v, ok := v.(vals.String); ok {
		return v.StrLen(), nil
	}
	return nil, cmd.ErrInvalidValType
}
<|endoftext|>


<commit_before>// Package duoimage helps create images that differ depending on what theme you are using
// on Discord.
package duoimage

import (
	"image"
	"image/draw"
	"image/png"
	"log"
	"math"
	"os"

	"github.com/nfnt/resize"

	"github.com/anthonynsimon/bild/parallel"

	"github.com/anthonynsimon/bild/clone"
)

// Color constants
const (
	DarkThemeClr  = int(0x36393Eff)
	LightThemeClr = int(0xffffffff)
)

// MaskOption is an enum of mask types
type MaskOption int

// Mask constants
const (
	MaskHorizontal MaskOption = iota
	MaskVertical
	MaskDiagonal
)

// Options are the options
type Options struct {
	// Mask is one of the MaskOption types
	// EG. MaskVertical, MaskHorizontal, MaskDiagonal
	Mask MaskOption
}

// Merge merges two images with the specified mask option
func Merge(srca, srcb image.Image, o *Options) *image.RGBA {
	if o == nil {
		o = &Options{
			Mask: MaskHorizontal,
		}
	}

	// Resize the images to be the same width
	srca = resize.Resize(0, 300, srca, resize.NearestNeighbor)
	srcb = resize.Resize(0, 300, srcb, resize.NearestNeighbor)

	var (
		xmod = 1
		ymod = 1
	)

	// Set the mask options depending on the specified
	// Mask type
	switch o.Mask {
	case MaskHorizontal:
		xmod = 1
		ymod = 2
	case MaskVertical:
		xmod = 2
		ymod = 1
	case MaskDiagonal:
		xmod = 2
		ymod = 2
	}

	log.Println(xmod, ymod)

	// The destination image is the same size as srca.
	dst := image.NewRGBA(srca.Bounds())
	ca, cb := clone.AsRGBA(srca), clone.AsRGBA(srcb)

	// Reduce the colour schemes of the image to
	// A transparent or colour of the given theme
	ca = Reduce(ca, []int{0x0, LightThemeClr})
	cb = Reduce(cb, []int{DarkThemeClr, 0x00})

	// debugWriteImage(ca, "tempCA.png")
	// debugWriteImage(cb, "tempCB.png")

	// Pad the pixels of CB to be the same dimensions as CA
	// cb = clone.Pad(cb, ca.Rect.Dx(), ca.Rect.Dy(), clone.NoFill)
	cb = Pad(cb, ca.Rect.Dx(), cb.Rect.Dy())

	width := ca.Rect.Dx()

	parallel.Line(dst.Rect.Dy(), func(start, end int) {
		for y := start; y < end; y++ {
			for x := 0; x < width; x++ {
				idx := y*ca.Stride + x*4
				if x%xmod != 0 || y%ymod != 0 {
					// if y%2 != 0 {
					dst.Pix[idx+0] = ca.Pix[idx+0]
					dst.Pix[idx+1] = ca.Pix[idx+1]
					dst.Pix[idx+2] = ca.Pix[idx+2]
					dst.Pix[idx+3] = ca.Pix[idx+3]
				} else {
					dst.Pix[idx+0] = cb.Pix[idx+0]
					dst.Pix[idx+1] = cb.Pix[idx+1]
					dst.Pix[idx+2] = cb.Pix[idx+2]
					dst.Pix[idx+3] = cb.Pix[idx+3]
				}
			}
		}
	})

	return dst
}

// Pad pads an image to the dimensions width and height
//     src    : image to pad
//     width  : width of the new dimensions
//     height : height of the new dimensions
func Pad(source image.Image, width, height int) *image.RGBA {
	src := clone.AsRGBA(source)
	var w, h int

	if src.Rect.Dx() > width {
		w = src.Rect.Dx()
	} else {
		w = width
	}

	if src.Rect.Dy() > height {
		h = src.Rect.Dy()
	} else {
		h = height
	}

	dst := image.NewRGBA(image.Rect(0, 0, w, h))
	draw.Draw(dst, dst.Rect, src, image.ZP, draw.Over)

	return dst
}

func debugWriteImage(img image.Image, dst string) {
	f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		log.Println(err)
		return
	}
	defer f.Close()
	png.Encode(f, img)
}

// Reduce reduces the colours of an image into the given palette
//     src     : Source image.
//     palette : Palette of colours.
func Reduce(src image.Image, palette []int) *image.RGBA {
	ca := clone.AsRGBA(src)
	dst := image.NewRGBA(ca.Rect)

	// ab := averageBrightness(ca)

	width := ca.Rect.Dx()
	parallel.Line(ca.Rect.Dy(), func(start, end int) {
		for y := start; y < end; y++ {
			for x := 0; x < width; x++ {
				idx := y*ca.Stride + x*4
				r := ca.Pix[idx+0]
				g := ca.Pix[idx+1]
				b := ca.Pix[idx+2]

				brightness := float64(int(r)+int(g)+int(b)) / 3
				pidx := int(brightness / 256 * float64(len(palette)))
				dr, dg, db, da := intToRgba(palette[pidx])

				dst.Pix[idx+0] = dr
				dst.Pix[idx+1] = dg
				dst.Pix[idx+2] = db
				dst.Pix[idx+3] = da
			}
		}
	})

	return dst
}

// nearestColor returns the nearest color in a palette.
func nearestColor(src int, palette []int) int {
	var nearestColor int
	var lowestDistance = math.MaxFloat64

	for _, v := range palette {
		r, g, b, a := intToRgba(v)
		r1, g1, b1, a1 := intToRgba(v)

		dist := colorDistance(
			r, g, b, a,
			r1, g1, b1, a1,
		)

		if dist < lowestDistance {
			lowestDistance = dist
			nearestColor = v
		}
	}

	return nearestColor
}

// colorDistance returns the euclidean distance between two colours
func colorDistance(r1, b1, g1, a1, r2, b2, g2, a2 uint8) float64 {
	return math.Sqrt(
		math.Pow(float64(r2)-float64(r1), 2) +
			math.Pow(float64(g2)-float64(g1), 2) +
			math.Pow(float64(b2)-float64(b1), 2) +
			math.Pow(float64(a2)-float64(a1), 2),
	)
}

// rgbaToInt converts RGBA to an integer
func rgbaToInt(r, g, b, a uint8) int {
	return (int(r) << 24) | ((int(g)) << 16) | (int(b) << 8) | (int(a))
}

// intToRGBA converts an integer to RGBA
func intToRgba(c int) (r, g, b, a uint8) {
	r = uint8((c >> 24) & 0xFF)
	g = uint8((c >> 16) & 0xFF)
	b = uint8((c >> 8) & 0xFF)
	a = uint8(c & 0xFF)
	return
}

// averageBrightness computes the average brightness of an image
func averageBrightness(src image.Image) float64 {
	var sum uint64
	ca := clone.AsRGBA(src)

	width := ca.Rect.Dy()
	parallel.Line(ca.Rect.Dy(), func(start, end int) {
		for y := start; y < end; y++ {
			for x := 0; x < width; x++ {
				idx := y*ca.Stride + x*4
				sum += uint64((ca.Pix[idx+0] + ca.Pix[idx+1] + ca.Pix[idx+2])) / 3
			}
		}
	})

	return float64(sum) / float64(ca.Rect.Dx()*ca.Rect.Dy())
}
<commit_msg>Remove debug stuff<commit_after>// Package duoimage helps create images that differ depending on what theme you are using
// on Discord.
package duoimage

import (
	"image"
	"image/draw"
	"image/png"
	"log"
	"math"
	"os"

	"github.com/nfnt/resize"

	"github.com/anthonynsimon/bild/parallel"

	"github.com/anthonynsimon/bild/clone"
)

// Color constants
const (
	DarkThemeClr  = int(0x36393Eff)
	LightThemeClr = int(0xffffffff)
)

// MaskOption is an enum of mask types
type MaskOption int

// Mask constants
const (
	MaskHorizontal MaskOption = iota
	MaskVertical
	MaskDiagonal
)

// Options are the options
type Options struct {
	// Mask is one of the MaskOption types
	// EG. MaskVertical, MaskHorizontal, MaskDiagonal
	Mask MaskOption
}

// Merge merges two images with the specified mask option
func Merge(srca, srcb image.Image, o *Options) *image.RGBA {
	if o == nil {
		o = &Options{
			Mask: MaskHorizontal,
		}
	}

	// Resize the images to be the same width
	srca = resize.Resize(0, 300, srca, resize.NearestNeighbor)
	srcb = resize.Resize(0, 300, srcb, resize.NearestNeighbor)

	var (
		xmod = 1
		ymod = 1
	)

	// Set the mask options depending on the specified
	// Mask type
	switch o.Mask {
	case MaskHorizontal:
		xmod = 1
		ymod = 2
	case MaskVertical:
		xmod = 2
		ymod = 1
	case MaskDiagonal:
		xmod = 2
		ymod = 2
	}

	// The destination image is the same size as srca.
	dst := image.NewRGBA(srca.Bounds())
	ca, cb := clone.AsRGBA(srca), clone.AsRGBA(srcb)

	// Reduce the colour schemes of the image to
	// A transparent or colour of the given theme
	ca = Reduce(ca, []int{0x0, LightThemeClr})
	cb = Reduce(cb, []int{DarkThemeClr, 0x00})

	// debugWriteImage(ca, "tempCA.png")
	// debugWriteImage(cb, "tempCB.png")

	// Pad the pixels of CB to be the same dimensions as CA
	// cb = clone.Pad(cb, ca.Rect.Dx(), ca.Rect.Dy(), clone.NoFill)
	cb = Pad(cb, ca.Rect.Dx(), cb.Rect.Dy())

	width := ca.Rect.Dx()

	parallel.Line(dst.Rect.Dy(), func(start, end int) {
		for y := start; y < end; y++ {
			for x := 0; x < width; x++ {
				idx := y*ca.Stride + x*4
				if x%xmod != 0 || y%ymod != 0 {
					// if y%2 != 0 {
					dst.Pix[idx+0] = ca.Pix[idx+0]
					dst.Pix[idx+1] = ca.Pix[idx+1]
					dst.Pix[idx+2] = ca.Pix[idx+2]
					dst.Pix[idx+3] = ca.Pix[idx+3]
				} else {
					dst.Pix[idx+0] = cb.Pix[idx+0]
					dst.Pix[idx+1] = cb.Pix[idx+1]
					dst.Pix[idx+2] = cb.Pix[idx+2]
					dst.Pix[idx+3] = cb.Pix[idx+3]
				}
			}
		}
	})

	return dst
}

// Pad pads an image to the dimensions width and height
//     src    : image to pad
//     width  : width of the new dimensions
//     height : height of the new dimensions
func Pad(source image.Image, width, height int) *image.RGBA {
	src := clone.AsRGBA(source)
	var w, h int

	if src.Rect.Dx() > width {
		w = src.Rect.Dx()
	} else {
		w = width
	}

	if src.Rect.Dy() > height {
		h = src.Rect.Dy()
	} else {
		h = height
	}

	dst := image.NewRGBA(image.Rect(0, 0, w, h))
	draw.Draw(dst, dst.Rect, src, image.ZP, draw.Over)

	return dst
}

func debugWriteImage(img image.Image, dst string) {
	f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		log.Println(err)
		return
	}
	defer f.Close()
	png.Encode(f, img)
}

// Reduce reduces the colours of an image into the given palette
//     src     : Source image.
//     palette : Palette of colours.
func Reduce(src image.Image, palette []int) *image.RGBA {
	ca := clone.AsRGBA(src)
	dst := image.NewRGBA(ca.Rect)

	// ab := averageBrightness(ca)

	width := ca.Rect.Dx()
	parallel.Line(ca.Rect.Dy(), func(start, end int) {
		for y := start; y < end; y++ {
			for x := 0; x < width; x++ {
				idx := y*ca.Stride + x*4
				r := ca.Pix[idx+0]
				g := ca.Pix[idx+1]
				b := ca.Pix[idx+2]

				brightness := float64(int(r)+int(g)+int(b)) / 3
				pidx := int(brightness / 256 * float64(len(palette)))
				dr, dg, db, da := intToRgba(palette[pidx])

				dst.Pix[idx+0] = dr
				dst.Pix[idx+1] = dg
				dst.Pix[idx+2] = db
				dst.Pix[idx+3] = da
			}
		}
	})

	return dst
}

// nearestColor returns the nearest color in a palette.
func nearestColor(src int, palette []int) int {
	var nearestColor int
	var lowestDistance = math.MaxFloat64

	for _, v := range palette {
		r, g, b, a := intToRgba(v)
		r1, g1, b1, a1 := intToRgba(v)

		dist := colorDistance(
			r, g, b, a,
			r1, g1, b1, a1,
		)

		if dist < lowestDistance {
			lowestDistance = dist
			nearestColor = v
		}
	}

	return nearestColor
}

// colorDistance returns the euclidean distance between two colours
func colorDistance(r1, b1, g1, a1, r2, b2, g2, a2 uint8) float64 {
	return math.Sqrt(
		math.Pow(float64(r2)-float64(r1), 2) +
			math.Pow(float64(g2)-float64(g1), 2) +
			math.Pow(float64(b2)-float64(b1), 2) +
			math.Pow(float64(a2)-float64(a1), 2),
	)
}

// rgbaToInt converts RGBA to an integer
func rgbaToInt(r, g, b, a uint8) int {
	return (int(r) << 24) | ((int(g)) << 16) | (int(b) << 8) | (int(a))
}

// intToRGBA converts an integer to RGBA
func intToRgba(c int) (r, g, b, a uint8) {
	r = uint8((c >> 24) & 0xFF)
	g = uint8((c >> 16) & 0xFF)
	b = uint8((c >> 8) & 0xFF)
	a = uint8(c & 0xFF)
	return
}

// averageBrightness computes the average brightness of an image
func averageBrightness(src image.Image) float64 {
	var sum uint64
	ca := clone.AsRGBA(src)

	width := ca.Rect.Dy()
	parallel.Line(ca.Rect.Dy(), func(start, end int) {
		for y := start; y < end; y++ {
			for x := 0; x < width; x++ {
				idx := y*ca.Stride + x*4
				sum += uint64((ca.Pix[idx+0] + ca.Pix[idx+1] + ca.Pix[idx+2])) / 3
			}
		}
	})

	return float64(sum) / float64(ca.Rect.Dx()*ca.Rect.Dy())
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/siddontang/ledisdb/client/go/ledis"
	"regexp"
	"strings"
)

var ip = flag.String("h", "127.0.0.1", "ledisdb server ip (default 127.0.0.1)")
var port = flag.Int("p", 6380, "ledisdb server port (default 6380)")
var socket = flag.String("s", "", "ledisdb server socket, overwrite ip and port")

func main() {
	flag.Parse()

	cfg := new(ledis.Config)
	if len(*socket) > 0 {
		cfg.Addr = *socket
	} else {
		cfg.Addr = fmt.Sprintf("%s:%d", *ip, *port)
	}

	cfg.MaxIdleConns = 1

	c := ledis.NewClient(cfg)

	setHistoryCapacity(100)

	reg, _ := regexp.Compile(`'.*?'|".*?"|\S+`)

	for {
		cmd, err := line(fmt.Sprintf("%s> ", cfg.Addr))
		if err != nil {
			fmt.Printf("%s\n", err.Error())
			return
		}

		cmds := reg.FindAllString(cmd, -1)
		if len(cmds) == 0 {
			continue
		} else {
			addHistory(cmd)

			args := make([]interface{}, len(cmds[1:]))
			for i := range args {
				args[i] = strings.Trim(string(cmds[1+i]), "\"'")
			}
			r, err := c.Do(cmds[0], args...)
			if err != nil {
				fmt.Printf("%s", err.Error())
			} else {
				printReply(cmd, r)
			}

			fmt.Printf("\n")
		}
	}
}

func printReply(cmd string, reply interface{}) {
	switch reply := reply.(type) {
	case int64:
		fmt.Printf("(integer) %d", reply)
	case string:
		fmt.Printf("%s", reply)
	case []byte:
		fmt.Printf("%q", reply)
	case nil:
		fmt.Printf("(nil)")
	case ledis.Error:
		fmt.Printf("%s", string(reply))
	case []interface{}:
		for i, v := range reply {
			fmt.Printf("%d) ", i+1)
			if v == nil {
				fmt.Printf("(nil)")
			} else {
				fmt.Printf("%q", v)
			}
			if i != len(reply)-1 {
				fmt.Printf("\n")
			}
		}
	default:
		fmt.Printf("invalid ledis reply")
	}
}
<commit_msg>add select display support; plus the -n flag in command line parameter<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/siddontang/ledisdb/client/go/ledis"
	"regexp"
	"strconv"
	"strings"
)

var ip = flag.String("h", "127.0.0.1", "ledisdb server ip (default 127.0.0.1)")
var port = flag.Int("p", 6380, "ledisdb server port (default 6380)")
var socket = flag.String("s", "", "ledisdb server socket, overwrite ip and port")
var dbnum = flag.Int("n", 0, "ledisdb database number(default 0)")

func main() {
	flag.Parse()

	cfg := new(ledis.Config)
	if len(*socket) > 0 {
		cfg.Addr = *socket
	} else {
		cfg.Addr = fmt.Sprintf("%s:%d", *ip, *port)
	}

	cfg.MaxIdleConns = 1

	c := ledis.NewClient(cfg)

	setHistoryCapacity(100)

	reg, _ := regexp.Compile(`'.*?'|".*?"|\S+`)

	prompt := ""

	for {
		if *dbnum != 0 {
			prompt = fmt.Sprintf("%s[%d]>", cfg.Addr, *dbnum)
		} else {
			prompt = fmt.Sprintf("%s>", cfg.Addr)
		}

		cmd, err := line(prompt)
		if err != nil {
			fmt.Printf("%s\n", err.Error())
			return
		}

		cmds := reg.FindAllString(cmd, -1)
		if len(cmds) == 0 {
			continue
		} else {
			addHistory(cmd)

			args := make([]interface{}, len(cmds[1:]))
			for i := range args {
				args[i] = strings.Trim(string(cmds[1+i]), "\"'")
			}
			r, err := c.Do(cmds[0], args...)
			if strings.ToLower(cmds[0]) == "select" {
				*dbnum, _ = strconv.Atoi(cmds[1])
			}
			if err != nil {
				fmt.Printf("%s", err.Error())
			} else {
				printReply(cmd, r)
			}

			fmt.Printf("\n")
		}
	}
}

func printReply(cmd string, reply interface{}) {
	switch reply := reply.(type) {
	case int64:
		fmt.Printf("(integer) %d", reply)
	case string:
		fmt.Printf("%s", reply)
	case []byte:
		fmt.Printf("%q", reply)
	case nil:
		fmt.Printf("(nil)")
	case ledis.Error:
		fmt.Printf("%s", string(reply))
	case []interface{}:
		for i, v := range reply {
			fmt.Printf("%d) ", i+1)
			if v == nil {
				fmt.Printf("(nil)")
			} else {
				fmt.Printf("%q", v)
			}
			if i != len(reply)-1 {
				fmt.Printf("\n")
			}
		}
	default:
		fmt.Printf("invalid ledis reply")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/siddontang/ledisdb/client/go/ledis"
	"regexp"
	"strings"
)

var ip = flag.String("h", "127.0.0.1", "ledisdb server ip (default 127.0.0.1)")
var port = flag.Int("p", 6380, "ledisdb server port (default 6380)")
var socket = flag.String("s", "", "ledisdb server socket, overwrite ip and port")

func main() {
	flag.Parse()

	cfg := new(ledis.Config)
	if len(*socket) > 0 {
		cfg.Addr = *socket
	} else {
		cfg.Addr = fmt.Sprintf("%s:%d", *ip, *port)
	}

	cfg.MaxIdleConns = 1

	c := ledis.NewClient(cfg)

	setHistoryCapacity(100)

	reg, _ := regexp.Compile(`'.*?'|".*?"|\S+`)

	for {
		cmd, err := line(fmt.Sprintf("%s> ", cfg.Addr))
		if err != nil {
			fmt.Printf("%s\n", err.Error())
			return
		}

		cmds := reg.FindAllString(cmd, -1)
		if len(cmds) == 0 {
			continue
		} else {
			addHistory(cmd)

			args := make([]interface{}, len(cmds[1:]))
			for i := range args {
				args[i] = strings.Trim(string(cmds[1+i]), "\"'")
			}
			r, err := c.Do(cmds[0], args...)
			if err != nil {
				fmt.Printf("%s", err.Error())
			} else {
				printReply(cmd, r)
			}

			fmt.Printf("\n")
		}
	}
}

func printReply(cmd string, reply interface{}) {
	switch reply := reply.(type) {
	case int64:
		fmt.Printf("(integer) %d", reply)
	case string:
		fmt.Printf("%s", reply)
	case []byte:
		fmt.Printf("%s", string(reply))
	case nil:
		fmt.Printf("(nil)")
	case ledis.Error:
		fmt.Printf("%s", string(reply))
	case []interface{}:
		for i, v := range reply {
			fmt.Printf("%d) ", i+1)
			if v == nil {
				fmt.Printf("(nil)")
			} else {
				fmt.Printf("%q", v)
			}
			if i != len(reply)-1 {
				fmt.Printf("\n")
			}
		}
	default:
		fmt.Printf("invalid ledis reply")
	}
}
<commit_msg>fix unprintable character<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/siddontang/ledisdb/client/go/ledis"
	"regexp"
	"strings"
)

var ip = flag.String("h", "127.0.0.1", "ledisdb server ip (default 127.0.0.1)")
var port = flag.Int("p", 6380, "ledisdb server port (default 6380)")
var socket = flag.String("s", "", "ledisdb server socket, overwrite ip and port")

func main() {
	flag.Parse()

	cfg := new(ledis.Config)
	if len(*socket) > 0 {
		cfg.Addr = *socket
	} else {
		cfg.Addr = fmt.Sprintf("%s:%d", *ip, *port)
	}

	cfg.MaxIdleConns = 1

	c := ledis.NewClient(cfg)

	setHistoryCapacity(100)

	reg, _ := regexp.Compile(`'.*?'|".*?"|\S+`)

	for {
		cmd, err := line(fmt.Sprintf("%s> ", cfg.Addr))
		if err != nil {
			fmt.Printf("%s\n", err.Error())
			return
		}

		cmds := reg.FindAllString(cmd, -1)
		if len(cmds) == 0 {
			continue
		} else {
			addHistory(cmd)

			args := make([]interface{}, len(cmds[1:]))
			for i := range args {
				args[i] = strings.Trim(string(cmds[1+i]), "\"'")
			}
			r, err := c.Do(cmds[0], args...)
			if err != nil {
				fmt.Printf("%s", err.Error())
			} else {
				printReply(cmd, r)
			}

			fmt.Printf("\n")
		}
	}
}

func printReply(cmd string, reply interface{}) {
	switch reply := reply.(type) {
	case int64:
		fmt.Printf("(integer) %d", reply)
	case string:
		fmt.Printf("%s", reply)
	case []byte:
		fmt.Printf("%q", reply)
	case nil:
		fmt.Printf("(nil)")
	case ledis.Error:
		fmt.Printf("%s", string(reply))
	case []interface{}:
		for i, v := range reply {
			fmt.Printf("%d) ", i+1)
			if v == nil {
				fmt.Printf("(nil)")
			} else {
				fmt.Printf("%q", v)
			}
			if i != len(reply)-1 {
				fmt.Printf("\n")
			}
		}
	default:
		fmt.Printf("invalid ledis reply")
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2015-2021 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package cmd

import "errors"

// errUnexpected - unexpected error, requires manual intervention.
var errUnexpected = StorageErr("unexpected error, please report this issue at https://github.com/minio/minio/issues")

// errCorruptedFormat - corrupted backend format.
var errCorruptedFormat = StorageErr("corrupted backend format, specified disk mount has unexpected previous content")

// errUnformattedDisk - unformatted disk found.
var errUnformattedDisk = StorageErr("unformatted disk found")

// errInconsistentDisk - inconsistent disk found.
var errInconsistentDisk = StorageErr("inconsistent disk found")

// errUnsupporteDisk - when disk does not support O_DIRECT flag.
var errUnsupportedDisk = StorageErr("disk does not support O_DIRECT")

// errDiskFull - cannot create volume or files when disk is full.
var errDiskFull = StorageErr("disk path full")

// errDiskNotDir - cannot use storage disk if its not a directory
var errDiskNotDir = StorageErr("disk is not directory or mountpoint")

// errDiskNotFound - cannot find the underlying configured disk anymore.
var errDiskNotFound = StorageErr("disk not found")

// errFaultyRemoteDisk - remote disk is faulty.
var errFaultyRemoteDisk = StorageErr("remote disk is faulty")

// errFaultyDisk - disk is faulty.
var errFaultyDisk = StorageErr("disk is faulty")

// errDiskAccessDenied - we don't have write permissions on disk.
var errDiskAccessDenied = StorageErr("disk access denied")

// errFileNotFound - cannot find the file.
var errFileNotFound = StorageErr("file not found")

// errFileNotFound - cannot find requested file version.
var errFileVersionNotFound = StorageErr("file version not found")

// errTooManyOpenFiles - too many open files.
var errTooManyOpenFiles = StorageErr("too many open files, please increase 'ulimit -n'")

// errFileNameTooLong - given file name is too long than supported length.
var errFileNameTooLong = StorageErr("file name too long")

// errVolumeExists - cannot create same volume again.
var errVolumeExists = StorageErr("volume already exists")

// errIsNotRegular - not of regular file type.
var errIsNotRegular = StorageErr("not of regular file type")

// errPathNotFound - cannot find the path.
var errPathNotFound = StorageErr("path not found")

// errVolumeNotFound - cannot find the volume.
var errVolumeNotFound = StorageErr("volume not found")

// errVolumeNotEmpty - volume not empty.
var errVolumeNotEmpty = StorageErr("volume is not empty")

// errVolumeAccessDenied - cannot access volume, insufficient permissions.
var errVolumeAccessDenied = StorageErr("volume access denied")

// errFileAccessDenied - cannot access file, insufficient permissions.
var errFileAccessDenied = StorageErr("file access denied")

// errFileCorrupt - file has an unexpected size, or is not readable
var errFileCorrupt = StorageErr("file is corrupted")

// errBitrotHashAlgoInvalid - the algo for bit-rot hash
// verification is empty or invalid.
var errBitrotHashAlgoInvalid = StorageErr("bit-rot hash algorithm is invalid")

// errCrossDeviceLink - rename across devices not allowed.
var errCrossDeviceLink = StorageErr("Rename across devices not allowed, please fix your backend configuration")

// errMinDiskSize - cannot create volume or files when disk size is less than threshold.
var errMinDiskSize = StorageErr("The disk size is less than 900MiB threshold")

// errLessData - returned when less data available than what was requested.
var errLessData = StorageErr("less data available than what was requested")

// errMoreData = returned when more data was sent by the caller than what it was supposed to.
var errMoreData = StorageErr("more data was sent than what was advertised")

// indicates readDirFn to return without further applying the fn()
var errDoneForNow = errors.New("done for now")

// errSkipFile returned by the fn() for readDirFn() when it needs
// to proceed to next entry.
var errSkipFile = errors.New("skip this file")

// StorageErr represents error generated by xlStorage call.
type StorageErr string

func (h StorageErr) Error() string {
	return string(h)
}

// Collection of basic errors.
var baseErrs = []error{
	errDiskNotFound,
	errFaultyDisk,
	errFaultyRemoteDisk,
}

var baseIgnoredErrs = baseErrs

// Is a one place function which converts all os.PathError
// into a more FS object layer friendly form, converts
// known errors into their typed form for top level
// interpretation.
func osErrToFileErr(err error) error {
	if err == nil {
		return nil
	}
	if osIsNotExist(err) {
		return errFileNotFound
	}
	if osIsPermission(err) {
		return errFileAccessDenied
	}
	if isSysErrNotDir(err) || isSysErrIsDir(err) {
		return errFileNotFound
	}
	if isSysErrPathNotFound(err) {
		return errFileNotFound
	}
	if isSysErrTooManyFiles(err) {
		return errTooManyOpenFiles
	}
	if isSysErrHandleInvalid(err) {
		return errFileNotFound
	}
	if isSysErrIO(err) {
		return errFaultyDisk
	}
	if isSysErrInvalidArg(err) {
		// For some odd calls with O_DIRECT reads
		// filesystems can return EINVAL, handle
		// these as FileNotFound instead.
		return errFileNotFound
	}
	if isSysErrNoSpace(err) {
		return errDiskFull
	}
	return err
}
<commit_msg>Print log when EINVALID is encountered in storage layer (#13341)<commit_after>// Copyright (c) 2015-2021 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package cmd

import (
	"context"
	"errors"

	"github.com/minio/minio/internal/logger"
)

// errUnexpected - unexpected error, requires manual intervention.
var errUnexpected = StorageErr("unexpected error, please report this issue at https://github.com/minio/minio/issues")

// errCorruptedFormat - corrupted backend format.
var errCorruptedFormat = StorageErr("corrupted backend format, specified disk mount has unexpected previous content")

// errUnformattedDisk - unformatted disk found.
var errUnformattedDisk = StorageErr("unformatted disk found")

// errInconsistentDisk - inconsistent disk found.
var errInconsistentDisk = StorageErr("inconsistent disk found")

// errUnsupporteDisk - when disk does not support O_DIRECT flag.
var errUnsupportedDisk = StorageErr("disk does not support O_DIRECT")

// errDiskFull - cannot create volume or files when disk is full.
var errDiskFull = StorageErr("disk path full")

// errDiskNotDir - cannot use storage disk if its not a directory
var errDiskNotDir = StorageErr("disk is not directory or mountpoint")

// errDiskNotFound - cannot find the underlying configured disk anymore.
var errDiskNotFound = StorageErr("disk not found")

// errFaultyRemoteDisk - remote disk is faulty.
var errFaultyRemoteDisk = StorageErr("remote disk is faulty")

// errFaultyDisk - disk is faulty.
var errFaultyDisk = StorageErr("disk is faulty")

// errDiskAccessDenied - we don't have write permissions on disk.
var errDiskAccessDenied = StorageErr("disk access denied")

// errFileNotFound - cannot find the file.
var errFileNotFound = StorageErr("file not found")

// errFileNotFound - cannot find requested file version.
var errFileVersionNotFound = StorageErr("file version not found")

// errTooManyOpenFiles - too many open files.
var errTooManyOpenFiles = StorageErr("too many open files, please increase 'ulimit -n'")

// errFileNameTooLong - given file name is too long than supported length.
var errFileNameTooLong = StorageErr("file name too long")

// errVolumeExists - cannot create same volume again.
var errVolumeExists = StorageErr("volume already exists")

// errIsNotRegular - not of regular file type.
var errIsNotRegular = StorageErr("not of regular file type")

// errPathNotFound - cannot find the path.
var errPathNotFound = StorageErr("path not found")

// errVolumeNotFound - cannot find the volume.
var errVolumeNotFound = StorageErr("volume not found")

// errVolumeNotEmpty - volume not empty.
var errVolumeNotEmpty = StorageErr("volume is not empty")

// errVolumeAccessDenied - cannot access volume, insufficient permissions.
var errVolumeAccessDenied = StorageErr("volume access denied")

// errFileAccessDenied - cannot access file, insufficient permissions.
var errFileAccessDenied = StorageErr("file access denied")

// errFileCorrupt - file has an unexpected size, or is not readable
var errFileCorrupt = StorageErr("file is corrupted")

// errBitrotHashAlgoInvalid - the algo for bit-rot hash
// verification is empty or invalid.
var errBitrotHashAlgoInvalid = StorageErr("bit-rot hash algorithm is invalid")

// errCrossDeviceLink - rename across devices not allowed.
var errCrossDeviceLink = StorageErr("Rename across devices not allowed, please fix your backend configuration")

// errMinDiskSize - cannot create volume or files when disk size is less than threshold.
var errMinDiskSize = StorageErr("The disk size is less than 900MiB threshold")

// errLessData - returned when less data available than what was requested.
var errLessData = StorageErr("less data available than what was requested")

// errMoreData = returned when more data was sent by the caller than what it was supposed to.
var errMoreData = StorageErr("more data was sent than what was advertised")

// indicates readDirFn to return without further applying the fn()
var errDoneForNow = errors.New("done for now")

// errSkipFile returned by the fn() for readDirFn() when it needs
// to proceed to next entry.
var errSkipFile = errors.New("skip this file")

// StorageErr represents error generated by xlStorage call.
type StorageErr string

func (h StorageErr) Error() string {
	return string(h)
}

// Collection of basic errors.
var baseErrs = []error{
	errDiskNotFound,
	errFaultyDisk,
	errFaultyRemoteDisk,
}

var baseIgnoredErrs = baseErrs

// Is a one place function which converts all os.PathError
// into a more FS object layer friendly form, converts
// known errors into their typed form for top level
// interpretation.
func osErrToFileErr(err error) error {
	if err == nil {
		return nil
	}
	if osIsNotExist(err) {
		return errFileNotFound
	}
	if osIsPermission(err) {
		return errFileAccessDenied
	}
	if isSysErrNotDir(err) || isSysErrIsDir(err) {
		return errFileNotFound
	}
	if isSysErrPathNotFound(err) {
		return errFileNotFound
	}
	if isSysErrTooManyFiles(err) {
		return errTooManyOpenFiles
	}
	if isSysErrHandleInvalid(err) {
		return errFileNotFound
	}
	if isSysErrIO(err) {
		return errFaultyDisk
	}
	if isSysErrInvalidArg(err) {
		logger.LogIf(context.Background(), err)
		// For some odd calls with O_DIRECT reads
		// filesystems can return EINVAL, handle
		// these as FileNotFound instead.
		return errFileNotFound
	}
	if isSysErrNoSpace(err) {
		return errDiskFull
	}
	return err
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"code.google.com/p/freetype-go/freetype"
	"code.google.com/p/freetype-go/freetype/truetype"
	"flag"
	"fmt"
	"github.com/errnoh/term.color"
	"github.com/sugyan/ttygif"
	"image"
	"image/color/palette"
	"image/draw"
	"image/gif"
	"io"
	"io/ioutil"
	"j4k.co/terminal"
	"os"
	"path/filepath"
)

var font *truetype.Font

const fontSize = 18

func init() {
	fontData, err := Asset("font/Anonymous Pro Minus.ttf")
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	font, err = freetype.ParseFont(fontData)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func main() {
	input := flag.String("in", "ttyrecord", "input ttyrec file")
	output := flag.String("out", "tty.gif", "output gif file")
	speed := flag.Float64("s", 1.0, "play speed")
	flag.Parse()

	err := generateGIF(*input, *output, *speed)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	absPath, err := filepath.Abs(*output)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	fmt.Printf("%s created!\n", absPath)
}

func generateGIF(input string, output string, speed float64) (err error) {
	// input
	inFile, err := os.Open(input)
	if err != nil {
		return
	}
	defer inFile.Close()

	// virtual terminal
	var state = terminal.State{}
	vt, err := terminal.Create(&state, ioutil.NopCloser(bytes.NewBuffer([]byte{})))
	if err != nil {
		return
	}
	defer vt.Close()

	// read ttyrecord
	reader := ttygif.NewTtyReader(inFile)
	var (
		first  = true
		prevTv ttygif.TimeVal
		images []*image.Paletted
		delays []int
	)
	for {
		var data *ttygif.TtyData
		data, err = reader.ReadData()
		if err != nil {
			if err == io.EOF {
				break
			} else {
				return
			}
		}
		var diff ttygif.TimeVal
		if first {
			first = false
		} else {
			diff = data.TimeVal.Subtract(prevTv)
		}
		prevTv = data.TimeVal

		// calc delay and capture
		delay := int(float64(diff.Sec*1000000+diff.Usec)/speed) / 10000
		if delay > 0 {
			var img *image.Paletted
			img, err = capture(&state)
			if err != nil {
				return
			}
			images = append(images, img)
			delays = append(delays, delay)
		}
		// write to vt
		_, err = vt.Write(*data.Buffer)
		if err != nil {
			return
		}
	}

	outFile, err := os.Create(output)
	err = gif.EncodeAll(outFile, &gif.GIF{
		Image: images,
		Delay: delays,
	})
	if err != nil {
		return
	}
	return nil
}

func capture(state *terminal.State) (paletted *image.Paletted, err error) {
	fb := font.Bounds(fontSize)

	paletted = image.NewPaletted(image.Rect(0, 0, 80*int(fb.XMax-fb.XMin)+10, 24*int(fb.YMax-fb.YMin)), palette.WebSafe)
	draw.Draw(paletted, paletted.Bounds(), image.Black, image.ZP, draw.Src)
	c := freetype.NewContext()
	c.SetFont(font)
	c.SetFontSize(fontSize)
	c.SetDst(paletted)
	c.SetClip(paletted.Bounds())
	for row := 0; row < 24; row++ {
		for col := 0; col < 80; col++ {
			ch, fg, bg := state.Cell(col, row)
			if bg != terminal.DefaultBG {
				uniform := image.NewUniform(color.Term256{Val: uint8(bg)})
				draw.Draw(paletted, image.Rect(5+col*int(fb.XMax-fb.XMin), row*int(fb.YMax-fb.YMin)-int(fb.YMin), 5+(col+1)*int(fb.XMax-fb.XMin), (row+1)*int(fb.YMax-fb.YMin)-int(fb.YMin)), uniform, image.ZP, draw.Src)
			}
			switch fg {
			case terminal.DefaultFG:
				c.SetSrc(image.White)
			case terminal.DefaultBG:
				c.SetSrc(image.Black)
			default:
				c.SetSrc(image.NewUniform(color.Term256{Val: uint8(fg)}))
			}
			str := string(ch)
			_, err = c.DrawString(str, freetype.Pt(5+col*int(fb.XMax-fb.XMin), (row+1)*int(fb.YMax-fb.YMin)))
			if err != nil {
				return
			}
		}
	}

	return paletted, nil
}
<commit_msg>use cursor<commit_after>package main

import (
	"bytes"
	"code.google.com/p/freetype-go/freetype"
	"code.google.com/p/freetype-go/freetype/truetype"
	"flag"
	"fmt"
	tcolor "github.com/errnoh/term.color"
	"github.com/sugyan/ttygif"
	"image"
	"image/color"
	"image/color/palette"
	"image/draw"
	"image/gif"
	"io"
	"io/ioutil"
	"j4k.co/terminal"
	"os"
	"path/filepath"
)

var font *truetype.Font

const fontSize = 18

func init() {
	fontData, err := Asset("font/Anonymous Pro Minus.ttf")
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	font, err = freetype.ParseFont(fontData)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func main() {
	input := flag.String("in", "ttyrecord", "input ttyrec file")
	output := flag.String("out", "tty.gif", "output gif file")
	speed := flag.Float64("s", 1.0, "play speed")
	flag.Parse()

	err := generateGIF(*input, *output, *speed)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	absPath, err := filepath.Abs(*output)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	fmt.Printf("%s created!\n", absPath)
}

func generateGIF(input string, output string, speed float64) (err error) {
	// input
	inFile, err := os.Open(input)
	if err != nil {
		return
	}
	defer inFile.Close()

	// virtual terminal
	var state = terminal.State{}
	vt, err := terminal.Create(&state, ioutil.NopCloser(bytes.NewBuffer([]byte{})))
	if err != nil {
		return
	}
	defer vt.Close()

	// read ttyrecord
	reader := ttygif.NewTtyReader(inFile)
	var (
		first  = true
		prevTv ttygif.TimeVal
		images []*image.Paletted
		delays []int
	)
	for {
		var data *ttygif.TtyData
		data, err = reader.ReadData()
		if err != nil {
			if err == io.EOF {
				break
			} else {
				return
			}
		}
		var diff ttygif.TimeVal
		if first {
			first = false
		} else {
			diff = data.TimeVal.Subtract(prevTv)
		}
		prevTv = data.TimeVal

		// calc delay and capture
		delay := int(float64(diff.Sec*1000000+diff.Usec)/speed) / 10000
		if delay > 0 {
			var img *image.Paletted
			img, err = capture(&state)
			if err != nil {
				return
			}
			images = append(images, img)
			delays = append(delays, delay)
		}
		// write to vt
		_, err = vt.Write(*data.Buffer)
		if err != nil {
			return
		}
	}

	outFile, err := os.Create(output)
	err = gif.EncodeAll(outFile, &gif.GIF{
		Image: images,
		Delay: delays,
	})
	if err != nil {
		return
	}
	return nil
}

func capture(state *terminal.State) (paletted *image.Paletted, err error) {
	cursorX, cursorY := state.Cursor()
	fb := font.Bounds(fontSize)

	paletted = image.NewPaletted(image.Rect(0, 0, 80*int(fb.XMax-fb.XMin)+10, 24*int(fb.YMax-fb.YMin)), palette.WebSafe)
	draw.Draw(paletted, paletted.Bounds(), image.Black, image.ZP, draw.Src)
	c := freetype.NewContext()
	c.SetFont(font)
	c.SetFontSize(fontSize)
	c.SetDst(paletted)
	c.SetClip(paletted.Bounds())
	for row := 0; row < 24; row++ {
		for col := 0; col < 80; col++ {
			cursor := col == cursorX && row == cursorY
			ch, fg, bg := state.Cell(col, row)
			if bg != terminal.DefaultBG || cursor {
				var uniform *image.Uniform
				if cursor {
					uniform = image.NewUniform(color.Gray16{0x8888})
				} else {
					uniform = image.NewUniform(tcolor.Term256{Val: uint8(bg)})
				}
				draw.Draw(paletted, image.Rect(5+col*int(fb.XMax-fb.XMin), row*int(fb.YMax-fb.YMin)-int(fb.YMin), 5+(col+1)*int(fb.XMax-fb.XMin), (row+1)*int(fb.YMax-fb.YMin)-int(fb.YMin)), uniform, image.ZP, draw.Src)
			}
			switch fg {
			case terminal.DefaultFG:
				c.SetSrc(image.White)
			case terminal.DefaultBG:
				c.SetSrc(image.Black)
			default:
				c.SetSrc(image.NewUniform(tcolor.Term256{Val: uint8(fg)}))
			}
			str := string(ch)
			_, err = c.DrawString(str, freetype.Pt(5+col*int(fb.XMax-fb.XMin), (row+1)*int(fb.YMax-fb.YMin)))
			if err != nil {
				return
			}
		}
	}

	return paletted, nil
}
<|endoftext|>


<commit_before>// Copyright 2021 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// Derived work from Daniel Martí <mvdan@mvdan.cc>

package main

import (
	"context"
	"flag"
	"fmt"
	"io"
	"os"
	"strings"

	prompt "github.com/c-bata/go-prompt"
	"github.com/c-bata/go-prompt/completer"
	"golang.org/x/term"

	"mvdan.cc/sh/v3/interp"
	"mvdan.cc/sh/v3/syntax"
)

var notabCompletion = flag.Bool("notabcomp", false, "Disable tab completion.")

type input interface {
	Input(prefix string, completer prompt.Completer, opts ...prompt.Option) string
}

type inputPrompt struct{}

func (i inputPrompt) Input(prefix string, completer prompt.Completer, opts ...prompt.Option) string {
	return prompt.Input(prefix, completer, opts...)
}

type shell struct {
	input
}

func main() {
	flag.Parse()
	sh := shell{
		input: inputPrompt{},
	}
	err := sh.runAll(flag.NArg())
	if e, ok := interp.IsExitStatus(err); ok {
		os.Exit(int(e))
	}
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func (s shell) runAll(narg int) error {
	r, err := interp.New(interp.StdIO(os.Stdin, os.Stdout, os.Stderr))
	if err != nil {
		return err
	}

	if narg > 0 {
		return s.run(r, strings.NewReader(strings.Join(flag.Args(), " ")), "")
	}
	if narg == 0 {
		if term.IsTerminal(int(os.Stdin.Fd())) {
			if !*notabCompletion {
				return s.runInteractiveTabCompletion(r, os.Stdout)
			}
			return s.runInteractive(r, os.Stdin, os.Stdout)
		}
		return s.run(r, os.Stdin, "")
	}
	return nil
}

func (s shell) run(r *interp.Runner, reader io.Reader, name string) error {
	prog, err := syntax.NewParser().Parse(reader, name)
	if err != nil {
		return err
	}
	r.Reset()
	return r.Run(context.Background(), prog)
}

func (s shell) runInteractive(r *interp.Runner, stdin io.Reader, stdout io.Writer) error {
	parser := syntax.NewParser()
	fmt.Fprintf(stdout, "$ ")
	var runErr error
	if err := parser.Interactive(stdin, func(stmts []*syntax.Stmt) bool {
		if parser.Incomplete() {
			fmt.Fprintf(stdout, "> ")
			return true
		}
		for _, stmt := range stmts {
			runErr = r.Run(context.Background(), stmt)
			if r.Exited() {
				return false
			}
		}
		fmt.Fprintf(stdout, "$ ")
		return true
	}); err != nil {
		return err
	}
	return runErr
}

func (s shell) runInteractiveTabCompletion(r *interp.Runner, stdout io.Writer) error {
	parser := syntax.NewParser()
	if s.input == nil {
		s.input = inputPrompt{}
	}
	var runErr error
	for {
		in := s.Input(
			"$ ",
			completerFunc,
			prompt.OptionCompletionWordSeparator(completer.FilePathCompletionSeparator),
		)
		if in == "exit" {
			break
		}
		if err := parser.Stmts(strings.NewReader(in), func(stmt *syntax.Stmt) bool {
			if parser.Incomplete() {
				fmt.Fprintf(stdout, "> ")
				return true
			}
			runErr = r.Run(context.Background(), stmt)
			return !r.Exited()
		}); err != nil {
			return err
		}
	}
	return runErr
}
<commit_msg>Change gosh tabcomp default<commit_after>// Copyright 2021 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// Derived work from Daniel Martí <mvdan@mvdan.cc>

package main

import (
	"context"
	"flag"
	"fmt"
	"io"
	"os"
	"strings"

	prompt "github.com/c-bata/go-prompt"
	"github.com/c-bata/go-prompt/completer"
	"golang.org/x/term"

	"mvdan.cc/sh/v3/interp"
	"mvdan.cc/sh/v3/syntax"
)

var tabCompletion = flag.Bool("tabcomp", false, "Enable tab completion.")

type input interface {
	Input(prefix string, completer prompt.Completer, opts ...prompt.Option) string
}

type inputPrompt struct{}

func (i inputPrompt) Input(prefix string, completer prompt.Completer, opts ...prompt.Option) string {
	return prompt.Input(prefix, completer, opts...)
}

type shell struct {
	input
}

func main() {
	flag.Parse()

	sh := shell{
		input: inputPrompt{},
	}

	err := sh.runAll(flag.NArg())

	if e, ok := interp.IsExitStatus(err); ok {
		os.Exit(int(e))
	}

	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func (s shell) runAll(narg int) error {
	r, err := interp.New(interp.StdIO(os.Stdin, os.Stdout, os.Stderr))
	if err != nil {
		return err
	}

	if narg > 0 {
		return s.run(r, strings.NewReader(strings.Join(flag.Args(), " ")), "")
	}

	if narg == 0 {
		if term.IsTerminal(int(os.Stdin.Fd())) {
			if *tabCompletion {
				return s.runInteractiveTabCompletion(r, os.Stdout)
			}

			fmt.Println("Do get tabcompletion run 'gosh -tabcomp'\nThis will only work with a working framebuffer for now")

			return s.runInteractive(r, os.Stdin, os.Stdout)
		}

		return s.run(r, os.Stdin, "")
	}

	return nil
}

func (s shell) run(r *interp.Runner, reader io.Reader, name string) error {
	prog, err := syntax.NewParser().Parse(reader, name)
	if err != nil {
		return err
	}

	r.Reset()

	return r.Run(context.Background(), prog)
}

func (s shell) runInteractive(r *interp.Runner, stdin io.Reader, stdout io.Writer) error {
	parser := syntax.NewParser()

	fmt.Fprintf(stdout, "$ ")

	var runErr error

	if err := parser.Interactive(stdin, func(stmts []*syntax.Stmt) bool {
		if parser.Incomplete() {
			fmt.Fprintf(stdout, "> ")

			return true
		}
		for _, stmt := range stmts {
			runErr = r.Run(context.Background(), stmt)
			if r.Exited() {
				return false
			}
		}
		fmt.Fprintf(stdout, "$ ")

		return true
	}); err != nil {
		return err
	}

	return runErr
}

func (s shell) runInteractiveTabCompletion(r *interp.Runner, stdout io.Writer) error {
	parser := syntax.NewParser()

	if s.input == nil {
		s.input = inputPrompt{}
	}

	var runErr error

	// TODO(MDr164): Has a tendency to panic when no framebuffer is available.
	defer func() {
		if err := recover(); err != nil {
			runErr = fmt.Errorf("failed to initialize tabcompletion, falling back to no tabcompletion")
		}
	}()

	for {
		if runErr != nil {
			break
		}

		in := s.Input(
			"$ ",
			completerFunc,
			prompt.OptionCompletionWordSeparator(completer.FilePathCompletionSeparator),
		)

		if in == "exit" {
			break
		}

		if err := parser.Stmts(strings.NewReader(in), func(stmt *syntax.Stmt) bool {
			if parser.Incomplete() {
				fmt.Fprintf(stdout, "> ")

				return true
			}

			runErr = r.Run(context.Background(), stmt)

			return !r.Exited()
		}); err != nil {
			return err
		}
	}

	return runErr
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/mrspock/godocsis"
	"net"
	"os"
	"strings"
	//"strings"
)

const (
	VERSION string = "1.0.4"
	AUTHOR  string = "Marcin Jurczuk"
	EMAIL   string = "marcin@jurczuk.eu"
)

func main() {
	app := cli.NewApp()
	app.Name = "cmforward"
	app.Usage = "automatic add, remove forwarding rules for Technicolor TC7200 Cable modem and connected NP devices"
	app.Version = VERSION
	app.Author = AUTHOR
	app.Email = EMAIL
	app.CommandNotFound = func(ctx *cli.Context, command string) {
		fmt.Fprintf(os.Stderr, "\n%s action not found.\n\n", command)
		cli.ShowAppHelp(ctx)
	}
	app.Commands = []cli.Command{
		{
			Name:  "add",
			Usage: "add forwarding rules",
			Flags: []cli.Flag{
				cli.IntFlag{
					Name:  "extport,ep",
					Value: 5001,
					Usage: "External starting port (incomming connection). If multiple devices are connected next will get export+1 value",
				},
			},
			Action: AddFwdRules,
		},
		{
			Name:   "del",
			Usage:  "delete forwarding rules (currently does nothing !! - see TC bug #1-104377764)\n\tSyntax: del <CM_IP> <rule_no1> <rule_no2> <rule_no_N>",
			Action: DelFwdRules,
		},
	}
	app.Run(os.Args)
}

func AddFwdRules(c *cli.Context) {
	var ip string
	var localIP string
	var startPort int
	startPort = c.Int("extport")
	fmt.Println("ExtPort:", startPort)
	var extIP string

	if len(c.Args()) < 1 {
		fmt.Fprintf(os.Stderr, "NG: Missing argument - cm ip address.")
		return
	} else {
		ip = c.Args().First()
		//localIP = flag.Arg(1)
	}

	s := godocsis.Session
	s.Target = ip
	s.Community = "private"
	// forward rules
	forwardRule := godocsis.CgForwardRule{}
	forwardRule.LocalIP = net.ParseIP(localIP)
	//forwardRule.RuleName = "Test"
	forwardRule.ExtPortStart = 5001
	forwardRule.LocalPortStart = 22
	forwardRule.ProtocolType = godocsis.Tcp
	forwardRule.IPAddrType = godocsis.IPv4
	//fmt.Println(s.Target, "device list:")
	devices, err := godocsis.CmGetNetiaPlayerList(s)
	if err != nil {
		fmt.Fprintf(os.Stderr, "NG: %s", err)
		return
	}
	if len(devices) > 0 {
		cm, err := godocsis.GetRouterIP(s)
		if err != nil {
			fmt.Fprintf(os.Stderr, "WARN: Unable to get externam router IP")
			//perr()
		}
		extIP = cm.RouterIP
	} else {
		fmt.Fprintf(os.Stdout, "NG: No NetiaPlayer devices found behind cable modem\n")
		os.Exit(0)
		extIP = "unknown"
	}
	for _, device := range devices {
		fmt.Println("NP detected:", device.IPAddr.String()+"\t"+device.MacAddr.String()+"\t"+device.Name)
		forwardRule.LocalIP = net.ParseIP(device.IPAddr.String())
		//forwardRule.ExtPortStart = startPort
		forwardRule.RuleName = strings.Replace(device.Name, "NetiaPlayer", "NP", -1)
		startPort++
		//fmt.Println(forwardRule)
		err = forwardRule.Validate()

		if err != nil {
			fmt.Println(err)
			continue
		}
		err = godocsis.CmSetForwardRule(s, &forwardRule, godocsis.TC7200ForwardingTree)
		if err != nil {
			fmt.Println(err)
			continue
		}
		fmt.Println("OK:", s.Target, "rules set. CM Router IP:", extIP, "external port:", startPort)
	}
	//ruleCount, err := godocsis.CmGetFwdRuleCount(s, godocsis.TC7200ForwardingTree)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s", err)
	}
	//fmt.Println("Liczba aktwnych reguł:", ruleCount)
	// fmt.Println(forwardRule)
}

func DelFwdRules(c *cli.Context) {
	fmt.Fprintf(os.Stdout, "OK: Rules removed\n")
}
<commit_msg>msg fix<commit_after>package main

import (
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/mrspock/godocsis"
	"net"
	"os"
	"strings"
	//"strings"
)

const (
	VERSION string = "1.0.4"
	AUTHOR  string = "Marcin Jurczuk"
	EMAIL   string = "marcin@jurczuk.eu"
)

func main() {
	app := cli.NewApp()
	app.Name = "cmforward"
	app.Usage = "automatic add, remove forwarding rules for Technicolor TC7200 Cable modem and connected NP devices"
	app.Version = VERSION
	app.Author = AUTHOR
	app.Email = EMAIL
	app.CommandNotFound = func(ctx *cli.Context, command string) {
		fmt.Fprintf(os.Stderr, "\n%s action not found.\n\n", command)
		cli.ShowAppHelp(ctx)
	}
	app.Commands = []cli.Command{
		{
			Name:  "add",
			Usage: "add forwarding rules",
			Flags: []cli.Flag{
				cli.IntFlag{
					Name:  "extport,ep",
					Value: 5001,
					Usage: "External starting port (incomming connection). If multiple devices are connected next will get export+1 value",
				},
			},
			Action: AddFwdRules,
		},
		{
			Name:   "del",
			Usage:  "delete forwarding rules (currently does nothing !! - see TC bug #1-104377764)\n\tSyntax: del <CM_IP> <rule_no1> <rule_no2> <rule_no_N>",
			Action: DelFwdRules,
		},
	}
	app.Run(os.Args)
}

func AddFwdRules(c *cli.Context) {
	var ip string
	var localIP string
	var startPort int
	startPort = c.Int("extport")
	beginPort := startPort
	fmt.Println("ExtPort:", startPort)
	var extIP string

	if len(c.Args()) < 1 {
		fmt.Fprintf(os.Stderr, "NG: Missing argument - cm ip address.")
		return
	} else {
		ip = c.Args().First()
		//localIP = flag.Arg(1)
	}

	s := godocsis.Session
	s.Target = ip
	s.Community = "private"
	// forward rules
	forwardRule := godocsis.CgForwardRule{}
	forwardRule.LocalIP = net.ParseIP(localIP)
	//forwardRule.RuleName = "Test"
	forwardRule.ExtPortStart = startPort
	forwardRule.LocalPortStart = 22
	forwardRule.ProtocolType = godocsis.Tcp
	forwardRule.IPAddrType = godocsis.IPv4
	//fmt.Println(s.Target, "device list:")
	devices, err := godocsis.CmGetNetiaPlayerList(s)
	if err != nil {
		fmt.Fprintf(os.Stderr, "NG: %s", err)
		return
	}
	if len(devices) > 0 {
		cm, err := godocsis.GetRouterIP(s)
		if err != nil {
			fmt.Fprintf(os.Stderr, "WARN: Unable to get externam router IP")
			//perr()
		}
		extIP = cm.RouterIP
	} else {
		fmt.Fprintf(os.Stdout, "NG: No NetiaPlayer devices found behind cable modem\n")
		os.Exit(0)
		extIP = "unknown"
	}
	for _, device := range devices {
		fmt.Println("NP detected:", device.IPAddr.String()+"\t"+device.MacAddr.String()+"\t"+device.Name)
		forwardRule.LocalIP = net.ParseIP(device.IPAddr.String())
		//forwardRule.ExtPortStart = startPort
		forwardRule.RuleName = strings.Replace(device.Name, "NetiaPlayer", "NP", -1)
		startPort++
		//fmt.Println(forwardRule)
		err = forwardRule.Validate()

		if err != nil {
			fmt.Println(err)
			continue
		}
		err = godocsis.CmSetForwardRule(s, &forwardRule, godocsis.TC7200ForwardingTree)
		if err != nil {
			fmt.Println(err)
			continue
		}
		fmt.Println("OK:", s.Target, "rules set. CM Router IP:", extIP, "external port:", beginPort)
	}
	//ruleCount, err := godocsis.CmGetFwdRuleCount(s, godocsis.TC7200ForwardingTree)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s", err)
	}
	//fmt.Println("Liczba aktwnych reguł:", ruleCount)
	// fmt.Println(forwardRule)
}

func DelFwdRules(c *cli.Context) {
	fmt.Fprintf(os.Stdout, "OK: Rules removed\n")
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
)

func TestAccDataSourceAwsRoute53ResolverRules_basic(t *testing.T) {
	dsResourceName := "data.aws_route53_resolver_rules.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			{
				Config: testAccDataSourceAwsRoute53ResolverRules_basic,
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr(dsResourceName, "resolver_rule_ids.#", "1"),
					resource.TestCheckResourceAttr(dsResourceName, "resolver_rule_ids.1743502667", "rslvr-autodefined-rr-internet-resolver"),
				),
			},
		},
	})
}

func TestAccDataSourceAwsRoute53ResolverRules_ResolverEndpointId(t *testing.T) {
	rName1 := fmt.Sprintf("tf-testacc-r53-resolver-%s", acctest.RandStringFromCharSet(8, acctest.CharSetAlphaNum))
	rName2 := fmt.Sprintf("tf-testacc-r53-resolver-%s", acctest.RandStringFromCharSet(8, acctest.CharSetAlphaNum))
	ds1ResourceName := "data.aws_route53_resolver_rules.by_resolver_endpoint_id"
	ds2ResourceName := "data.aws_route53_resolver_rules.by_resolver_endpoint_id_rule_type_share_status"
	ds3ResourceName := "data.aws_route53_resolver_rules.by_invalid_owner_id"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			{
				Config: testAccDataSourceAwsRoute53ResolverRules_resolverEndpointId(rName1, rName2),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr(ds1ResourceName, "resolver_rule_ids.#", "1"),
					resource.TestCheckResourceAttr(ds2ResourceName, "resolver_rule_ids.#", "1"),
					resource.TestCheckResourceAttr(ds3ResourceName, "resolver_rule_ids.#", "0"),
				),
			},
		},
	})
}

const testAccDataSourceAwsRoute53ResolverRules_basic = `
# The default Internet Resolver rule.
data "aws_route53_resolver_rules" "test" {
  owner_id     = "Route 53 Resolver"
  rule_type    = "RECURSIVE"
  share_status = "NOT_SHARED"
}
`

func testAccDataSourceAwsRoute53ResolverRules_resolverEndpointId(rName1, rName2 string) string {
	return testAccRoute53ResolverRuleConfig_resolverEndpoint(rName1) + fmt.Sprintf(`
resource "aws_route53_resolver_rule" "forward" {
  domain_name = "%[1]s.example.com"
  rule_type   = "FORWARD"
  name        = %[1]q

  resolver_endpoint_id = "${aws_route53_resolver_endpoint.bar.id}"

  target_ip {
    ip = "192.0.2.7"
  }
}

resource "aws_route53_resolver_rule" "system" {
  domain_name = "%[2]s.example.org"
  rule_type   = "SYSTEM"
  name        = %[2]q
}

data "aws_route53_resolver_rules" "by_resolver_endpoint_id" {
  owner_id             = "${aws_route53_resolver_rule.forward.owner_id}"
  resolver_endpoint_id = "${aws_route53_resolver_rule.forward.resolver_endpoint_id}"
}

data "aws_route53_resolver_rules" "by_resolver_endpoint_id_rule_type_share_status" {
  owner_id             = "${aws_route53_resolver_rule.system.owner_id}"
  resolver_endpoint_id = "${aws_route53_resolver_rule.system.resolver_endpoint_id}"
  rule_type            = "${aws_route53_resolver_rule.system.rule_type}"
  share_status         = "${aws_route53_resolver_rule.system.share_status}"
}

data "aws_route53_resolver_rules" "by_invalid_owner_id" {
  owner_id     = "000000000000"
  share_status = "SHARED_WITH_ME"
}
`, rName1, rName2)
}
<commit_msg>Update test configuration to narrow search scope<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
)

func TestAccDataSourceAwsRoute53ResolverRules_basic(t *testing.T) {
	dsResourceName := "data.aws_route53_resolver_rules.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			{
				Config: testAccDataSourceAwsRoute53ResolverRules_basic,
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr(dsResourceName, "resolver_rule_ids.#", "1"),
					resource.TestCheckResourceAttr(dsResourceName, "resolver_rule_ids.1743502667", "rslvr-autodefined-rr-internet-resolver"),
				),
			},
		},
	})
}

func TestAccDataSourceAwsRoute53ResolverRules_ResolverEndpointId(t *testing.T) {
	rName1 := fmt.Sprintf("tf-testacc-r53-resolver-%s", acctest.RandStringFromCharSet(8, acctest.CharSetAlphaNum))
	rName2 := fmt.Sprintf("tf-testacc-r53-resolver-%s", acctest.RandStringFromCharSet(8, acctest.CharSetAlphaNum))
	ds1ResourceName := "data.aws_route53_resolver_rules.by_resolver_endpoint_id"
	ds2ResourceName := "data.aws_route53_resolver_rules.by_resolver_endpoint_id_rule_type_share_status"
	ds3ResourceName := "data.aws_route53_resolver_rules.by_invalid_owner_id"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			{
				Config: testAccDataSourceAwsRoute53ResolverRules_resolverEndpointId(rName1, rName2),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr(ds1ResourceName, "resolver_rule_ids.#", "1"),
					resource.TestCheckResourceAttr(ds2ResourceName, "resolver_rule_ids.#", "1"),
					resource.TestCheckResourceAttr(ds3ResourceName, "resolver_rule_ids.#", "0"),
				),
			},
		},
	})
}

const testAccDataSourceAwsRoute53ResolverRules_basic = `
# The default Internet Resolver rule.
data "aws_route53_resolver_rules" "test" {
  owner_id     = "Route 53 Resolver"
  rule_type    = "RECURSIVE"
  share_status = "NOT_SHARED"
}
`

func testAccDataSourceAwsRoute53ResolverRules_resolverEndpointId(rName1, rName2 string) string {
	return testAccRoute53ResolverRuleConfig_resolverEndpoint(rName1) + fmt.Sprintf(`
resource "aws_route53_resolver_rule" "forward" {
  domain_name = "%[1]s.example.com"
  rule_type   = "FORWARD"
  name        = %[1]q

  resolver_endpoint_id = "${aws_route53_resolver_endpoint.bar.id}"

  target_ip {
    ip = "192.0.2.7"
  }
}

resource "aws_route53_resolver_rule" "recursive" {
  domain_name = "%[2]s.example.org"
  rule_type   = "RECURSIVE"
  name        = %[2]q
}

data "aws_route53_resolver_rules" "by_resolver_endpoint_id" {
  owner_id             = "${aws_route53_resolver_rule.forward.owner_id}"
  resolver_endpoint_id = "${aws_route53_resolver_rule.forward.resolver_endpoint_id}"
}

data "aws_route53_resolver_rules" "by_resolver_endpoint_id_rule_type_share_status" {
  owner_id             = "${aws_route53_resolver_rule.recursive.owner_id}"
  resolver_endpoint_id = "${aws_route53_resolver_rule.recursive.resolver_endpoint_id}"
  rule_type            = "${aws_route53_resolver_rule.recursive.rule_type}"
  share_status         = "${aws_route53_resolver_rule.recursive.share_status}"
}

data "aws_route53_resolver_rules" "by_invalid_owner_id" {
  owner_id     = "000000000000"
  share_status = "SHARED_WITH_ME"
}
`, rName1, rName2)
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 	https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package safehttptest

import (
	"html/template"
	"io"
	"net/http"
	"strings"

	"github.com/google/go-safeweb/safehttp"
	"github.com/google/safehtml"
)

type testDispatcher struct{}

func (testDispatcher) Write(rw http.ResponseWriter, resp safehttp.Response) error {
	switch x := resp.(type) {
	case safehtml.HTML:
		_, err := rw.Write([]byte(x.String()))
		return err
	default:
		panic("not a safe response type")
	}
}

func (testDispatcher) ExecuteTemplate(rw http.ResponseWriter, t safehttp.Template, data interface{}) error {
	switch x := t.(type) {
	case *template.Template:
		return x.Execute(rw, data)
	default:
		panic("not a safe response type")
	}
}

// ResponseRecorder encapsulates a safehttp.ResponseWriter that records
// mutations for later inspection in tests. The safehttp.ResponseWriter
// should be passed as part of the handler function in tests.
type ResponseRecorder struct {
	safehttp.ResponseWriter
	rw *responseWriter
	b  *strings.Builder
}

// NewResponseRecorder creates a ResponseRecorder from the default testDispatcher.
func NewResponseRecorder() *ResponseRecorder {
	var b strings.Builder
	rw := newResponseWriter(&b)
	return &ResponseRecorder{
		rw:             rw,
		b:              &b,
		ResponseWriter: safehttp.NewResponseWriter(testDispatcher{}, rw, nil),
	}
}

// NewResponseRecorderFromDispatcher creates a ResponseRecorder from a
// provided safehttp.Dispatcher.
func NewResponseRecorderFromDispatcher(d safehttp.Dispatcher) *ResponseRecorder {
	var b strings.Builder
	rw := newResponseWriter(&b)
	return &ResponseRecorder{
		rw:             rw,
		b:              &b,
		ResponseWriter: safehttp.NewResponseWriter(d, rw, nil),
	}
}

// Header returns the recorded response headers.
func (r *ResponseRecorder) Header() http.Header {
	return r.rw.Header()
}

// Status returns the recorded response status code.
func (r *ResponseRecorder) Status() safehttp.StatusCode {
	return safehttp.StatusCode(r.rw.status)
}

// Body returns the recorded response body.
func (r *ResponseRecorder) Body() string {
	return r.b.String()
}

// responseWriter is an implementation of the http.ResponseWriter interface used
// for constructing an HTTP response.
type responseWriter struct {
	header http.Header
	writer io.Writer
	status int
}

func newResponseWriter(w io.Writer) *responseWriter {
	return &responseWriter{
		header: http.Header{},
		writer: w,
		status: http.StatusOK,
	}
}

func (r *responseWriter) Header() http.Header {
	return r.header
}

func (r *responseWriter) WriteHeader(statusCode int) {
	r.status = statusCode
}

func (r *responseWriter) Write(data []byte) (int, error) {
	return r.writer.Write(data)
}
<commit_msg>Changed safehttptest.responseWriter.status to safehttp.StatusCode instead of int.<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 	https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package safehttptest

import (
	"html/template"
	"io"
	"net/http"
	"strings"

	"github.com/google/go-safeweb/safehttp"
	"github.com/google/safehtml"
)

type testDispatcher struct{}

func (testDispatcher) Write(rw http.ResponseWriter, resp safehttp.Response) error {
	switch x := resp.(type) {
	case safehtml.HTML:
		_, err := rw.Write([]byte(x.String()))
		return err
	default:
		panic("not a safe response type")
	}
}

func (testDispatcher) ExecuteTemplate(rw http.ResponseWriter, t safehttp.Template, data interface{}) error {
	switch x := t.(type) {
	case *template.Template:
		return x.Execute(rw, data)
	default:
		panic("not a safe response type")
	}
}

// ResponseRecorder encapsulates a safehttp.ResponseWriter that records
// mutations for later inspection in tests. The safehttp.ResponseWriter
// should be passed as part of the handler function in tests.
type ResponseRecorder struct {
	safehttp.ResponseWriter
	rw *responseWriter
	b  *strings.Builder
}

// NewResponseRecorder creates a ResponseRecorder from the default testDispatcher.
func NewResponseRecorder() *ResponseRecorder {
	var b strings.Builder
	rw := newResponseWriter(&b)
	return &ResponseRecorder{
		rw:             rw,
		b:              &b,
		ResponseWriter: safehttp.NewResponseWriter(testDispatcher{}, rw, nil),
	}
}

// NewResponseRecorderFromDispatcher creates a ResponseRecorder from a
// provided safehttp.Dispatcher.
func NewResponseRecorderFromDispatcher(d safehttp.Dispatcher) *ResponseRecorder {
	var b strings.Builder
	rw := newResponseWriter(&b)
	return &ResponseRecorder{
		rw:             rw,
		b:              &b,
		ResponseWriter: safehttp.NewResponseWriter(d, rw, nil),
	}
}

// Header returns the recorded response headers.
func (r *ResponseRecorder) Header() http.Header {
	return r.rw.Header()
}

// Status returns the recorded response status code.
func (r *ResponseRecorder) Status() safehttp.StatusCode {
	return r.rw.status
}

// Body returns the recorded response body.
func (r *ResponseRecorder) Body() string {
	return r.b.String()
}

// responseWriter is an implementation of the http.ResponseWriter interface used
// for constructing an HTTP response.
type responseWriter struct {
	header http.Header
	writer io.Writer
	status safehttp.StatusCode
}

func newResponseWriter(w io.Writer) *responseWriter {
	return &responseWriter{
		header: http.Header{},
		writer: w,
		status: http.StatusOK,
	}
}

func (r *responseWriter) Header() http.Header {
	return r.header
}

func (r *responseWriter) WriteHeader(statusCode int) {
	r.status = safehttp.StatusCode(statusCode)
}

func (r *responseWriter) Write(data []byte) (int, error) {
	return r.writer.Write(data)
}
<|endoftext|>


<commit_before>package cards

import(
	"math/rand"
	"encoding/json"
)

type CardStack []interface{}

func (p *CardStack) remove(i int) interface{} {
	if i < 0 {
		i += len(*p)
	}
	if i > p.Length() {
		return nil
	}
	out := (*p)[i]
	if i == 0 {
		*p = (*p)[1:]
	} else if i == len(*p) - 1 {
		*p = (*p)[0:i]
	} else {
		*p = append((*p)[:i], (*p)[i+1:]...)
	}
	return out
}

func (p *CardStack) Reset() *CardStack {
	p = NewCardStack()
	return p
}

func (p *CardStack) Pop() interface{} {
	return p.remove(-1)
}

func (p *CardStack) Push(card interface{}) {
	*p = append(*p, card)
}

func (p *CardStack) Shift() interface{} {
	return p.remove(0)
}

func (p *CardStack) Unshift(card interface{}) {
	*p = append(CardStack{ card }, (*p)[:]...)
}

func (p *CardStack) Remove(i int) interface{} {
	return p.remove(i)
}

func (p *CardStack) IndexOf(card interface{}) int {
	for i, c := range *p {
		if c == card {
			return i
		}
	}
	return -1
}

func (p *CardStack) All() []interface{} {
	return (*p)[:]
}

func (p *CardStack) Length() int {
	return len(*p)
}

func (p *CardStack) Swap (i, j int) {
	left := (*p)[i]
	right := (*p)[j]
	(*p)[j] = left
	(*p)[i] = right
}

func NewCardStack() *CardStack {
	return &CardStack{}
}

//

type Deck struct {
	Source     *CardStack
	Trash      *CardStack
	Out        *CardStack
}

func (p *Deck) Reset(all bool) *Deck {
	for p.Trash.Length() > 0 {
		p.Source.Push(p.Trash.Pop())
	}
	if all {
		for p.Out.Length() > 0 {
			p.Source.Push(p.Out.Pop())
		}
	}
	return p
}

func (p *Deck) Shuffle() *Deck {
	l := p.Source.Length()
	for i := l - 1; i > 0; i-- {
		j := rand.Intn(i + 1)
		p.Source.Swap(i, j)
	}
	return p
}

func (p *Deck) Draw() interface{} {
	out := p.Source.Shift()
	p.Out.Push(out)
	return out
}

func (p *Deck) discard(i int) {
	p.Trash.Unshift(p.Out.Remove(i))
}

func (p *Deck) Discard(card interface{}) bool {
	if i := p.Out.IndexOf(card); i != -1 {
		p.discard(i)
		card = nil
		return true
	}
	return false
}

func (p *Deck) DiscardAll(cards *CardStack) bool {
	length := cards.Length()
	// validate them first
	for _, card := range *cards {
		i := p.Out.IndexOf(card)
		if i >= 0 {
			return false
		}
	}
	for _, card := range *cards {
		i := p.Out.IndexOf(card)
		if i >= 0 {
			p.discard(i)
		}
	}
	return true
}

func (p *Deck) IndexOf(card interface{}) (int, int, int) {
	return p.Source.IndexOf(card), p.Out.IndexOf(card), p.Trash.IndexOf(card)
}

func (p *Deck) String() string {
	out, _ := json.Marshal(p)
	return string(out)
}

func (p *Deck) AddCard(card interface{}) *Deck {
	p.Source.Push(card)
	return p
}

func NewDeck() *Deck {
	return &Deck{
		Source: NewCardStack(),
		Trash: NewCardStack(),
		Out: NewCardStack(),
	}
}
<commit_msg>Removed unnecessary variable<commit_after>package cards

import(
	"math/rand"
	"encoding/json"
)

type CardStack []interface{}

func (p *CardStack) remove(i int) interface{} {
	if i < 0 {
		i += len(*p)
	}
	if i > p.Length() {
		return nil
	}
	out := (*p)[i]
	if i == 0 {
		*p = (*p)[1:]
	} else if i == len(*p) - 1 {
		*p = (*p)[0:i]
	} else {
		*p = append((*p)[:i], (*p)[i+1:]...)
	}
	return out
}

func (p *CardStack) Reset() *CardStack {
	p = NewCardStack()
	return p
}

func (p *CardStack) Pop() interface{} {
	return p.remove(-1)
}

func (p *CardStack) Push(card interface{}) {
	*p = append(*p, card)
}

func (p *CardStack) Shift() interface{} {
	return p.remove(0)
}

func (p *CardStack) Unshift(card interface{}) {
	*p = append(CardStack{ card }, (*p)[:]...)
}

func (p *CardStack) Remove(i int) interface{} {
	return p.remove(i)
}

func (p *CardStack) IndexOf(card interface{}) int {
	for i, c := range *p {
		if c == card {
			return i
		}
	}
	return -1
}

func (p *CardStack) All() []interface{} {
	return (*p)[:]
}

func (p *CardStack) Length() int {
	return len(*p)
}

func (p *CardStack) Swap (i, j int) {
	left := (*p)[i]
	right := (*p)[j]
	(*p)[j] = left
	(*p)[i] = right
}

func NewCardStack() *CardStack {
	return &CardStack{}
}

//

type Deck struct {
	Source     *CardStack
	Trash      *CardStack
	Out        *CardStack
}

func (p *Deck) Reset(all bool) *Deck {
	for p.Trash.Length() > 0 {
		p.Source.Push(p.Trash.Pop())
	}
	if all {
		for p.Out.Length() > 0 {
			p.Source.Push(p.Out.Pop())
		}
	}
	return p
}

func (p *Deck) Shuffle() *Deck {
	l := p.Source.Length()
	for i := l - 1; i > 0; i-- {
		j := rand.Intn(i + 1)
		p.Source.Swap(i, j)
	}
	return p
}

func (p *Deck) Draw() interface{} {
	out := p.Source.Shift()
	p.Out.Push(out)
	return out
}

func (p *Deck) discard(i int) {
	p.Trash.Unshift(p.Out.Remove(i))
}

func (p *Deck) Discard(card interface{}) bool {
	if i := p.Out.IndexOf(card); i != -1 {
		p.discard(i)
		card = nil
		return true
	}
	return false
}

func (p *Deck) DiscardAll(cards *CardStack) bool {
	// validate them first
	for _, card := range *cards {
		i := p.Out.IndexOf(card)
		if i >= 0 {
			return false
		}
	}
	for _, card := range *cards {
		i := p.Out.IndexOf(card)
		if i >= 0 {
			p.discard(i)
		}
	}
	return true
}

func (p *Deck) IndexOf(card interface{}) (int, int, int) {
	return p.Source.IndexOf(card), p.Out.IndexOf(card), p.Trash.IndexOf(card)
}

func (p *Deck) String() string {
	out, _ := json.Marshal(p)
	return string(out)
}

func (p *Deck) AddCard(card interface{}) *Deck {
	p.Source.Push(card)
	return p
}

func NewDeck() *Deck {
	return &Deck{
		Source: NewCardStack(),
		Trash: NewCardStack(),
		Out: NewCardStack(),
	}
}
<|endoftext|>


<commit_before>package queue

import "time"
import "unsafe"

type Metric interface {
	Executor() string
	BeginTime() time.Time
	FinishTime() time.Time

	Calculate(interface{})

	ElapsedTime() time.Duration
	MemoryUsage() uintptr
}

func NewMetric(executor string) Metric { // {{{
	m := metricPoolGet()
	m.executor = executor
	m.beginTime = time.Now()
	return m
} // }}}

type metric struct {
	executor    string
	beginTime   time.Time
	finishTime  time.Time
	memoryUsage uintptr
}

func (this *metric) Reset() { // {{{
	this.executor = ""
	this.beginTime = time.Time{}
	this.finishTime = time.Time{}
	this.memoryUsage = 0
} // }}}

func (this *metric) Release() { // {{{
	metricPoolPut(this)
} // }}}

func (this *metric) Executor() string { // {{{
	return this.executor
} // }}}

func (this *metric) BeginTime() time.Time { // {{{
	return this.beginTime
} // }}}

func (this *metric) FinishTime() time.Time { // {{{
	return this.finishTime
} // }}}

func (this *metric) Calculate(v interface{}) { // {{{
	this.finishTime = time.Now()
	this.memoryUsage = unsafe.Sizeof(v)
} // }}}

func (this *metric) ElapsedTime() time.Duration { // {{{
	return this.finishTime.Sub(this.beginTime)
} // }}}

func (this *metric) MemoryUsage() uintptr { // {{{
	return this.memoryUsage
} // }}}
<commit_msg>Updated Metric interface: added Reset() and Release()<commit_after>package queue

import "time"
import "unsafe"

type Metric interface {
	Executor() string
	BeginTime() time.Time
	FinishTime() time.Time

	Calculate(interface{})

	ElapsedTime() time.Duration
	MemoryUsage() uintptr

	Reset()
	Release()
}

func NewMetric(executor string) Metric { // {{{
	m := metricPoolGet()
	m.executor = executor
	m.beginTime = time.Now()
	return m
} // }}}

type metric struct {
	executor    string
	beginTime   time.Time
	finishTime  time.Time
	memoryUsage uintptr
}

func (this *metric) Reset() { // {{{
	this.executor = ""
	this.beginTime = time.Time{}
	this.finishTime = time.Time{}
	this.memoryUsage = 0
} // }}}

func (this *metric) Release() { // {{{
	metricPoolPut(this)
} // }}}

func (this *metric) Executor() string { // {{{
	return this.executor
} // }}}

func (this *metric) BeginTime() time.Time { // {{{
	return this.beginTime
} // }}}

func (this *metric) FinishTime() time.Time { // {{{
	return this.finishTime
} // }}}

func (this *metric) Calculate(v interface{}) { // {{{
	this.finishTime = time.Now()
	this.memoryUsage = unsafe.Sizeof(v)
} // }}}

func (this *metric) ElapsedTime() time.Duration { // {{{
	return this.finishTime.Sub(this.beginTime)
} // }}}

func (this *metric) MemoryUsage() uintptr { // {{{
	return this.memoryUsage
} // }}}
<|endoftext|>