<commit_before>/*
Package channels provides a collection of helper functions, interfaces and implementations for
working with and extending the capabilities of golang's existing channels. The main interface of
interest is Channel, though sub-interfaces are also provided for cases where the full Channel interface
cannot be met (for example, InChannel for write-only channels).

For integration with native typed golang channels, functions Wrap and Unwrap are provided which do the
appropriate type conversions. The NativeChannel, NativeInChannel and NativeOutChannel type definitions
are also provided for use with native channels which already carry values of type interface{}.

The heart of the package consists of several distinct implementations of the Channel interface, including
channels backed by special buffers (resizable, infinite, ring buffers, etc) and other useful types. A
"black hole" channel for discarding unwanted values (similar in purpose to ioutil.Discard or /dev/null)
rounds out the set.

Helper functions for operating on Channels include Pipe and Tee (which behave much like their Unix
namesakes), as well as Multiplex and Distribute. "Weak" versions of these functions also exist, which
do not close their output channel(s) on completion.

Warning: several types in this package provide so-called "infinite" buffers. Be *very* careful using
these, as no buffer is truly infinite - if such a buffer grows too large your program will run out of
memory and crash. Caveat emptor.
*/
package channels

import "reflect"

// BufferCap represents the capacity of the buffer backing a channel. Valid values consist of all
// positive integers, as well as the special values below.
type BufferCap int

const (
	// None is the capacity for channels that have no buffer at all.
	None BufferCap = 0
	// Infinity is the capacity for channels with no limit on their buffer size.
	Infinity BufferCap = -1
)

// Buffer is an interface for any channel that provides access to query the state of its buffer.
// Even unbuffered channels can implement this interface by simply returning 0 from Len() and None from Cap().
type Buffer interface {
	Len() int       // The number of elements currently buffered.
	Cap() BufferCap // The maximum number of elements that can be buffered.
}

// SimpleInChannel is an interface representing a writeable channel that does not necessarily
// implement the Buffer interface.
type SimpleInChannel interface {
	In() chan<- interface{} // The writeable end of the channel.
	Close()                 // Closes the channel. It is an error to write to In() after calling Close().
}

// InChannel is an interface representing a writeable channel with a buffer.
type InChannel interface {
	SimpleInChannel
	Buffer
}

// SimpleOutChannel is an interface representing a readable channel that does not necessarily
// implement the Buffer interface.
type SimpleOutChannel interface {
	Out() <-chan interface{} // The readable end of the channel.
}

// OutChannel is an interface representing a readable channel implementing the Buffer interface.
type OutChannel interface {
	SimpleOutChannel
	Buffer
}

// SimpleChannel is an interface representing a channel that is both readable and writeable,
// but does not necessarily implement the Buffer interface.
type SimpleChannel interface {
	SimpleInChannel
	SimpleOutChannel
}

// Channel is an interface representing a channel that is readable, writeable and implements
// the Buffer interface
type Channel interface {
	SimpleChannel
	Buffer
}

// Pipe connects the input channel to the output channel so that
// they behave as if a single channel.
func Pipe(input SimpleOutChannel, output SimpleInChannel) {
	go func() {
		for elem := range input.Out() {
			output.In() <- elem
		}
		output.Close()
	}()
}

// Multiplex takes an arbitrary number of input channels and multiplexes their output into a single output
// channel. When all input channels have been closed, the output channel is closed. Multiplex with a single
// input channel is equivalent to Pipe (though slightly less efficient).
func Multiplex(output SimpleInChannel, inputs ...SimpleOutChannel) {
	if len(inputs) == 0 {
		panic("channels: Multiplex requires at least one input")
	}
	go func() {
		inputCount := len(inputs)
		cases := make([]reflect.SelectCase, inputCount)
		for i := range cases {
			cases[i].Dir = reflect.SelectRecv
			cases[i].Chan = reflect.ValueOf(inputs[i].Out())
		}
		for inputCount > 0 {
			chosen, recv, recvOK := reflect.Select(cases)
			if recvOK {
				output.In() <- recv.Interface()
			} else {
				cases[chosen].Chan = reflect.ValueOf(nil)
				inputCount--
			}
		}
		output.Close()
	}()
}

// Tee (like its Unix namesake) takes a single input channel and an arbitrary number of output channels
// and duplicates each input into every output. When the input channel is closed, all outputs channels are closed.
// Tee with a single output channel is equivalent to Pipe (though slightly less efficient).
func Tee(input SimpleOutChannel, outputs ...SimpleInChannel) {
	if len(outputs) == 0 {
		panic("channels: Tee requires at least one output")
	}
	go func() {
		cases := make([]reflect.SelectCase, len(outputs))
		for i := range cases {
			cases[i].Dir = reflect.SelectSend
		}
		for elem := range input.Out() {
			for i := range cases {
				cases[i].Chan = reflect.ValueOf(outputs[i].In())
				cases[i].Send = reflect.ValueOf(elem)
			}
			for _ = range cases {
				chosen, _, _ := reflect.Select(cases)
				cases[chosen].Chan = reflect.ValueOf(nil)
			}
		}
		for i := range outputs {
			outputs[i].Close()
		}
	}()
}

// Distribute takes a single input channel and an arbitrary number of output channels and duplicates each input
// into *one* available output. If multiple outputs are waiting for a value, one is chosen at random. When the
// input channel is closed, all outputs channels are closed. Distribute with a single output channel is
// equivalent to Pipe (though slightly less efficient).
func Distribute(input SimpleOutChannel, outputs ...SimpleInChannel) {
	if len(outputs) == 0 {
		panic("channels: Distribute requires at least one output")
	}
	go func() {
		cases := make([]reflect.SelectCase, len(outputs))
		for i := range cases {
			cases[i].Dir = reflect.SelectSend
			cases[i].Chan = reflect.ValueOf(outputs[i].In())
		}
		for elem := range input.Out() {
			for i := range cases {
				cases[i].Send = reflect.ValueOf(elem)
			}
			reflect.Select(cases)
		}
		for i := range outputs {
			outputs[i].Close()
		}
	}()
}

// WeakPipe behaves like Pipe (connecting the two channels) except that it does not close
// the output channel when the input channel is closed.
func WeakPipe(input SimpleOutChannel, output SimpleInChannel) {
	go func() {
		for elem := range input.Out() {
			output.In() <- elem
		}
	}()
}

// WeakMultiplex behaves like Multiplex (multiplexing multiple inputs into a single output) except that it does not close
// the output channel when the input channels are closed.
func WeakMultiplex(output SimpleInChannel, inputs ...SimpleOutChannel) {
	if len(inputs) == 0 {
		panic("channels: WeakMultiplex requires at least one input")
	}
	go func() {
		inputCount := len(inputs)
		cases := make([]reflect.SelectCase, inputCount)
		for i := range cases {
			cases[i].Dir = reflect.SelectRecv
			cases[i].Chan = reflect.ValueOf(inputs[i].Out())
		}
		for inputCount > 0 {
			chosen, recv, recvOK := reflect.Select(cases)
			if recvOK {
				output.In() <- recv.Interface()
			} else {
				cases[chosen].Chan = reflect.ValueOf(nil)
				inputCount--
			}
		}
	}()
}

// WeakTee behaves like Tee (duplicating a single input into multiple outputs) except that it does not close
// the output channels when the input channel is closed.
func WeakTee(input SimpleOutChannel, outputs ...SimpleInChannel) {
	if len(outputs) == 0 {
		panic("channels: WeakTee requires at least one output")
	}
	go func() {
		cases := make([]reflect.SelectCase, len(outputs))
		for i := range cases {
			cases[i].Dir = reflect.SelectSend
		}
		for elem := range input.Out() {
			for i := range cases {
				cases[i].Chan = reflect.ValueOf(outputs[i].In())
				cases[i].Send = reflect.ValueOf(elem)
			}
			for _ = range cases {
				chosen, _, _ := reflect.Select(cases)
				cases[chosen].Chan = reflect.ValueOf(nil)
			}
		}
	}()
}

// WeakDistribute behaves like Distribute (distributing a single input amongst multiple outputs) except that
// it does not close the output channels when the input channel is closed.
func WeakDistribute(input SimpleOutChannel, outputs ...SimpleInChannel) {
	if len(outputs) == 0 {
		panic("channels: WeakDistribute requires at least one output")
	}
	go func() {
		cases := make([]reflect.SelectCase, len(outputs))
		for i := range cases {
			cases[i].Dir = reflect.SelectSend
			cases[i].Chan = reflect.ValueOf(outputs[i].In())
		}
		for elem := range input.Out() {
			for i := range cases {
				cases[i].Send = reflect.ValueOf(elem)
			}
			reflect.Select(cases)
		}
	}()
}

// Wrap takes any readable channel type (chan or <-chan but not chan<-) and
// exposes it as a SimpleOutChannel for easy integration with existing channel sources.
// It panics if the input is not a readable channel.
func Wrap(ch interface{}) SimpleOutChannel {
	t := reflect.TypeOf(ch)
	if t.Kind() != reflect.Chan || t.ChanDir()&reflect.RecvDir == 0 {
		panic("channels: input to Wrap must be readable channel")
	}
	realChan := make(chan interface{})

	go func() {
		v := reflect.ValueOf(ch)
		for {
			x, ok := v.Recv()
			if !ok {
				close(realChan)
				return
			}
			realChan <- x.Interface()
		}
	}()

	return NativeOutChannel(realChan)
}

// Unwrap takes a SimpleOutChannel and uses reflection to pipe it to a typed native channel for
// easy integration with existing channel sources. Output can be any writable channel type (chan or chan<-).
// It panics if the output is not a writable channel, or if a value is received that cannot be sent on the
// output channel.
func Unwrap(input SimpleOutChannel, output interface{}) {
	t := reflect.TypeOf(output)
	if t.Kind() != reflect.Chan || t.ChanDir()&reflect.SendDir == 0 {
		panic("channels: input to Unwrap must be readable channel")
	}

	go func() {
		v := reflect.ValueOf(output)
		for {
			x, ok := <-input.Out()
			if !ok {
				v.Close()
				return
			}
			v.Send(reflect.ValueOf(x))
		}
	}()
}
<commit_msg>DRY up some functions<commit_after>/*
Package channels provides a collection of helper functions, interfaces and implementations for
working with and extending the capabilities of golang's existing channels. The main interface of
interest is Channel, though sub-interfaces are also provided for cases where the full Channel interface
cannot be met (for example, InChannel for write-only channels).

For integration with native typed golang channels, functions Wrap and Unwrap are provided which do the
appropriate type conversions. The NativeChannel, NativeInChannel and NativeOutChannel type definitions
are also provided for use with native channels which already carry values of type interface{}.

The heart of the package consists of several distinct implementations of the Channel interface, including
channels backed by special buffers (resizable, infinite, ring buffers, etc) and other useful types. A
"black hole" channel for discarding unwanted values (similar in purpose to ioutil.Discard or /dev/null)
rounds out the set.

Helper functions for operating on Channels include Pipe and Tee (which behave much like their Unix
namesakes), as well as Multiplex and Distribute. "Weak" versions of these functions also exist, which
do not close their output channel(s) on completion.

Warning: several types in this package provide so-called "infinite" buffers. Be *very* careful using
these, as no buffer is truly infinite - if such a buffer grows too large your program will run out of
memory and crash. Caveat emptor.
*/
package channels

import "reflect"

// BufferCap represents the capacity of the buffer backing a channel. Valid values consist of all
// positive integers, as well as the special values below.
type BufferCap int

const (
	// None is the capacity for channels that have no buffer at all.
	None BufferCap = 0
	// Infinity is the capacity for channels with no limit on their buffer size.
	Infinity BufferCap = -1
)

// Buffer is an interface for any channel that provides access to query the state of its buffer.
// Even unbuffered channels can implement this interface by simply returning 0 from Len() and None from Cap().
type Buffer interface {
	Len() int       // The number of elements currently buffered.
	Cap() BufferCap // The maximum number of elements that can be buffered.
}

// SimpleInChannel is an interface representing a writeable channel that does not necessarily
// implement the Buffer interface.
type SimpleInChannel interface {
	In() chan<- interface{} // The writeable end of the channel.
	Close()                 // Closes the channel. It is an error to write to In() after calling Close().
}

// InChannel is an interface representing a writeable channel with a buffer.
type InChannel interface {
	SimpleInChannel
	Buffer
}

// SimpleOutChannel is an interface representing a readable channel that does not necessarily
// implement the Buffer interface.
type SimpleOutChannel interface {
	Out() <-chan interface{} // The readable end of the channel.
}

// OutChannel is an interface representing a readable channel implementing the Buffer interface.
type OutChannel interface {
	SimpleOutChannel
	Buffer
}

// SimpleChannel is an interface representing a channel that is both readable and writeable,
// but does not necessarily implement the Buffer interface.
type SimpleChannel interface {
	SimpleInChannel
	SimpleOutChannel
}

// Channel is an interface representing a channel that is readable, writeable and implements
// the Buffer interface
type Channel interface {
	SimpleChannel
	Buffer
}

func pipe(input SimpleOutChannel, output SimpleInChannel, closeWhenDone bool) {
	for elem := range input.Out() {
		output.In() <- elem
	}
	if closeWhenDone {
		output.Close()
	}
}

func multiplex(output SimpleInChannel, inputs []SimpleOutChannel, closeWhenDone bool) {
	inputCount := len(inputs)
	cases := make([]reflect.SelectCase, inputCount)
	for i := range cases {
		cases[i].Dir = reflect.SelectRecv
		cases[i].Chan = reflect.ValueOf(inputs[i].Out())
	}
	for inputCount > 0 {
		chosen, recv, recvOK := reflect.Select(cases)
		if recvOK {
			output.In() <- recv.Interface()
		} else {
			cases[chosen].Chan = reflect.ValueOf(nil)
			inputCount--
		}
	}
	if closeWhenDone {
		output.Close()
	}
}

func tee(input SimpleOutChannel, outputs []SimpleInChannel, closeWhenDone bool) {
	cases := make([]reflect.SelectCase, len(outputs))
	for i := range cases {
		cases[i].Dir = reflect.SelectSend
	}
	for elem := range input.Out() {
		for i := range cases {
			cases[i].Chan = reflect.ValueOf(outputs[i].In())
			cases[i].Send = reflect.ValueOf(elem)
		}
		for _ = range cases {
			chosen, _, _ := reflect.Select(cases)
			cases[chosen].Chan = reflect.ValueOf(nil)
		}
	}
	if closeWhenDone {
		for i := range outputs {
			outputs[i].Close()
		}
	}
}

func distribute(input SimpleOutChannel, outputs []SimpleInChannel, closeWhenDone bool) {
	cases := make([]reflect.SelectCase, len(outputs))
	for i := range cases {
		cases[i].Dir = reflect.SelectSend
		cases[i].Chan = reflect.ValueOf(outputs[i].In())
	}
	for elem := range input.Out() {
		for i := range cases {
			cases[i].Send = reflect.ValueOf(elem)
		}
		reflect.Select(cases)
	}
	if closeWhenDone {
		for i := range outputs {
			outputs[i].Close()
		}
	}
}

// Pipe connects the input channel to the output channel so that
// they behave as if a single channel.
func Pipe(input SimpleOutChannel, output SimpleInChannel) {
	go pipe(input, output, true)
}

// Multiplex takes an arbitrary number of input channels and multiplexes their output into a single output
// channel. When all input channels have been closed, the output channel is closed. Multiplex with a single
// input channel is equivalent to Pipe (though slightly less efficient).
func Multiplex(output SimpleInChannel, inputs ...SimpleOutChannel) {
	if len(inputs) == 0 {
		panic("channels: Multiplex requires at least one input")
	}
	go multiplex(output, inputs, true)
}

// Tee (like its Unix namesake) takes a single input channel and an arbitrary number of output channels
// and duplicates each input into every output. When the input channel is closed, all outputs channels are closed.
// Tee with a single output channel is equivalent to Pipe (though slightly less efficient).
func Tee(input SimpleOutChannel, outputs ...SimpleInChannel) {
	if len(outputs) == 0 {
		panic("channels: Tee requires at least one output")
	}
	go tee(input, outputs, true)
}

// Distribute takes a single input channel and an arbitrary number of output channels and duplicates each input
// into *one* available output. If multiple outputs are waiting for a value, one is chosen at random. When the
// input channel is closed, all outputs channels are closed. Distribute with a single output channel is
// equivalent to Pipe (though slightly less efficient).
func Distribute(input SimpleOutChannel, outputs ...SimpleInChannel) {
	if len(outputs) == 0 {
		panic("channels: Distribute requires at least one output")
	}
	go distribute(input, outputs, true)
}

// WeakPipe behaves like Pipe (connecting the two channels) except that it does not close
// the output channel when the input channel is closed.
func WeakPipe(input SimpleOutChannel, output SimpleInChannel) {
	go pipe(input, output, false)
}

// WeakMultiplex behaves like Multiplex (multiplexing multiple inputs into a single output) except that it does not close
// the output channel when the input channels are closed.
func WeakMultiplex(output SimpleInChannel, inputs ...SimpleOutChannel) {
	if len(inputs) == 0 {
		panic("channels: WeakMultiplex requires at least one input")
	}
	go multiplex(output, inputs, false)
}

// WeakTee behaves like Tee (duplicating a single input into multiple outputs) except that it does not close
// the output channels when the input channel is closed.
func WeakTee(input SimpleOutChannel, outputs ...SimpleInChannel) {
	if len(outputs) == 0 {
		panic("channels: WeakTee requires at least one output")
	}
	go tee(input, outputs, false)
}

// WeakDistribute behaves like Distribute (distributing a single input amongst multiple outputs) except that
// it does not close the output channels when the input channel is closed.
func WeakDistribute(input SimpleOutChannel, outputs ...SimpleInChannel) {
	if len(outputs) == 0 {
		panic("channels: WeakDistribute requires at least one output")
	}
	go distribute(input, outputs, false)
}

// Wrap takes any readable channel type (chan or <-chan but not chan<-) and
// exposes it as a SimpleOutChannel for easy integration with existing channel sources.
// It panics if the input is not a readable channel.
func Wrap(ch interface{}) SimpleOutChannel {
	t := reflect.TypeOf(ch)
	if t.Kind() != reflect.Chan || t.ChanDir()&reflect.RecvDir == 0 {
		panic("channels: input to Wrap must be readable channel")
	}
	realChan := make(chan interface{})

	go func() {
		v := reflect.ValueOf(ch)
		for {
			x, ok := v.Recv()
			if !ok {
				close(realChan)
				return
			}
			realChan <- x.Interface()
		}
	}()

	return NativeOutChannel(realChan)
}

// Unwrap takes a SimpleOutChannel and uses reflection to pipe it to a typed native channel for
// easy integration with existing channel sources. Output can be any writable channel type (chan or chan<-).
// It panics if the output is not a writable channel, or if a value is received that cannot be sent on the
// output channel.
func Unwrap(input SimpleOutChannel, output interface{}) {
	t := reflect.TypeOf(output)
	if t.Kind() != reflect.Chan || t.ChanDir()&reflect.SendDir == 0 {
		panic("channels: input to Unwrap must be readable channel")
	}

	go func() {
		v := reflect.ValueOf(output)
		for {
			x, ok := <-input.Out()
			if !ok {
				v.Close()
				return
			}
			v.Send(reflect.ValueOf(x))
		}
	}()
}
<|endoftext|>


<commit_before>package mackerel

// TODO

// Channel represents a Mackerel notification channel.
type Channel struct {
	ID   string `json:"id"`
	Name string `json:"name"`
	Type string `json:"type"`

	// Exists when the type is "email"
	Emails  []string `json:"emails,omitempty"`
	UserIDs []string `json:"userIds,omitempty"`

	// Exists when the type is "slack"
	Mentions struct {
		OK       string `json:"ok,omitempty"`
		Warning  string `json:"warning,omitempty"`
		Critical string `json:"critical,omitempty"`
	} `json:"mentions,omitempty"`
	EnabledGraphImage bool `json:"enabledGraphImage,omitempty"`

	// Exists when the type is "slack" or "webhook"
	URL string `json:"url,omitempty"`

	// Exists when the type is "email", "slack", or "webhook"
	Events []string `json:"events,omitempty"`
}
<commit_msg>adjust the channel struct to support list/create APIs<commit_after>package mackerel

// TODO

// Channel represents a Mackerel notification channel.
// ref. https://mackerel.io/api-docs/entry/channels
type Channel struct {
	ID string `json:"id"`
	ChannelWithoutID
}

// ChannelWithoutID represents a Mackerel notification channel without the ID.
type ChannelWithoutID struct {
	Name string `json:"name"`
	Type string `json:"type"`

	// Exists when the type is "email"
	Emails  []string `json:"emails,omitempty"`
	UserIDs []string `json:"userIds,omitempty"`

	// Exists when the type is "slack"
	Mentions struct {
		OK       string `json:"ok,omitempty"`
		Warning  string `json:"warning,omitempty"`
		Critical string `json:"critical,omitempty"`
	} `json:"mentions,omitempty"`
	EnabledGraphImage bool `json:"enabledGraphImage,omitempty"`

	// Exists when the type is "slack" or "webhook"
	URL string `json:"url,omitempty"`

	// Exists when the type is "email", "slack", or "webhook"
	Events []string `json:"events,omitempty"`
}
<|endoftext|>


<commit_before>package packfile

import (
	"bytes"

	"github.com/src-d/go-git-fixtures"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/storage/memory"

	. "gopkg.in/check.v1"
)

type EncoderSuite struct {
	fixtures.Suite
	buf   *bytes.Buffer
	store *memory.Storage
	enc   *Encoder
}

var _ = Suite(&EncoderSuite{})

func (s *EncoderSuite) SetUpTest(c *C) {
	s.buf = bytes.NewBuffer(nil)
	s.store = memory.NewStorage()
	s.enc = NewEncoder(s.buf, s.store, false)
}

func (s *EncoderSuite) TestCorrectPackHeader(c *C) {
	hash, err := s.enc.Encode([]plumbing.Hash{})
	c.Assert(err, IsNil)

	hb := [20]byte(hash)

	// PACK + VERSION + OBJECTS + HASH
	expectedResult := []byte{'P', 'A', 'C', 'K', 0, 0, 0, 2, 0, 0, 0, 0}
	expectedResult = append(expectedResult, hb[:]...)

	result := s.buf.Bytes()

	c.Assert(result, DeepEquals, expectedResult)
}

func (s *EncoderSuite) TestCorrectPackWithOneEmptyObject(c *C) {
	o := &plumbing.MemoryObject{}
	o.SetType(plumbing.CommitObject)
	o.SetSize(0)
	_, err := s.store.SetEncodedObject(o)
	c.Assert(err, IsNil)

	hash, err := s.enc.Encode([]plumbing.Hash{o.Hash()})
	c.Assert(err, IsNil)

	// PACK + VERSION(2) + OBJECT NUMBER(1)
	expectedResult := []byte{'P', 'A', 'C', 'K', 0, 0, 0, 2, 0, 0, 0, 1}
	// OBJECT HEADER(TYPE + SIZE)= 0001 0000
	expectedResult = append(expectedResult, []byte{16}...)

	// Zlib header
	expectedResult = append(expectedResult,
		[]byte{120, 156, 1, 0, 0, 255, 255, 0, 0, 0, 1}...)

	// + HASH
	hb := [20]byte(hash)
	expectedResult = append(expectedResult, hb[:]...)

	result := s.buf.Bytes()

	c.Assert(result, DeepEquals, expectedResult)
}

func (s *EncoderSuite) TestMaxObjectSize(c *C) {
	o := s.store.NewEncodedObject()
	o.SetSize(9223372036854775807)
	o.SetType(plumbing.CommitObject)
	_, err := s.store.SetEncodedObject(o)
	c.Assert(err, IsNil)
	hash, err := s.enc.Encode([]plumbing.Hash{o.Hash()})
	c.Assert(err, IsNil)
	c.Assert(hash.IsZero(), Not(Equals), true)
}

func (s *EncoderSuite) TestHashNotFound(c *C) {
	h, err := s.enc.Encode([]plumbing.Hash{plumbing.NewHash("BAD")})
	c.Assert(h, Equals, plumbing.ZeroHash)
	c.Assert(err, NotNil)
	c.Assert(err, Equals, plumbing.ErrObjectNotFound)
}

func (s *EncoderSuite) TestDecodeEncodeDecode(c *C) {
	fixtures.Basic().ByTag("packfile").Test(c, func(f *fixtures.Fixture) {
		scanner := NewScanner(f.Packfile())
		storage := memory.NewStorage()

		d, err := NewDecoder(scanner, storage)
		c.Assert(err, IsNil)

		ch, err := d.Decode()
		c.Assert(err, IsNil)
		c.Assert(ch, Equals, f.PackfileHash)

		objIter, err := d.o.IterEncodedObjects(plumbing.AnyObject)
		c.Assert(err, IsNil)

		objects := []plumbing.EncodedObject{}
		hashes := []plumbing.Hash{}
		err = objIter.ForEach(func(o plumbing.EncodedObject) error {
			objects = append(objects, o)
			hash, err := s.store.SetEncodedObject(o)
			c.Assert(err, IsNil)

			hashes = append(hashes, hash)

			return err

		})
		c.Assert(err, IsNil)
		_, err = s.enc.Encode(hashes)
		c.Assert(err, IsNil)

		scanner = NewScanner(s.buf)
		storage = memory.NewStorage()
		d, err = NewDecoder(scanner, storage)
		c.Assert(err, IsNil)
		_, err = d.Decode()
		c.Assert(err, IsNil)

		objIter, err = d.o.IterEncodedObjects(plumbing.AnyObject)
		c.Assert(err, IsNil)
		obtainedObjects := []plumbing.EncodedObject{}
		err = objIter.ForEach(func(o plumbing.EncodedObject) error {
			obtainedObjects = append(obtainedObjects, o)

			return nil
		})
		c.Assert(err, IsNil)
		c.Assert(len(obtainedObjects), Equals, len(objects))

		equals := 0
		for _, oo := range obtainedObjects {
			for _, o := range objects {
				if o.Hash() == oo.Hash() {
					equals++
				}
			}
		}

		c.Assert(len(obtainedObjects), Equals, equals)
	})
}

func (s *EncoderSuite) TestDecodeEncodeWithDeltaDecodeREF(c *C) {
	s.enc = NewEncoder(s.buf, s.store, true)
	s.simpleDeltaTest(c)
}

func (s *EncoderSuite) TestDecodeEncodeWithDeltaDecodeOFS(c *C) {
	s.enc = NewEncoder(s.buf, s.store, false)
	s.simpleDeltaTest(c)
}

func (s *EncoderSuite) TestDecodeEncodeWithDeltasDecodeREF(c *C) {
	s.enc = NewEncoder(s.buf, s.store, true)
	s.deltaOverDeltaTest(c)
}

func (s *EncoderSuite) TestDecodeEncodeWithDeltasDecodeOFS(c *C) {
	s.enc = NewEncoder(s.buf, s.store, false)
	s.deltaOverDeltaTest(c)
}

func (s *EncoderSuite) simpleDeltaTest(c *C) {
	srcObject := newObject(plumbing.BlobObject, []byte("0"))
	targetObject := newObject(plumbing.BlobObject, []byte("01"))

	deltaObject, err := GetDelta(srcObject, targetObject)
	c.Assert(err, IsNil)

	srcToPack := newObjectToPack(srcObject)
	_, err = s.enc.encode([]*ObjectToPack{
		srcToPack,
		newDeltaObjectToPack(srcToPack, targetObject, deltaObject),
	})
	c.Assert(err, IsNil)

	scanner := NewScanner(s.buf)

	storage := memory.NewStorage()
	d, err := NewDecoder(scanner, storage)
	c.Assert(err, IsNil)

	_, err = d.Decode()
	c.Assert(err, IsNil)

	decSrc, err := storage.EncodedObject(srcObject.Type(), srcObject.Hash())
	c.Assert(err, IsNil)
	c.Assert(decSrc, DeepEquals, srcObject)

	decTarget, err := storage.EncodedObject(targetObject.Type(), targetObject.Hash())
	c.Assert(err, IsNil)
	c.Assert(decTarget, DeepEquals, targetObject)
}

func (s *EncoderSuite) deltaOverDeltaTest(c *C) {
	srcObject := newObject(plumbing.BlobObject, []byte("0"))
	targetObject := newObject(plumbing.BlobObject, []byte("01"))
	otherTargetObject := newObject(plumbing.BlobObject, []byte("011111"))

	deltaObject, err := GetDelta(srcObject, targetObject)
	c.Assert(err, IsNil)
	c.Assert(deltaObject.Hash(), Not(Equals), plumbing.ZeroHash)

	otherDeltaObject, err := GetDelta(targetObject, otherTargetObject)
	c.Assert(err, IsNil)
	c.Assert(otherDeltaObject.Hash(), Not(Equals), plumbing.ZeroHash)

	srcToPack := newObjectToPack(srcObject)
	targetToPack := newObjectToPack(targetObject)
	_, err = s.enc.encode([]*ObjectToPack{
		srcToPack,
		newDeltaObjectToPack(srcToPack, targetObject, deltaObject),
		newDeltaObjectToPack(targetToPack, otherTargetObject, otherDeltaObject),
	})
	c.Assert(err, IsNil)

	scanner := NewScanner(s.buf)
	storage := memory.NewStorage()
	d, err := NewDecoder(scanner, storage)
	c.Assert(err, IsNil)

	_, err = d.Decode()
	c.Assert(err, IsNil)

	decSrc, err := storage.EncodedObject(srcObject.Type(), srcObject.Hash())
	c.Assert(err, IsNil)
	c.Assert(decSrc, DeepEquals, srcObject)

	decTarget, err := storage.EncodedObject(targetObject.Type(), targetObject.Hash())
	c.Assert(err, IsNil)
	c.Assert(decTarget, DeepEquals, targetObject)

	decOtherTarget, err := storage.EncodedObject(otherTargetObject.Type(), otherTargetObject.Hash())
	c.Assert(err, IsNil)
	c.Assert(decOtherTarget, DeepEquals, otherTargetObject)
}
<commit_msg>test: improve packfile.Encoder tests<commit_after>package packfile

import (
	"bytes"
	"io"

	"github.com/src-d/go-git-fixtures"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/storer"
	"gopkg.in/src-d/go-git.v4/storage/memory"

	. "gopkg.in/check.v1"
)

type EncoderSuite struct {
	fixtures.Suite
	buf   *bytes.Buffer
	store *memory.Storage
	enc   *Encoder
}

var _ = Suite(&EncoderSuite{})

func (s *EncoderSuite) SetUpTest(c *C) {
	s.buf = bytes.NewBuffer(nil)
	s.store = memory.NewStorage()
	s.enc = NewEncoder(s.buf, s.store, false)
}

func (s *EncoderSuite) TestCorrectPackHeader(c *C) {
	hash, err := s.enc.Encode([]plumbing.Hash{})
	c.Assert(err, IsNil)

	hb := [20]byte(hash)

	// PACK + VERSION + OBJECTS + HASH
	expectedResult := []byte{'P', 'A', 'C', 'K', 0, 0, 0, 2, 0, 0, 0, 0}
	expectedResult = append(expectedResult, hb[:]...)

	result := s.buf.Bytes()

	c.Assert(result, DeepEquals, expectedResult)
}

func (s *EncoderSuite) TestCorrectPackWithOneEmptyObject(c *C) {
	o := &plumbing.MemoryObject{}
	o.SetType(plumbing.CommitObject)
	o.SetSize(0)
	_, err := s.store.SetEncodedObject(o)
	c.Assert(err, IsNil)

	hash, err := s.enc.Encode([]plumbing.Hash{o.Hash()})
	c.Assert(err, IsNil)

	// PACK + VERSION(2) + OBJECT NUMBER(1)
	expectedResult := []byte{'P', 'A', 'C', 'K', 0, 0, 0, 2, 0, 0, 0, 1}
	// OBJECT HEADER(TYPE + SIZE)= 0001 0000
	expectedResult = append(expectedResult, []byte{16}...)

	// Zlib header
	expectedResult = append(expectedResult,
		[]byte{120, 156, 1, 0, 0, 255, 255, 0, 0, 0, 1}...)

	// + HASH
	hb := [20]byte(hash)
	expectedResult = append(expectedResult, hb[:]...)

	result := s.buf.Bytes()

	c.Assert(result, DeepEquals, expectedResult)
}

func (s *EncoderSuite) TestMaxObjectSize(c *C) {
	o := s.store.NewEncodedObject()
	o.SetSize(9223372036854775807)
	o.SetType(plumbing.CommitObject)
	_, err := s.store.SetEncodedObject(o)
	c.Assert(err, IsNil)
	hash, err := s.enc.Encode([]plumbing.Hash{o.Hash()})
	c.Assert(err, IsNil)
	c.Assert(hash.IsZero(), Not(Equals), true)
}

func (s *EncoderSuite) TestHashNotFound(c *C) {
	h, err := s.enc.Encode([]plumbing.Hash{plumbing.NewHash("BAD")})
	c.Assert(h, Equals, plumbing.ZeroHash)
	c.Assert(err, NotNil)
	c.Assert(err, Equals, plumbing.ErrObjectNotFound)
}

func (s *EncoderSuite) TestDecodeEncodeDecode(c *C) {
	fixtures.Basic().ByTag("packfile").Test(c, func(f *fixtures.Fixture) {
		pf := f.Packfile()
		ph := f.PackfileHash
		storage := memory.NewStorage()
		s.testDecodeEncodeDecode(c, pf, ph, storage)
	})
}

func (s *EncoderSuite) testDecodeEncodeDecode(c *C,
	pf io.ReadCloser,
	ph plumbing.Hash,
	storage storer.Storer) {

	defer func() {
		c.Assert(pf.Close(), IsNil)
	}()

	scanner := NewScanner(pf)

	d, err := NewDecoder(scanner, storage)
	c.Assert(err, IsNil)

	ch, err := d.Decode()
	c.Assert(err, IsNil)
	c.Assert(ch, Equals, ph)

	objIter, err := storage.IterEncodedObjects(plumbing.AnyObject)
	c.Assert(err, IsNil)

	expectedObjects := map[plumbing.Hash]bool{}
	var hashes []plumbing.Hash
	err = objIter.ForEach(func(o plumbing.EncodedObject) error {
		expectedObjects[o.Hash()] = true
		hashes = append(hashes, o.Hash())
		return err

	})
	c.Assert(err, IsNil)

	enc := NewEncoder(s.buf, storage, false)
	_, err = enc.Encode(hashes)
	c.Assert(err, IsNil)

	scanner = NewScanner(s.buf)
	storage = memory.NewStorage()
	d, err = NewDecoder(scanner, storage)
	c.Assert(err, IsNil)
	_, err = d.Decode()
	c.Assert(err, IsNil)

	objIter, err = storage.IterEncodedObjects(plumbing.AnyObject)
	c.Assert(err, IsNil)
	obtainedObjects := map[plumbing.Hash]bool{}
	err = objIter.ForEach(func(o plumbing.EncodedObject) error {
		obtainedObjects[o.Hash()] = true
		return nil
	})
	c.Assert(err, IsNil)
	c.Assert(obtainedObjects, DeepEquals, expectedObjects)

	for h := range obtainedObjects {
		if !expectedObjects[h] {
			c.Errorf("obtained unexpected object: %s", h)
		}
	}

	for h := range expectedObjects {
		if !obtainedObjects[h] {
			c.Errorf("missing object: %s", h)
		}
	}
}

func (s *EncoderSuite) TestDecodeEncodeWithDeltaDecodeREF(c *C) {
	s.enc = NewEncoder(s.buf, s.store, true)
	s.simpleDeltaTest(c)
}

func (s *EncoderSuite) TestDecodeEncodeWithDeltaDecodeOFS(c *C) {
	s.enc = NewEncoder(s.buf, s.store, false)
	s.simpleDeltaTest(c)
}

func (s *EncoderSuite) TestDecodeEncodeWithDeltasDecodeREF(c *C) {
	s.enc = NewEncoder(s.buf, s.store, true)
	s.deltaOverDeltaTest(c)
}

func (s *EncoderSuite) TestDecodeEncodeWithDeltasDecodeOFS(c *C) {
	s.enc = NewEncoder(s.buf, s.store, false)
	s.deltaOverDeltaTest(c)
}

func (s *EncoderSuite) simpleDeltaTest(c *C) {
	srcObject := newObject(plumbing.BlobObject, []byte("0"))
	targetObject := newObject(plumbing.BlobObject, []byte("01"))

	deltaObject, err := GetDelta(srcObject, targetObject)
	c.Assert(err, IsNil)

	srcToPack := newObjectToPack(srcObject)
	_, err = s.enc.encode([]*ObjectToPack{
		srcToPack,
		newDeltaObjectToPack(srcToPack, targetObject, deltaObject),
	})
	c.Assert(err, IsNil)

	scanner := NewScanner(s.buf)

	storage := memory.NewStorage()
	d, err := NewDecoder(scanner, storage)
	c.Assert(err, IsNil)

	_, err = d.Decode()
	c.Assert(err, IsNil)

	decSrc, err := storage.EncodedObject(srcObject.Type(), srcObject.Hash())
	c.Assert(err, IsNil)
	c.Assert(decSrc, DeepEquals, srcObject)

	decTarget, err := storage.EncodedObject(targetObject.Type(), targetObject.Hash())
	c.Assert(err, IsNil)
	c.Assert(decTarget, DeepEquals, targetObject)
}

func (s *EncoderSuite) deltaOverDeltaTest(c *C) {
	srcObject := newObject(plumbing.BlobObject, []byte("0"))
	targetObject := newObject(plumbing.BlobObject, []byte("01"))
	otherTargetObject := newObject(plumbing.BlobObject, []byte("011111"))

	deltaObject, err := GetDelta(srcObject, targetObject)
	c.Assert(err, IsNil)
	c.Assert(deltaObject.Hash(), Not(Equals), plumbing.ZeroHash)

	otherDeltaObject, err := GetDelta(targetObject, otherTargetObject)
	c.Assert(err, IsNil)
	c.Assert(otherDeltaObject.Hash(), Not(Equals), plumbing.ZeroHash)

	srcToPack := newObjectToPack(srcObject)
	targetToPack := newObjectToPack(targetObject)
	_, err = s.enc.encode([]*ObjectToPack{
		srcToPack,
		newDeltaObjectToPack(srcToPack, targetObject, deltaObject),
		newDeltaObjectToPack(targetToPack, otherTargetObject, otherDeltaObject),
	})
	c.Assert(err, IsNil)

	scanner := NewScanner(s.buf)
	storage := memory.NewStorage()
	d, err := NewDecoder(scanner, storage)
	c.Assert(err, IsNil)

	_, err = d.Decode()
	c.Assert(err, IsNil)

	decSrc, err := storage.EncodedObject(srcObject.Type(), srcObject.Hash())
	c.Assert(err, IsNil)
	c.Assert(decSrc, DeepEquals, srcObject)

	decTarget, err := storage.EncodedObject(targetObject.Type(), targetObject.Hash())
	c.Assert(err, IsNil)
	c.Assert(decTarget, DeepEquals, targetObject)

	decOtherTarget, err := storage.EncodedObject(otherTargetObject.Type(), otherTargetObject.Hash())
	c.Assert(err, IsNil)
	c.Assert(decOtherTarget, DeepEquals, otherTargetObject)
}
<|endoftext|>


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

package oglematchers_test

import (
	. "github.com/jacobsa/ogletest"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

type AllOfTest struct {
}

func init()                     { RegisterTestSuite(&AllOfTest{}) }

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func (t *AllOfTest) DoesFoo() {
}
<commit_msg>Added a fake matcher helper, for #12.<commit_after>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package oglematchers_test

import (
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"errors"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

type allOfFakeMatcher struct {
	desc string
	res  MatchResult
	err  string
}

func (m *allOfFakeMatcher) Matches(c interface{}) (MatchResult, error) {
	return m.res, errors.New(m.err)
}

func (m *allOfFakeMatcher) Description() string {
	return m.desc
}

type AllOfTest struct {
}

func init()                     { RegisterTestSuite(&AllOfTest{}) }

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func (t *AllOfTest) DoesFoo() {
}
<|endoftext|>


<commit_before>package games

import (
	"fmt"
	"log"

	"errors"

	"encoding/json"

	"github.com/mleonard87/merknera/repository"
)

const (
	TICTACTOE_MNEMONIC             = "TICTACTOE"
	TICTACTOE_NAME                 = "Tic-Tac-Toe"
	TICTACTOE_RPC_METHOD_NEXT_MOVE = "TicTacToe.NextMove"
	TICTACTOE_RPC_METHOD_COMPLETE  = "TicTacToe.Complete"
	TICTACTOE_RPC_METHOD_ERROR     = "TicTacToe.Error"
)

func init() {
	err := RegisterGameManager(new(TicTacToeGameManager))
	if err != nil {
		log.Fatal(err)
	}
}

type TicTacToeGameState []string

func (tgs *TicTacToeGameState) MarshalJSON() ([]byte, error) {
	sa := []string(*tgs)
	resultString := "{"
	for i, m := range sa {
		switch m {
		case "X":
			resultString += "\"X\""
		case "O":
			resultString += "\"O\""
		default:
			resultString += "null"
		}
		if i != len(sa) {
			resultString += ", "
		}
	}
	resultString += "}"

	fmt.Println("Marshalling JSON")
	fmt.Println(resultString)

	return []byte(resultString), nil
}

type TicTacToeGameManager struct{}

func (tgm TicTacToeGameManager) GenerateGames(bot repository.Bot) []repository.Game {
	gameType, err := repository.GetGameTypeByMnemonic(TICTACTOE_MNEMONIC)
	if err != nil {
		log.Fatal(err)
	}

	botList, err := repository.ListBotsForGameType(gameType)
	if err != nil {
		log.Fatal(err)
	}

	var gameList []repository.Game
	for _, b := range botList {
		// If its not the same bot as we are invoking this game for then create the game.
		if b.Id != bot.Id {
			// Create a game for these two bots with the initial bot as player 1
			game1, err := createGameWithPlayers(gameType, &b, &bot)
			if err != nil {
				log.Fatal(err)
			}
			// Create a game for these two bots with the initial bot as player 2
			game2, err := createGameWithPlayers(gameType, &bot, &b)
			if err != nil {
				log.Fatal(err)
			}
			gameList = append(gameList, game1, game2)
		}
	}

	return gameList
}

func (tgm TicTacToeGameManager) Mnemonic() string {
	return TICTACTOE_MNEMONIC
}

func (tgm TicTacToeGameManager) Name() string {
	return TICTACTOE_NAME
}

func (tgm TicTacToeGameManager) GetNextMoveRPCMethodName() string {
	return TICTACTOE_RPC_METHOD_NEXT_MOVE
}

func (tgm TicTacToeGameManager) GetCompleteRPCMethodName() string {
	return TICTACTOE_RPC_METHOD_COMPLETE
}

func (tgm TicTacToeGameManager) GetErrorRPCMethodName() string {
	return TICTACTOE_RPC_METHOD_ERROR
}

type nextMoveParams struct {
	GameId    int                `json:"gameid"`
	Mark      string             `json:"mark"`
	GameState TicTacToeGameState `json:"gamestate"`
}

func (tgm TicTacToeGameManager) GetNextMoveRPCParams(gameMove repository.GameMove) (interface{}, error) {
	gb, err := gameMove.GameBot()
	if err != nil {
		return nil, err
	}

	mark := getMarkForPlaySequence(gb.PlaySequence)

	g, err := gb.Game()
	if err != nil {
		return nil, err
	}

	gs, err := g.GameState()
	if err != nil {
		return nil, err
	}

	var tttGameState TicTacToeGameState
	err = json.Unmarshal([]byte(gs), &tttGameState)
	if err != nil {
		return nil, err
	}

	params := nextMoveParams{
		GameId:    g.Id,
		Mark:      mark,
		GameState: tttGameState,
	}

	return params, nil
}

type nextMoveResponse struct {
	Position int `json:"position"`
}

func (tgm TicTacToeGameManager) GetNextMoveRPCResult(gameMove repository.GameMove) interface{} {
	return nextMoveResponse{}
}

func (tgm TicTacToeGameManager) ProcessMove(gameMove repository.GameMove, result map[string]interface{}) (interface{}, bool, error) {
	var position int
	if pos, ok := result["position"].(float64); ok {
		position = int(pos)
	} else {
		return nil, false, errors.New("Could not find property \"position\" in your response or position was not an integer.")
	}

	gb, err := gameMove.GameBot()
	if err != nil {
		return nil, false, err
	}

	game, err := gb.Game()
	if err != nil {
		return nil, false, err
	}

	gs, err := game.GameState()
	if err != nil {
		return nil, false, err
	}

	var tttGameState TicTacToeGameState
	err = json.Unmarshal([]byte(gs), &tttGameState)
	if err != nil {
		return nil, false, err
	}

	if tttGameState[position] != "" {
		msg := fmt.Sprintf("Invalid position: The position you played, \"%d\", is already taken by \"%s\"", position, tttGameState[position])
		return nil, false, errors.New(msg)
	}

	mark := getMarkForPlaySequence(gb.PlaySequence)
	tttGameState[position] = mark

	win := isWinForMark(tttGameState, mark)

	return tttGameState, win, nil
}

func (tgm TicTacToeGameManager) GetGameBotForNextMove(currentMove repository.GameMove) (repository.GameBot, error) {
	gb, err := currentMove.GameBot()
	if err != nil {
		return repository.GameBot{}, err
	}

	game, err := gb.Game()
	if err != nil {
		return repository.GameBot{}, err
	}

	gameBots, err := game.Players()
	if err != nil {
		return repository.GameBot{}, err
	}

	for _, b := range gameBots {
		if b.Id != gb.Id {
			return b, nil
		}
	}

	return repository.GameBot{}, errors.New("Could not find GameBot for next move.")
}

type completeParams struct {
	GameId    int                `json:"gameid"`
	Winner    bool               `json:"winner"`
	Mark      string             `json:"mark"`
	GameState TicTacToeGameState `json:"gamestate"`
}

func (tgm TicTacToeGameManager) GetCompleteRPCParams(gb repository.GameBot) (interface{}, error) {
	game, err := gb.Game()
	if err != nil {
		return nil, err
	}

	gs, err := game.GameState()
	if err != nil {
		return nil, err
	}

	wm, err := game.WinningMove()
	if err != nil {
		return nil, err
	}

	winninggb, err := wm.GameBot()
	if err != nil {
		return nil, err
	}

	w := false
	if gb.Id == winninggb.Id {
		w = true
	}

	var tgs TicTacToeGameState
	err = json.Unmarshal([]byte(gs), &tgs)
	if err != nil {
		return nil, err
	}
	cp := completeParams{
		GameId:    game.Id,
		Winner:    w,
		Mark:      getMarkForPlaySequence(gb.PlaySequence),
		GameState: tgs,
	}

	return cp, nil
}

type errorParams struct {
	GameId    int    `json:"gameid"`
	Message   string `json:"message"`
	ErrorCode int    `json:"errorcode"`
}

func (tgm TicTacToeGameManager) GetErrorRPCParams(gm repository.GameMove, errorMessage string) interface{} {
	gb, _ := gm.GameBot()
	game, _ := gb.Game()
	return errorParams{
		GameId:    game.Id,
		Message:   errorMessage,
		ErrorCode: 999,
	}
}

func getMarkForPlaySequence(ps int) string {
	switch ps {
	case 1:
		return "X"
	case 2:
		return "O"
	default:
		log.Fatal("Invalid play sequence for Tic-Tac-Toe")
	}

	return ""
}

func createGameWithPlayers(gameType repository.GameType, playerOne *repository.Bot, playerTwo *repository.Bot) (repository.Game, error) {
	game, err := repository.CreateGame(gameType)
	if err != nil {
		return game, err
	}

	_, err = repository.CreateGameBot(game, *playerOne, 1)
	if err != nil {
		return game, err
	}

	_, err = repository.CreateGameBot(game, *playerTwo, 2)
	if err != nil {
		return game, err
	}

	err = createFirstGameMove(game)
	if err != nil {
		return game, err
	}

	return game, nil
}

func createFirstGameMove(game repository.Game) error {
	players, err := game.Players()
	if err != nil {
		return err
	}
	firstPlayer := players[0]
	initialGameState := make([]string, 9, 9)
	_, err = repository.CreateGameMove(firstPlayer, initialGameState)
	if err != nil {
		return err
	}

	return nil
}

func isWinForMark(gs []string, m string) bool {
	switch {
	case gs[0] == m && gs[3] == m && gs[6] == m:
		return true
	case gs[0] == m && gs[4] == m && gs[8] == m:
		return true
	case gs[1] == m && gs[4] == m && gs[7] == m:
		return true
	case gs[2] == m && gs[5] == m && gs[8] == m:
		return true
	case gs[2] == m && gs[4] == m && gs[6] == m:
		return true
	case gs[0] == m && gs[1] == m && gs[2] == m:
		return true
	case gs[3] == m && gs[4] == m && gs[5] == m:
		return true
	case gs[6] == m && gs[7] == m && gs[8] == m:
		return true
	default:
		return false
	}
}
<commit_msg>Added logic check to Tic-Tac-Toe engine to sure that positions player by bots are in the acceptable range.<commit_after>package games

import (
	"fmt"
	"log"

	"errors"

	"encoding/json"

	"github.com/mleonard87/merknera/repository"
)

const (
	TICTACTOE_MNEMONIC             = "TICTACTOE"
	TICTACTOE_NAME                 = "Tic-Tac-Toe"
	TICTACTOE_RPC_METHOD_NEXT_MOVE = "TicTacToe.NextMove"
	TICTACTOE_RPC_METHOD_COMPLETE  = "TicTacToe.Complete"
	TICTACTOE_RPC_METHOD_ERROR     = "TicTacToe.Error"
)

func init() {
	err := RegisterGameManager(new(TicTacToeGameManager))
	if err != nil {
		log.Fatal(err)
	}
}

type TicTacToeGameState []string

func (tgs *TicTacToeGameState) MarshalJSON() ([]byte, error) {
	sa := []string(*tgs)
	resultString := "{"
	for i, m := range sa {
		switch m {
		case "X":
			resultString += "\"X\""
		case "O":
			resultString += "\"O\""
		default:
			resultString += "null"
		}
		if i != len(sa) {
			resultString += ", "
		}
	}
	resultString += "}"

	fmt.Println("Marshalling JSON")
	fmt.Println(resultString)

	return []byte(resultString), nil
}

type TicTacToeGameManager struct{}

func (tgm TicTacToeGameManager) GenerateGames(bot repository.Bot) []repository.Game {
	gameType, err := repository.GetGameTypeByMnemonic(TICTACTOE_MNEMONIC)
	if err != nil {
		log.Fatal(err)
	}

	botList, err := repository.ListBotsForGameType(gameType)
	if err != nil {
		log.Fatal(err)
	}

	var gameList []repository.Game
	for _, b := range botList {
		// If its not the same bot as we are invoking this game for then create the game.
		if b.Id != bot.Id {
			// Create a game for these two bots with the initial bot as player 1
			game1, err := createGameWithPlayers(gameType, &b, &bot)
			if err != nil {
				log.Fatal(err)
			}
			// Create a game for these two bots with the initial bot as player 2
			game2, err := createGameWithPlayers(gameType, &bot, &b)
			if err != nil {
				log.Fatal(err)
			}
			gameList = append(gameList, game1, game2)
		}
	}

	return gameList
}

func (tgm TicTacToeGameManager) Mnemonic() string {
	return TICTACTOE_MNEMONIC
}

func (tgm TicTacToeGameManager) Name() string {
	return TICTACTOE_NAME
}

func (tgm TicTacToeGameManager) GetNextMoveRPCMethodName() string {
	return TICTACTOE_RPC_METHOD_NEXT_MOVE
}

func (tgm TicTacToeGameManager) GetCompleteRPCMethodName() string {
	return TICTACTOE_RPC_METHOD_COMPLETE
}

func (tgm TicTacToeGameManager) GetErrorRPCMethodName() string {
	return TICTACTOE_RPC_METHOD_ERROR
}

type nextMoveParams struct {
	GameId    int                `json:"gameid"`
	Mark      string             `json:"mark"`
	GameState TicTacToeGameState `json:"gamestate"`
}

func (tgm TicTacToeGameManager) GetNextMoveRPCParams(gameMove repository.GameMove) (interface{}, error) {
	gb, err := gameMove.GameBot()
	if err != nil {
		return nil, err
	}

	mark := getMarkForPlaySequence(gb.PlaySequence)

	g, err := gb.Game()
	if err != nil {
		return nil, err
	}

	gs, err := g.GameState()
	if err != nil {
		return nil, err
	}

	var tttGameState TicTacToeGameState
	err = json.Unmarshal([]byte(gs), &tttGameState)
	if err != nil {
		return nil, err
	}

	params := nextMoveParams{
		GameId:    g.Id,
		Mark:      mark,
		GameState: tttGameState,
	}

	return params, nil
}

type nextMoveResponse struct {
	Position int `json:"position"`
}

func (tgm TicTacToeGameManager) GetNextMoveRPCResult(gameMove repository.GameMove) interface{} {
	return nextMoveResponse{}
}

func (tgm TicTacToeGameManager) ProcessMove(gameMove repository.GameMove, result map[string]interface{}) (interface{}, bool, error) {
	var position int
	if pos, ok := result["position"].(float64); ok {
		position = int(pos)
	} else {
		return nil, false, errors.New("Could not find property \"position\" in your response or position was not an integer.")
	}

	gb, err := gameMove.GameBot()
	if err != nil {
		return nil, false, err
	}

	game, err := gb.Game()
	if err != nil {
		return nil, false, err
	}

	gs, err := game.GameState()
	if err != nil {
		return nil, false, err
	}

	var tttGameState TicTacToeGameState
	err = json.Unmarshal([]byte(gs), &tttGameState)
	if err != nil {
		return nil, false, err
	}

	// Check that the position played is within the range of the game board.
	if len(tttGameState) < position || position < 0 {
		msg := fmt.Sprintf("Invalid position: \"%d\" is not a valid position in a 3x3 Tic-Tac-Toe board. Valid positions are 0-8 inclusive.")
		return nil, false, errors.New(msg)
	}

	// Check that the position played has not already been played.
	if tttGameState[position] != "" {
		msg := fmt.Sprintf("Invalid position: The position you played, \"%d\", is already taken by \"%s\"", position, tttGameState[position])
		return nil, false, errors.New(msg)
	}

	mark := getMarkForPlaySequence(gb.PlaySequence)
	tttGameState[position] = mark

	win := isWinForMark(tttGameState, mark)

	return tttGameState, win, nil
}

func (tgm TicTacToeGameManager) GetGameBotForNextMove(currentMove repository.GameMove) (repository.GameBot, error) {
	gb, err := currentMove.GameBot()
	if err != nil {
		return repository.GameBot{}, err
	}

	game, err := gb.Game()
	if err != nil {
		return repository.GameBot{}, err
	}

	gameBots, err := game.Players()
	if err != nil {
		return repository.GameBot{}, err
	}

	for _, b := range gameBots {
		if b.Id != gb.Id {
			return b, nil
		}
	}

	return repository.GameBot{}, errors.New("Could not find GameBot for next move.")
}

type completeParams struct {
	GameId    int                `json:"gameid"`
	Winner    bool               `json:"winner"`
	Mark      string             `json:"mark"`
	GameState TicTacToeGameState `json:"gamestate"`
}

func (tgm TicTacToeGameManager) GetCompleteRPCParams(gb repository.GameBot) (interface{}, error) {
	game, err := gb.Game()
	if err != nil {
		return nil, err
	}

	gs, err := game.GameState()
	if err != nil {
		return nil, err
	}

	wm, err := game.WinningMove()
	if err != nil {
		return nil, err
	}

	winninggb, err := wm.GameBot()
	if err != nil {
		return nil, err
	}

	w := false
	if gb.Id == winninggb.Id {
		w = true
	}

	var tgs TicTacToeGameState
	err = json.Unmarshal([]byte(gs), &tgs)
	if err != nil {
		return nil, err
	}
	cp := completeParams{
		GameId:    game.Id,
		Winner:    w,
		Mark:      getMarkForPlaySequence(gb.PlaySequence),
		GameState: tgs,
	}

	return cp, nil
}

type errorParams struct {
	GameId    int    `json:"gameid"`
	Message   string `json:"message"`
	ErrorCode int    `json:"errorcode"`
}

func (tgm TicTacToeGameManager) GetErrorRPCParams(gm repository.GameMove, errorMessage string) interface{} {
	gb, _ := gm.GameBot()
	game, _ := gb.Game()
	return errorParams{
		GameId:    game.Id,
		Message:   errorMessage,
		ErrorCode: 999,
	}
}

func getMarkForPlaySequence(ps int) string {
	switch ps {
	case 1:
		return "X"
	case 2:
		return "O"
	default:
		log.Fatal("Invalid play sequence for Tic-Tac-Toe")
	}

	return ""
}

func createGameWithPlayers(gameType repository.GameType, playerOne *repository.Bot, playerTwo *repository.Bot) (repository.Game, error) {
	game, err := repository.CreateGame(gameType)
	if err != nil {
		return game, err
	}

	_, err = repository.CreateGameBot(game, *playerOne, 1)
	if err != nil {
		return game, err
	}

	_, err = repository.CreateGameBot(game, *playerTwo, 2)
	if err != nil {
		return game, err
	}

	err = createFirstGameMove(game)
	if err != nil {
		return game, err
	}

	return game, nil
}

func createFirstGameMove(game repository.Game) error {
	players, err := game.Players()
	if err != nil {
		return err
	}
	firstPlayer := players[0]
	initialGameState := make([]string, 9, 9)
	_, err = repository.CreateGameMove(firstPlayer, initialGameState)
	if err != nil {
		return err
	}

	return nil
}

func isWinForMark(gs []string, m string) bool {
	switch {
	case gs[0] == m && gs[3] == m && gs[6] == m:
		return true
	case gs[0] == m && gs[4] == m && gs[8] == m:
		return true
	case gs[1] == m && gs[4] == m && gs[7] == m:
		return true
	case gs[2] == m && gs[5] == m && gs[8] == m:
		return true
	case gs[2] == m && gs[4] == m && gs[6] == m:
		return true
	case gs[0] == m && gs[1] == m && gs[2] == m:
		return true
	case gs[3] == m && gs[4] == m && gs[5] == m:
		return true
	case gs[6] == m && gs[7] == m && gs[8] == m:
		return true
	default:
		return false
	}
}
<|endoftext|>


<commit_before>package mysonplugin

import (
	"github.com/iopred/bruxism"
	"github.com/iopred/discordgo"
)

func messageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) {
	if service.IsMe(message) || !bruxism.MatchesCommand(service, "myson", message) || service.Name() != bruxism.DiscordServiceName {
		return
	}

	discord := service.(*bruxism.Discord)
	discord.Session.ChannelMessageSendEmbed(message.Channel(), &discordgo.MessageEmbed{
		Color:       discord.Session.State.UserColor(service.UserID(), message.Channel()),
		Description: "Don't ever talk to me or my son ever again.",
		Author: &discordgo.MessageEmbedAuthor{
			Name:    discord.NicknameForID(service.UserID(), service.UserName(), message.Channel()),
			IconURL: discordgo.EndpointUserAvatar(service.UserID(), discord.Session.State.User.Avatar),
		},
	})
}

func helpFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message, detailed bool) []string {
	return nil
}

func New() bruxism.Plugin {
	p := bruxism.NewSimplePlugin("MySon")
	p.MessageFunc = messageFunc
	p.HelpFunc = helpFunc
	return p
}
<commit_msg>Fix color for myson.<commit_after>package mysonplugin

import (
	"github.com/iopred/bruxism"
	"github.com/iopred/discordgo"
)

func messageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) {
	if service.IsMe(message) || !bruxism.MatchesCommand(service, "myson", message) || service.Name() != bruxism.DiscordServiceName {
		return
	}

	discord := service.(*bruxism.Discord)
	discord.Session.ChannelMessageSendEmbed(message.Channel(), &discordgo.MessageEmbed{
		Color:       discord.UserColor(service.UserID(), message.Channel()),
		Description: "Don't ever talk to me or my son ever again.",
		Author: &discordgo.MessageEmbedAuthor{
			Name:    discord.NicknameForID(service.UserID(), service.UserName(), message.Channel()),
			IconURL: discordgo.EndpointUserAvatar(service.UserID(), discord.Session.State.User.Avatar),
		},
	})
}

func helpFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message, detailed bool) []string {
	return nil
}

func New() bruxism.Plugin {
	p := bruxism.NewSimplePlugin("MySon")
	p.MessageFunc = messageFunc
	p.HelpFunc = helpFunc
	return p
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	mkr "github.com/mackerelio/mackerel-client-go"
	"github.com/mackerelio/mkr/logger"
	"gopkg.in/urfave/cli.v1"
)

var commandAnnotations = cli.Command{
	Name: "annotations",
	Subcommands: []cli.Command{
		{
			Name:        "create",
			Usage:       "create annotation",
			Description: "Creates an annotation.",
			Action:      doAnnotationsCreate,
			Flags: []cli.Flag{
				cli.StringFlag{Name: "title", Value: "", Usage: "Title for annotation."},
				cli.StringFlag{Name: "description", Value: "", Usage: "Description for annotation."},
				cli.IntFlag{Name: "from"},
				cli.IntFlag{Name: "to"},
				cli.StringFlag{Name: "service, s", Value: "", Usage: "Service name for annotation."},
				cli.StringSliceFlag{
					Name:  "role, r",
					Value: &cli.StringSlice{},
					Usage: "Roles for annotation. Multiple choices are allowed.",
				},
			},
		},
		{
			Name:        "list",
			Usage:       "list annotations",
			Description: "Shows annotations by service name and duration(from and to).",
			Action:      doAnnotationsList,
			Flags: []cli.Flag{
				cli.StringFlag{Name: "service, s", Value: "", Usage: "Service name for annotation."},
				cli.IntFlag{Name: "from"},
				cli.IntFlag{Name: "to"},
			},
		},
		{
			Name:        "update",
			Usage:       "update annotation",
			Description: "Updates an annotation.",
			Action:      doAnnotationsUpdate,
			Flags: []cli.Flag{
				cli.StringFlag{Name: "id", Value: "", Usage: "Annotation ID."},
				cli.StringFlag{Name: "service, s", Value: "", Usage: "Service name for annotation."},
				cli.StringFlag{Name: "title", Value: "", Usage: "Title for annotation."},
				cli.StringFlag{Name: "description", Value: "", Usage: "Description for annotation."},
				cli.IntFlag{Name: "from"},
				cli.IntFlag{Name: "to"},
				cli.StringSliceFlag{
					Name:  "role, r",
					Value: &cli.StringSlice{},
					Usage: "Roles for annotation. Multiple choices are allowed.",
				},
			},
		},
		{
			Name:        "delete",
			Usage:       "delete annotation",
			Description: "Delete graph annotation by annotation id.",
			Action:      doAnnotationsDelete,
			Flags: []cli.Flag{
				cli.StringFlag{Name: "id", Value: "", Usage: "Reason of closing alert."},
			},
		},
	},
}

func doAnnotationsCreate(c *cli.Context) error {
	title := c.String("title")
	description := c.String("description")
	from := c.Int64("from")
	to := c.Int64("to")
	service := c.String("service")
	roles := c.StringSlice("role")

	if service == "" || from == 0 || to == 0 {
		_ = cli.ShowCommandHelp(c, "create")
		os.Exit(1)
	}

	client := newMackerelFromContext(c)
	err := client.CreateGraphAnnotation(&mkr.GraphAnnotation{
		Title:       title,
		Description: description,
		From:        from,
		To:          to,
		Service:     service,
		Roles:       roles,
	})
	logger.DieIf(err)
	return nil
}

func doAnnotationsList(c *cli.Context) error {
	service := c.String("service")
	from := c.Int64("from")
	to := c.Int64("to")

	if service == "" || from == 0 || to == 0 {
		_ = cli.ShowCommandHelp(c, "list")
		os.Exit(1)
	}

	client := newMackerelFromContext(c)
	annotations, err := client.FindGraphAnnotations(service, from, to)
	logger.DieIf(err)
	PrettyPrintJSON(annotations)
	return nil
}

func doAnnotationsUpdate(c *cli.Context) error {
	annotationID := c.String("id")
	title := c.String("title")
	description := c.String("description")
	from := c.Int64("from")
	to := c.Int64("to")
	service := c.String("service")
	roles := c.StringSlice("role")

	if service == "" || from == 0 || to == 0 {
		_ = cli.ShowCommandHelp(c, "update")
		os.Exit(1)
	}

	client := newMackerelFromContext(c)
	annotation, err := client.UpdateGraphAnnotation(annotationID, &mkr.GraphAnnotation{
		Title:       title,
		Description: description,
		From:        from,
		To:          to,
		Service:     service,
		Roles:       roles,
	})
	logger.DieIf(err)
	PrettyPrintJSON(annotation)
	return nil
}

func doAnnotationsDelete(c *cli.Context) error {
	annotationID := c.String("id")

	if annotationID == "" {
		_ = cli.ShowCommandHelp(c, "delete")
		os.Exit(1)
	}

	client := newMackerelFromContext(c)
	annotation, err := client.DeleteGraphAnnotation(annotationID)
	logger.DieIf(err)
	PrettyPrintJSON(annotation)
	return nil
}
<commit_msg>add description for annotations command<commit_after>package main

import (
	"os"

	mkr "github.com/mackerelio/mackerel-client-go"
	"github.com/mackerelio/mkr/logger"
	"gopkg.in/urfave/cli.v1"
)

var commandAnnotations = cli.Command{
	Name: "annotations",
	Description: `
    Manipulate graph annotations. Requests APIs under "/api/v0/graph-annotations".
    See https://mackerel.io/api-docs/entry/graph-annotations .
`,
	Subcommands: []cli.Command{
		{
			Name:        "create",
			Usage:       "create annotation",
			Description: "Creates an annotation.",
			Action:      doAnnotationsCreate,
			Flags: []cli.Flag{
				cli.StringFlag{Name: "title", Value: "", Usage: "Title for annotation."},
				cli.StringFlag{Name: "description", Value: "", Usage: "Description for annotation."},
				cli.IntFlag{Name: "from"},
				cli.IntFlag{Name: "to"},
				cli.StringFlag{Name: "service, s", Value: "", Usage: "Service name for annotation."},
				cli.StringSliceFlag{
					Name:  "role, r",
					Value: &cli.StringSlice{},
					Usage: "Roles for annotation. Multiple choices are allowed.",
				},
			},
		},
		{
			Name:        "list",
			Usage:       "list annotations",
			Description: "Shows annotations by service name and duration(from and to).",
			Action:      doAnnotationsList,
			Flags: []cli.Flag{
				cli.StringFlag{Name: "service, s", Value: "", Usage: "Service name for annotation."},
				cli.IntFlag{Name: "from"},
				cli.IntFlag{Name: "to"},
			},
		},
		{
			Name:        "update",
			Usage:       "update annotation",
			Description: "Updates an annotation.",
			Action:      doAnnotationsUpdate,
			Flags: []cli.Flag{
				cli.StringFlag{Name: "id", Value: "", Usage: "Annotation ID."},
				cli.StringFlag{Name: "service, s", Value: "", Usage: "Service name for annotation."},
				cli.StringFlag{Name: "title", Value: "", Usage: "Title for annotation."},
				cli.StringFlag{Name: "description", Value: "", Usage: "Description for annotation."},
				cli.IntFlag{Name: "from"},
				cli.IntFlag{Name: "to"},
				cli.StringSliceFlag{
					Name:  "role, r",
					Value: &cli.StringSlice{},
					Usage: "Roles for annotation. Multiple choices are allowed.",
				},
			},
		},
		{
			Name:        "delete",
			Usage:       "delete annotation",
			Description: "Delete graph annotation by annotation id.",
			Action:      doAnnotationsDelete,
			Flags: []cli.Flag{
				cli.StringFlag{Name: "id", Value: "", Usage: "Reason of closing alert."},
			},
		},
	},
}

func doAnnotationsCreate(c *cli.Context) error {
	title := c.String("title")
	description := c.String("description")
	from := c.Int64("from")
	to := c.Int64("to")
	service := c.String("service")
	roles := c.StringSlice("role")

	if service == "" || from == 0 || to == 0 {
		_ = cli.ShowCommandHelp(c, "create")
		os.Exit(1)
	}

	client := newMackerelFromContext(c)
	err := client.CreateGraphAnnotation(&mkr.GraphAnnotation{
		Title:       title,
		Description: description,
		From:        from,
		To:          to,
		Service:     service,
		Roles:       roles,
	})
	logger.DieIf(err)
	return nil
}

func doAnnotationsList(c *cli.Context) error {
	service := c.String("service")
	from := c.Int64("from")
	to := c.Int64("to")

	if service == "" || from == 0 || to == 0 {
		_ = cli.ShowCommandHelp(c, "list")
		os.Exit(1)
	}

	client := newMackerelFromContext(c)
	annotations, err := client.FindGraphAnnotations(service, from, to)
	logger.DieIf(err)
	PrettyPrintJSON(annotations)
	return nil
}

func doAnnotationsUpdate(c *cli.Context) error {
	annotationID := c.String("id")
	title := c.String("title")
	description := c.String("description")
	from := c.Int64("from")
	to := c.Int64("to")
	service := c.String("service")
	roles := c.StringSlice("role")

	if service == "" || from == 0 || to == 0 {
		_ = cli.ShowCommandHelp(c, "update")
		os.Exit(1)
	}

	client := newMackerelFromContext(c)
	annotation, err := client.UpdateGraphAnnotation(annotationID, &mkr.GraphAnnotation{
		Title:       title,
		Description: description,
		From:        from,
		To:          to,
		Service:     service,
		Roles:       roles,
	})
	logger.DieIf(err)
	PrettyPrintJSON(annotation)
	return nil
}

func doAnnotationsDelete(c *cli.Context) error {
	annotationID := c.String("id")

	if annotationID == "" {
		_ = cli.ShowCommandHelp(c, "delete")
		os.Exit(1)
	}

	client := newMackerelFromContext(c)
	annotation, err := client.DeleteGraphAnnotation(annotationID)
	logger.DieIf(err)
	PrettyPrintJSON(annotation)
	return nil
}
<|endoftext|>


<commit_before>package tensor3

import "runtime"

func init() {
	Hints.Threads = runtime.NumCPU() - 1
	Hints.DefaultChunkSize = 10000
}

// parallel optimisation Hints.
var Hints struct {
	Threads          int   // used to keep chunk to core ratio near parity.
	ChunkSizeFixed   bool
	DefaultChunkSize int   // ideally set at run time to number of items that fit into CPU cache.
}

// selects parallel application of functions to Vectors and Matrices types (slices of Vector and Matrix types).
var Parallel bool

// selects parallel application of functions to Matrix components,(its Vector fields).
// only improves performance if using costly functions, non of the built-ins are likely to benefit. YRMV.
var ParallelComponents bool

// use hints to calc a good chunk size
func chunkSize(l int) int {
	if !Hints.ChunkSizeFixed {
		if cs := l / Hints.Threads; cs > Hints.DefaultChunkSize {
			return cs
		}
	}
	return Hints.DefaultChunkSize
}

// return a channel of Vectors that are chunks of the passed Vectors
func vectorsInChunks(vs Vectors, cs int) chan Vectors {
	c := make(chan Vectors, 1)
	lastSplitMax := len(vs)-cs/2
	go func() {
		var bottom int
		for top := cs; top < lastSplitMax; top += cs {
			c <- vs[bottom:top]
			bottom = top
		}
		c <- vs[bottom:]
		close(c)
	}()
	return c
}

// return a channel of Matrices that are chunks of the passed Matrices
func matricesInChunks(ms Matrices, cs int) chan Matrices {
	c := make(chan Matrices)
	lastSplitMax := len(ms)-cs/2
	go func() {
		var bottom int
		for top := cs; top < lastSplitMax; top += cs {
			c <- ms[bottom:top]
			bottom = top
		}
		c <- ms[bottom:]
		close(c)
	}()
	return c
}

// return a channel of VectorRefs that are chunks of the passed VectorRefs
func vectorRefsInChunks(vs VectorRefs, cs int) chan VectorRefs {
	c := make(chan VectorRefs, 1)
	lastSplitMax := len(vs)-cs/2
	go func() {
		var bottom int
		for top := cs; top < lastSplitMax; top += cs {
			c <- vs[bottom:top]
			bottom = top
		}
		c <- vs[bottom:]
		close(c)
	}()
	return c
}

// return a channel of chunks of, fixed length slices of, the passed Vectors
// progress by Stride Vector's for each slice, if Stride less than length, the same Vector can appear in consecutive slices.
// if wrap true, include slices that wrap around, from the end to the start of the passed Vectors.
// notice: all the slices will be the same provided length.
// notice: can panic if length larger than chunksize/2 (ie the min. terminal chunk size)
func vectorSlicesInChunks(vs Vectors, cs int,length,stride int, wrap bool) chan []Vectors {
	c := make(chan []Vectors, 2)  // 2 so that the next chunk is being calculated in parallel, here unlike other chunking it has a significant cost, although if all cores kept 100% busy, not beneficial.
	go func(){
		// need to special case last chunk; it might have to include the wrap-round's, but don't know its the last until channel closes, so handle previous loop cycle.
		chunkChan :=vectorsInChunks(vs,cs)
		firstChunk := <- chunkChan // keep first chunk for potential wrap-round
		previousChunk := firstChunk
		var i int
		for chunk:=range chunkChan{
			vssc := make([]Vectors,len(previousChunk)/stride)
			for ;i<len(vssc);i+=stride {
				vssc[i]=previousChunk[i:i+length]
			}
			c <- vssc
			previousChunk=chunk
			i%=stride  // reset start index, allowing for stride continuation
		}
		// now handle the last (previous) chunk
		if wrap {
			vssc := make([]Vectors,len(previousChunk)/stride)
			for ; i< len(vssc)-length+1;i+=stride {
				vssc[i]=previousChunk[i:i+length]
			}
			// add the overlapping slices
			for ;i < len(vssc);i+=stride {
				vssc[i]=previousChunk[i:]
				vssc[i]=append(vssc[i],firstChunk[:length-len(vssc[i])]...)
			}
			c <- vssc
		}else{
			// not wrapping so its just shortened
			vssc := make([]Vectors,(len(previousChunk)-length+1)/stride)
			for ;i < len(vssc);i+=stride {
				vssc[i]=previousChunk[i:i+length]
			}
			c <- vssc
		}
		close(c)
	}()
	return c
}

// TODO VectorRefSlicesInChunks(vs Vectors, cs int,length,stride int, wrap bool) chan []Vectors {

// return a channel of VectorRefs that are chunks of the passed VectorRefs.
// as an optimisation, which some functions might benefit from, the VectorRefs are split so that each chunk contains all/only the VectorRefs within a spacial region, meaning nearby points are MUCH more likely to be in the same chunk.
func vectorRefsInRegionalChunks(vs VectorRefs, centre Vector, cs int) chan VectorRefs {
	// TODO continue to subdivide if exceed chunk size?
	// TODO return, another channel?, boundingbox of chunk?
	cvr := make(chan VectorRefs,8)  // no blocking since a max on 8 VectorRefs from this used split function
	// range over a slice of VectorRefs, returned by the Split function using a function that splits into 8 regions using which side of the origin Vector, by axis alignment, the point is on.
	for _,s:=range func() []VectorRefs {
		return vs.Split(
			func(v *Vector)(i uint){
				i++   // i never zero,since all points go somewhere
				if v.x>=centre.x {i++}
				if v.y>=centre.y {i+=2}
				if v.z>=centre.z {i+=4}
				return
			},
		)
	}(){
		cvr <- s
	}
	close(cvr)
	return cvr
}

<commit_msg>comments<commit_after>package tensor3

import "runtime"

func init() {
	Hints.Threads = runtime.NumCPU() - 1
	Hints.DefaultChunkSize = 10000
}

// parallel optimisation Hints.
var Hints struct {
	Threads          int   // used to keep chunk to core ratio near parity.
	ChunkSizeFixed   bool
	DefaultChunkSize int   // ideally set at run time to number of items that fit into CPU cache.
}

// selects parallel application of functions to Vectors and Matrices types (slices of Vector and Matrix types).
var Parallel bool

// selects parallel application of functions to Matrix components,(its Vector fields).
// only improves performance if using costly functions, non of the built-ins are likely to benefit. YRMV.
var ParallelComponents bool

// use hints to calc a good chunk size
func chunkSize(l int) int {
	if !Hints.ChunkSizeFixed {
		if cs := l / Hints.Threads; cs > Hints.DefaultChunkSize {
			return cs
		}
	}
	return Hints.DefaultChunkSize
}

// return a channel of Vectors that are chunks of the passed Vectors
func vectorsInChunks(vs Vectors, cs int) chan Vectors {
	c := make(chan Vectors, 1)
	lastSplitMax := len(vs)-cs/2
	go func() {
		var bottom int
		for top := cs; top < lastSplitMax; top += cs {
			c <- vs[bottom:top]
			bottom = top
		}
		c <- vs[bottom:]
		close(c)
	}()
	return c
}

// return a channel of Matrices that are chunks of the passed Matrices
func matricesInChunks(ms Matrices, cs int) chan Matrices {
	c := make(chan Matrices)
	lastSplitMax := len(ms)-cs/2
	go func() {
		var bottom int
		for top := cs; top < lastSplitMax; top += cs {
			c <- ms[bottom:top]
			bottom = top
		}
		c <- ms[bottom:]
		close(c)
	}()
	return c
}

// return a channel of VectorRefs that are chunks of the passed VectorRefs
func vectorRefsInChunks(vs VectorRefs, cs int) chan VectorRefs {
	c := make(chan VectorRefs, 1)
	lastSplitMax := len(vs)-cs/2
	go func() {
		var bottom int
		for top := cs; top < lastSplitMax; top += cs {
			c <- vs[bottom:top]
			bottom = top
		}
		c <- vs[bottom:]
		close(c)
	}()
	return c
}

// return a channel of slices of the passed Vectors.
// each returned slice is of the provided Length.
// the start index is increased by Stride for each slice.
// if wrap true, then the last Vector is considered to join to the first.
// notice: wrapped around slices are newly created, modifying their content, unlike non-wrapped, won't change the source Vectors, if consistent behaviour needed use VectorRefs chunks.
// notice: if Stride less than Length, then the same Vector will appear in consecutive slices.
// notice: can panic if Length larger than chunksize/2 (ie the min. possible size of the last chunk)
func vectorSlicesInChunks(vs Vectors, cs int,length,stride int, wrap bool) chan []Vectors {
	c := make(chan []Vectors, 2)  // 2 so that the next chunk is being calculated in parallel, here unlike other chunking it has a significant cost, although if all cores kept 100% busy, not beneficial.
	go func(){
		// need to special case last chunk; it might have to include the wrap-round's, but don't know its the last until channel closes, so handle previous loop cycle.
		chunkChan :=vectorsInChunks(vs,cs)
		firstChunk := <- chunkChan // keep first chunk for potential wrap-round
		previousChunk := firstChunk
		var i int
		for chunk:=range chunkChan{
			vssc := make([]Vectors,len(previousChunk)/stride)
			for ;i<len(vssc);i+=stride {
				vssc[i]=previousChunk[i:i+length]
			}
			c <- vssc
			previousChunk=chunk
			i%=stride  // reset start index, allowing for stride continuation
		}
		// now handle the last (previous) chunk
		if wrap {
			vssc := make([]Vectors,len(previousChunk)/stride)
			for ; i< len(vssc)-length+1;i+=stride {
				vssc[i]=previousChunk[i:i+length]
			}
			// add the beginning Vectors
			for ;i < len(vssc);i+=stride {
				vssc[i]=previousChunk[i:]
				vssc[i]=append(vssc[i],firstChunk[:length-len(vssc[i])]...)
			}
			c <- vssc
		}else{
			// not wrapping so its just shortened
			vssc := make([]Vectors,(len(previousChunk)-length+1)/stride)
			for ;i < len(vssc);i+=stride {
				vssc[i]=previousChunk[i:i+length]
			}
			c <- vssc
		}
		close(c)
	}()
	return c
}

// TODO VectorRefSlicesInChunks(vs Vectors, cs int,length,stride int, wrap bool) chan []Vectors {

// return a channel of VectorRefs that are chunks of the passed VectorRefs.
// as an optimisation, which some functions might benefit from, the VectorRefs are split so that each chunk contains all/only the VectorRefs within a spacial region, meaning nearby points are MUCH more likely to be in the same chunk.
func vectorRefsInRegionalChunks(vs VectorRefs, centre Vector, cs int) chan VectorRefs {
	// TODO continue to subdivide if exceed chunk size?
	// TODO return, another channel?, boundingbox of chunk?
	cvr := make(chan VectorRefs,8)  // non blocking since a max on 8 VectorRefs from this split function
	// range over a slice of VectorRefs, returned by the Split function using a function that splits into 8 regions using which side of the origin Vector, by axis alignment, the point is on.
	for _,s:=range func() []VectorRefs {
		return vs.Split(
			func(v *Vector)(i uint){
				i++   // index never zero, since for this all points go somewhere
				if v.x>=centre.x {i++}
				if v.y>=centre.y {i+=2}
				if v.z>=centre.z {i+=4}
				return
			},
		)
	}(){
		cvr <- s
	}
	close(cvr)
	return cvr
}

<|endoftext|>


<commit_before>// Copyright 2014 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package api

import (
	"github.com/tsuru/tsuru/action"
	"github.com/tsuru/tsuru/auth"
)

var addUserToTeamInRepositoryAction = action.Action{
	Name: "add-user-to-team-in-repository",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		u := ctx.Params[0].(*auth.User)
		t := ctx.Params[1].(*auth.Team)
		return nil, addUserToTeamInRepository(u, t)
	},
	Backward: func(ctx action.BWContext) {
		u := ctx.Params[0].(*auth.User)
		team := ctx.Params[1].(*auth.Team)
		removeUserFromTeamInRepository(u, team)
	},
}

var addUserToTeamInDatabaseAction = action.Action{
	Name: "add-user-to-team-in-database",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		u := ctx.Params[0].(*auth.User)
		t := ctx.Params[1].(*auth.Team)
		return nil, addUserToTeamInDatabase(u, t)
	},
	Backward: func(ctx action.BWContext) {
		u := ctx.Params[0].(*auth.User)
		t := ctx.Params[1].(*auth.Team)
		removeUserFromTeamInDatabase(u, t)
	},
}
<commit_msg>api: fix year in copyright header<commit_after>// Copyright 2015 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package api

import (
	"github.com/tsuru/tsuru/action"
	"github.com/tsuru/tsuru/auth"
)

var addUserToTeamInRepositoryAction = action.Action{
	Name: "add-user-to-team-in-repository",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		u := ctx.Params[0].(*auth.User)
		t := ctx.Params[1].(*auth.Team)
		return nil, addUserToTeamInRepository(u, t)
	},
	Backward: func(ctx action.BWContext) {
		u := ctx.Params[0].(*auth.User)
		team := ctx.Params[1].(*auth.Team)
		removeUserFromTeamInRepository(u, team)
	},
}

var addUserToTeamInDatabaseAction = action.Action{
	Name: "add-user-to-team-in-database",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		u := ctx.Params[0].(*auth.User)
		t := ctx.Params[1].(*auth.Team)
		return nil, addUserToTeamInDatabase(u, t)
	},
	Backward: func(ctx action.BWContext) {
		u := ctx.Params[0].(*auth.User)
		t := ctx.Params[1].(*auth.Team)
		removeUserFromTeamInDatabase(u, t)
	},
}
<|endoftext|>


<commit_before>/*
   Nging is a toolbox for webmasters
   Copyright (C) 2018-present  Wenhui Shen <swh@admpub.com>

   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 <https://www.gnu.org/licenses/>.
*/
package middleware

import (
	"strings"
	"time"

	"github.com/admpub/nging/application/handler"
	"github.com/admpub/nging/application/library/config"
	"github.com/admpub/nging/application/library/license"
	"github.com/admpub/nging/application/model"
	"github.com/admpub/nging/application/registry/perm"
	"github.com/webx-top/echo"
)

func AuthCheck(h echo.Handler) echo.HandlerFunc {
	return func(c echo.Context) error {
		//检查是否已安装
		if !config.IsInstalled() {
			return c.Redirect(handler.URLFor(`/setup`))
		}

		//验证授权文件
		if !license.Ok(c.Host()) {
			return c.Redirect(handler.URLFor(`/license`))
		}

		if user := handler.User(c); user != nil {
			if jump, ok := c.Session().Get(`auth2ndURL`).(string); ok && len(jump) > 0 {
				return c.Redirect(jump)
			}
			var (
				rpath = c.Path()
				ppath string
			)
			//println(`--------------------->>>`, rpath)
			if len(handler.BackendPrefix) > 0 {
				rpath = strings.TrimPrefix(rpath, handler.BackendPrefix)
			}
			if user.Id == 1 || strings.HasPrefix(rpath, `/user/`) {
				c.SetFunc(`CheckPerm`, func(route string) error {
					return nil
				})
				return h.Handle(c)
			}
			roleList := handler.RoleList(c)
			roleM := model.NewUserRole(c)
			if checker, ok := perm.SpecialAuths[rpath]; ok {
				var err error
				var ret bool
				err, ppath, ret = checker(h, c, rpath, user, roleM, roleList)
				if ret {
					return err
				}
				if err != nil {
					return err
				}
			} else {
				ppath = rpath
				if len(ppath) >= 13 {
					switch ppath[0:13] {
					case `/term/client/`:
						ppath = `/term/client`
					default:
						if strings.HasPrefix(rpath, `/frp/dashboard/`) {
							ppath = `/frp/dashboard`
						}
					}
				}
			}
			if !roleM.CheckPerm2(roleList, ppath) {
				return echo.ErrForbidden
			}
			c.SetFunc(`CheckPerm`, func(route string) error {
				if user.Id == 1 {
					return nil
				}
				if !roleM.CheckPerm2(roleList, route) {
					return echo.ErrForbidden
				}
				return nil
			})
			return h.Handle(c)
		}
		return c.Redirect(handler.URLFor(`/login`))
	}
}

func Auth(c echo.Context, saveSession bool) error {
	user := c.Form(`user`)
	pass := c.Form(`pass`)

	m := model.NewUser(c)
	exists, err := m.CheckPasswd(user, pass)
	if !exists {
		return c.E(`用户不存在`)
	}
	if err == nil {
		if saveSession {
			m.SetSession()
		}
		if m.NeedCheckU2F(m.User.Id) {
			c.Session().Set(`auth2ndURL`, handler.URLFor(`/gauth_check`))
		}
		m.User.LastLogin = uint(time.Now().Unix())
		m.User.LastIp = c.RealIP()
		m.User.Param().SetSend(map[string]interface{}{
			`last_login`: m.User.LastLogin,
			`last_ip`:    m.User.LastIp,
		}).SetArgs(`id`, m.User.Id).Update()
	}
	return err
}
<commit_msg>update<commit_after>/*
   Nging is a toolbox for webmasters
   Copyright (C) 2018-present  Wenhui Shen <swh@admpub.com>

   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 <https://www.gnu.org/licenses/>.
*/
package middleware

import (
	"strings"
	"time"

	"github.com/admpub/nging/application/handler"
	"github.com/admpub/nging/application/library/config"
	"github.com/admpub/nging/application/library/license"
	"github.com/admpub/nging/application/model"
	"github.com/admpub/nging/application/registry/perm"
	"github.com/webx-top/echo"
)

func AuthCheck(h echo.Handler) echo.HandlerFunc {
	return func(c echo.Context) error {
		//检查是否已安装
		if !config.IsInstalled() {
			c.Data().SetError(c.E(`请先安装`))
			return c.Redirect(handler.URLFor(`/setup`))
		}

		//验证授权文件
		if !license.Ok(c.Host()) {
			c.Data().SetError(c.E(`请先获取本系统授权`))
			return c.Redirect(handler.URLFor(`/license`))
		}

		if user := handler.User(c); user != nil {
			if jump, ok := c.Session().Get(`auth2ndURL`).(string); ok && len(jump) > 0 {
				c.Data().SetError(c.E(`请先进行第二步验证`))
				return c.Redirect(jump)
			}
			var (
				rpath = c.Path()
				ppath string
			)
			//println(`--------------------->>>`, rpath)
			if len(handler.BackendPrefix) > 0 {
				rpath = strings.TrimPrefix(rpath, handler.BackendPrefix)
			}
			if user.Id == 1 || strings.HasPrefix(rpath, `/user/`) {
				c.SetFunc(`CheckPerm`, func(route string) error {
					return nil
				})
				return h.Handle(c)
			}
			roleList := handler.RoleList(c)
			roleM := model.NewUserRole(c)
			if checker, ok := perm.SpecialAuths[rpath]; ok {
				var err error
				var ret bool
				err, ppath, ret = checker(h, c, rpath, user, roleM, roleList)
				if ret {
					return err
				}
				if err != nil {
					return err
				}
			} else {
				ppath = rpath
				if len(ppath) >= 13 {
					switch ppath[0:13] {
					case `/term/client/`:
						ppath = `/term/client`
					default:
						if strings.HasPrefix(rpath, `/frp/dashboard/`) {
							ppath = `/frp/dashboard`
						}
					}
				}
			}
			if !roleM.CheckPerm2(roleList, ppath) {
				return echo.ErrForbidden
			}
			c.SetFunc(`CheckPerm`, func(route string) error {
				if user.Id == 1 {
					return nil
				}
				if !roleM.CheckPerm2(roleList, route) {
					return echo.ErrForbidden
				}
				return nil
			})
			return h.Handle(c)
		}
		c.Data().SetError(c.E(`请先登录`))
		return c.Redirect(handler.URLFor(`/login`))
	}
}

func Auth(c echo.Context, saveSession bool) error {
	user := c.Form(`user`)
	pass := c.Form(`pass`)

	m := model.NewUser(c)
	exists, err := m.CheckPasswd(user, pass)
	if !exists {
		return c.E(`用户不存在`)
	}
	if err == nil {
		if saveSession {
			m.SetSession()
		}
		if m.NeedCheckU2F(m.User.Id) {
			c.Session().Set(`auth2ndURL`, handler.URLFor(`/gauth_check`))
		}
		m.User.LastLogin = uint(time.Now().Unix())
		m.User.LastIp = c.RealIP()
		m.User.Param().SetSend(map[string]interface{}{
			`last_login`: m.User.LastLogin,
			`last_ip`:    m.User.LastIp,
		}).SetArgs(`id`, m.User.Id).Update()
	}
	return err
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/docker/docker/pkg/reexec"
	"github.com/golang/glog"
	"github.com/hyperhq/runv/driverloader"
	"github.com/hyperhq/runv/hypervisor"
	"github.com/urfave/cli"
)

var (
	version   = ""
	gitCommit = ""
)

const (
	specConfig  = "config.json"
	stateJSON   = "state.json"
	processJSON = "process.json"
	usage       = `Open Container Initiative hypervisor-based runtime

runv is a command line client for running applications packaged according to
the Open Container Format (OCF) and is a compliant implementation of the
Open Container Initiative specification.  However, due to the difference
between hypervisors and containers, the following sections of OCF don't
apply to runV:
    Namespace
    Capability
    Device
    "linux" and "mount" fields in OCI specs are ignored

The current release of "runV" supports the following hypervisors:
    KVM (QEMU 2.0 or later)
    Xen (4.5 or later)
    VirtualBox (Mac OS X)

After creating a spec for your root filesystem, you can execute a container
in your shell by running:

    # cd /mycontainer
    # runv run [ -b bundle ] <container-id>

If not specified, the default value for the 'bundle' is the current directory.
'Bundle' is the directory where '` + specConfig + `' must be located.`
)

func main() {
	if reexec.Init() {
		return
	}

	app := cli.NewApp()
	app.Name = "runv"
	app.Usage = usage
	app.Version = fmt.Sprintf("%s, commit: %s", version, gitCommit)
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug",
			Usage: "enable debug output for logging, saved on the dir specified by log_dir via glog style",
		},
		cli.StringFlag{
			Name:  "log_dir",
			Value: "/var/log/hyper",
			Usage: "the directory for the logging (glog style)",
		},
		cli.StringFlag{
			Name:  "log",
			Value: "/dev/null",
			Usage: "[ignored on runv] set the log file path where internal debug information is written",
		},
		cli.StringFlag{
			Name:  "log-format",
			Usage: "[ignored on runv] set the format used by logs ('text' (default), or 'json')",
		},
		cli.StringFlag{
			Name:  "root",
			Value: "/run/runv",
			Usage: "root directory for storage of container state (this should be located in tmpfs)",
		},
		cli.StringFlag{
			Name:  "driver",
			Usage: "hypervisor driver (supports: kvm xen)",
		},
		cli.IntFlag{
			Name:  "default_cpus",
			Usage: "default number of vcpus to assign pod",
			Value: 1,
		},
		cli.IntFlag{
			Name:  "default_memory",
			Usage: "default memory to assign pod (mb)",
			Value: 128,
		},
		cli.StringFlag{
			Name:  "kernel",
			Usage: "kernel for the container",
		},
		cli.StringFlag{
			Name:  "initrd",
			Usage: "runv-compatible initrd for the container",
		},
		cli.StringFlag{
			Name:  "bios",
			Usage: "bios for the container",
		},
		cli.StringFlag{
			Name:  "cbfs",
			Usage: "cbfs for the container",
		},
		cli.StringFlag{
			Name:  "template",
			Usage: "path to the template vm state directory",
		},
	}
	app.After = func(context *cli.Context) error {
		// make sure glog flush all the messages to file
		glog.Flush()
		return nil
	}

	app.Commands = []cli.Command{
		createCommand,
		execCommand,
		interfaceCommand,
		killCommand,
		listCommand,
		psCommand,
		runCommand,
		specCommand,
		startCommand,
		stateCommand,
		manageCommand,
		pauseCommand,
		resumeCommand,
		deleteCommand,
		proxyCommand,
		shimCommand,
		nsListenCommand,
		watcherCommand,
	}
	if err := app.Run(os.Args); err != nil {
		glog.Errorf("app.Run(os.Args) failed with err: %#v", err)
		fmt.Fprintf(os.Stderr, "%v\n", err)
		cli.HandleExitCoder(err)
		// non-standard errors
		os.Exit(22)
	}
}

// runvOptions is used for create aux runv processes (networklistener/shim/proxy)
type runvOptions struct {
	*cli.Context
	withContainer *State
	attach        bool
}

func cmdPrepare(context *cli.Context, setupHypervisor, canLogToStderr bool) error {
	if setupHypervisor {
		var err error
		if hypervisor.HDriver, err = driverloader.Probe(context.GlobalString("driver")); err != nil {
			return err
		}
		setupHyperstartFunc(context)
	}

	logdir := context.GlobalString("log_dir")
	if logdir != "" {
		if err := os.MkdirAll(logdir, 0750); err != nil {
			return fmt.Errorf("can't create dir %q for log files", logdir)
		}
	}
	if !context.GlobalBool("debug") {
		flag.CommandLine.Parse([]string{"-v", "1", "--log_dir", logdir})
	} else if canLogToStderr {
		flag.CommandLine.Parse([]string{"-v", "3", "--log_dir", logdir, "--alsologtostderr"})
	} else {
		flag.CommandLine.Parse([]string{"-v", "3", "--log_dir", logdir})
	}
	return nil
}
<commit_msg>update the output format of `runv --version`<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"strings"

	"github.com/docker/docker/pkg/reexec"
	"github.com/golang/glog"
	"github.com/hyperhq/runv/driverloader"
	"github.com/hyperhq/runv/hypervisor"
	"github.com/opencontainers/runtime-spec/specs-go"
	"github.com/urfave/cli"
)

var (
	version   = ""
	gitCommit = ""
)

const (
	specConfig  = "config.json"
	stateJSON   = "state.json"
	processJSON = "process.json"
	usage       = `Open Container Initiative hypervisor-based runtime

runv is a command line client for running applications packaged according to
the Open Container Format (OCF) and is a compliant implementation of the
Open Container Initiative specification.  However, due to the difference
between hypervisors and containers, the following sections of OCF don't
apply to runV:
    Namespace
    Capability
    Device
    "linux" and "mount" fields in OCI specs are ignored

The current release of "runV" supports the following hypervisors:
    KVM (QEMU 2.0 or later)
    Xen (4.5 or later)
    VirtualBox (Mac OS X)

After creating a spec for your root filesystem, you can execute a container
in your shell by running:

    # cd /mycontainer
    # runv run [ -b bundle ] <container-id>

If not specified, the default value for the 'bundle' is the current directory.
'Bundle' is the directory where '` + specConfig + `' must be located.`
)

func main() {
	if reexec.Init() {
		return
	}

	app := cli.NewApp()
	app.Name = "runv"
	app.Usage = usage

	var v []string
	if version != "" {
		v = append(v, version)
	}
	if gitCommit != "" {
		v = append(v, fmt.Sprintf("commit: %s", gitCommit))
	}
	v = append(v, fmt.Sprintf("spec: %s", specs.Version))
	app.Version = strings.Join(v, "\n")

	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug",
			Usage: "enable debug output for logging, saved on the dir specified by log_dir via glog style",
		},
		cli.StringFlag{
			Name:  "log_dir",
			Value: "/var/log/hyper",
			Usage: "the directory for the logging (glog style)",
		},
		cli.StringFlag{
			Name:  "log",
			Value: "/dev/null",
			Usage: "[ignored on runv] set the log file path where internal debug information is written",
		},
		cli.StringFlag{
			Name:  "log-format",
			Usage: "[ignored on runv] set the format used by logs ('text' (default), or 'json')",
		},
		cli.StringFlag{
			Name:  "root",
			Value: "/run/runv",
			Usage: "root directory for storage of container state (this should be located in tmpfs)",
		},
		cli.StringFlag{
			Name:  "driver",
			Usage: "hypervisor driver (supports: kvm xen)",
		},
		cli.IntFlag{
			Name:  "default_cpus",
			Usage: "default number of vcpus to assign pod",
			Value: 1,
		},
		cli.IntFlag{
			Name:  "default_memory",
			Usage: "default memory to assign pod (mb)",
			Value: 128,
		},
		cli.StringFlag{
			Name:  "kernel",
			Usage: "kernel for the container",
		},
		cli.StringFlag{
			Name:  "initrd",
			Usage: "runv-compatible initrd for the container",
		},
		cli.StringFlag{
			Name:  "bios",
			Usage: "bios for the container",
		},
		cli.StringFlag{
			Name:  "cbfs",
			Usage: "cbfs for the container",
		},
		cli.StringFlag{
			Name:  "template",
			Usage: "path to the template vm state directory",
		},
	}
	app.After = func(context *cli.Context) error {
		// make sure glog flush all the messages to file
		glog.Flush()
		return nil
	}

	app.Commands = []cli.Command{
		createCommand,
		execCommand,
		interfaceCommand,
		killCommand,
		listCommand,
		psCommand,
		runCommand,
		specCommand,
		startCommand,
		stateCommand,
		manageCommand,
		pauseCommand,
		resumeCommand,
		deleteCommand,
		proxyCommand,
		shimCommand,
		nsListenCommand,
		watcherCommand,
	}
	if err := app.Run(os.Args); err != nil {
		glog.Errorf("app.Run(os.Args) failed with err: %#v", err)
		fmt.Fprintf(os.Stderr, "%v\n", err)
		cli.HandleExitCoder(err)
		// non-standard errors
		os.Exit(22)
	}
}

// runvOptions is used for create aux runv processes (networklistener/shim/proxy)
type runvOptions struct {
	*cli.Context
	withContainer *State
	attach        bool
}

func cmdPrepare(context *cli.Context, setupHypervisor, canLogToStderr bool) error {
	if setupHypervisor {
		var err error
		if hypervisor.HDriver, err = driverloader.Probe(context.GlobalString("driver")); err != nil {
			return err
		}
		setupHyperstartFunc(context)
	}

	logdir := context.GlobalString("log_dir")
	if logdir != "" {
		if err := os.MkdirAll(logdir, 0750); err != nil {
			return fmt.Errorf("can't create dir %q for log files", logdir)
		}
	}
	if !context.GlobalBool("debug") {
		flag.CommandLine.Parse([]string{"-v", "1", "--log_dir", logdir})
	} else if canLogToStderr {
		flag.CommandLine.Parse([]string{"-v", "3", "--log_dir", logdir, "--alsologtostderr"})
	} else {
		flag.CommandLine.Parse([]string{"-v", "3", "--log_dir", logdir})
	}
	return nil
}
<|endoftext|>