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

package ssh

import (
	"io"
	"sync"
)

// ErrTimeout is a value that satisfies net.Error
var ErrTimeout = errTimeout{}

type errTimeout struct{}

func (e errTimeout) Error() string {
	return "timeout"
}
func (e errTimeout) Timeout() bool {
	// Is the error a timeout?
	return true
}
func (e errTimeout) Temporary() bool {
	// Is the error temporary?
	return true
}

// buffer provides a linked list buffer for data exchange
// between producer and consumer. Theoretically the buffer is
// of unlimited capacity as it does no allocation of its own.
type buffer struct {
	// protects concurrent access to head, tail and closed
	*sync.Cond

	head *element // the buffer that will be read first
	tail *element // the buffer that will be read last

	closed   bool
	timedOut bool
	idle     *idleTimer
}

// An element represents a single link in a linked list.
type element struct {
	buf  []byte
	next *element
}

// newBuffer returns an empty buffer that is not closed.
func newBuffer(idle *idleTimer) *buffer {
	e := new(element)
	b := &buffer{
		Cond: newCond(),
		head: e,
		tail: e,
		idle: idle,
	}
	return b
}

// write makes buf available for Read to receive.
// buf must not be modified after the call to write.
func (b *buffer) write(buf []byte) {
	b.Cond.L.Lock()
	e := &element{buf: buf}
	b.tail.next = e
	b.tail = e
	b.Cond.Signal()
	b.Cond.L.Unlock()
}

// eof closes the buffer. Reads from the buffer once all
// the data has been consumed will receive os.EOF.
func (b *buffer) eof() error {
	b.Cond.L.Lock()
	b.closed = true
	b.Cond.Signal()
	b.Cond.L.Unlock()
	return nil
}

// timeout does not close the buffer. Reads from the buffer once all
// the data has been consumed will receive ErrTimeout.
// b.idle.TimeOut() must return true when queried for
// this to be succesful.
func (b *buffer) timeout() error {
	b.Cond.L.Lock()
	b.timedOut = true
	b.Cond.Signal()
	b.Cond.L.Unlock()
	return nil
}

// Read reads data from the internal buffer in buf.  Reads will block
// if no data is available, or until the buffer is closed.
func (b *buffer) Read(buf []byte) (n int, err error) {
	b.Cond.L.Lock()
	defer b.Cond.L.Unlock()

	for len(buf) > 0 {
		// if there is data in b.head, copy it
		if len(b.head.buf) > 0 {
			r := copy(buf, b.head.buf)
			buf, b.head.buf = buf[r:], b.head.buf[r:]
			n += r
			continue
		}
		// if there is a next buffer, make it the head
		if len(b.head.buf) == 0 && b.head != b.tail {
			b.head = b.head.next
			continue
		}

		// if at least one byte has been copied, return
		if n > 0 {
			break
		}

		// if nothing was read, and there is nothing outstanding
		// check to see if the buffer is closed.
		if b.closed {
			err = io.EOF
			break
		}
		timedOut := false
		select {
		case timedOut = <-b.idle.TimedOut:
		case <-b.idle.halt.ReqStop.Chan:
		}
		if timedOut {
			err = ErrTimeout
			break
		}
		// out of buffers, wait for producer
		b.Cond.Wait()
	}
	return
}
<commit_msg>atg. slimmed down buffer.go, removing timedOut member<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ssh

import (
	"io"
	"sync"
)

// ErrTimeout is a value that satisfies net.Error
var ErrTimeout = errTimeout{}

type errTimeout struct{}

func (e errTimeout) Error() string {
	return "timeout"
}
func (e errTimeout) Timeout() bool {
	// Is the error a timeout?
	return true
}
func (e errTimeout) Temporary() bool {
	// Is the error temporary?
	return true
}

// buffer provides a linked list buffer for data exchange
// between producer and consumer. Theoretically the buffer is
// of unlimited capacity as it does no allocation of its own.
type buffer struct {
	// protects concurrent access to head, tail and closed
	*sync.Cond

	head *element // the buffer that will be read first
	tail *element // the buffer that will be read last

	closed bool
	idle   *idleTimer
}

// An element represents a single link in a linked list.
type element struct {
	buf  []byte
	next *element
}

// newBuffer returns an empty buffer that is not closed.
func newBuffer(idle *idleTimer) *buffer {
	e := new(element)
	b := &buffer{
		Cond: newCond(),
		head: e,
		tail: e,
		idle: idle,
	}
	return b
}

// write makes buf available for Read to receive.
// buf must not be modified after the call to write.
func (b *buffer) write(buf []byte) {
	b.Cond.L.Lock()
	e := &element{buf: buf}
	b.tail.next = e
	b.tail = e
	b.Cond.Signal()
	b.Cond.L.Unlock()
}

// eof closes the buffer. Reads from the buffer once all
// the data has been consumed will receive os.EOF.
func (b *buffer) eof() error {
	b.Cond.L.Lock()
	b.closed = true
	b.Cond.Signal()
	b.Cond.L.Unlock()
	return nil
}

// timeout does not close the buffer. Reads from the buffer once all
// the data has been consumed will receive ErrTimeout.
// b.idle.TimeOut() must return true when queried for
// this to be succesful.
func (b *buffer) timeout() error {
	b.Cond.Signal()
	return nil
}

// Read reads data from the internal buffer in buf.  Reads will block
// if no data is available, or until the buffer is closed.
func (b *buffer) Read(buf []byte) (n int, err error) {
	b.Cond.L.Lock()
	defer b.Cond.L.Unlock()

	for len(buf) > 0 {
		// if there is data in b.head, copy it
		if len(b.head.buf) > 0 {
			r := copy(buf, b.head.buf)
			buf, b.head.buf = buf[r:], b.head.buf[r:]
			n += r
			continue
		}
		// if there is a next buffer, make it the head
		if len(b.head.buf) == 0 && b.head != b.tail {
			b.head = b.head.next
			continue
		}

		// if at least one byte has been copied, return
		if n > 0 {
			break
		}

		// if nothing was read, and there is nothing outstanding
		// check to see if the buffer is closed.
		if b.closed {
			err = io.EOF
			break
		}
		timedOut := false
		select {
		case timedOut = <-b.idle.TimedOut:
		case <-b.idle.halt.ReqStop.Chan:
		}
		if timedOut {
			err = ErrTimeout
			break
		}
		// out of buffers, wait for producer
		b.Cond.Wait()
	}
	return
}
<|endoftext|>


<commit_before>package ssh

import (
	"context"
	"fmt"
	"sync"
)

// IdemCloseChan can have Close() called on it
// multiple times, and it will only close
// Chan once.
type IdemCloseChan struct {
	Chan   chan struct{}
	closed bool
	mut    sync.Mutex
}

// Reinit re-allocates the Chan, assinging
// a new channel and reseting the state
// as if brand new.
func (c *IdemCloseChan) Reinit() {
	c.mut.Lock()
	defer c.mut.Unlock()
	c.Chan = make(chan struct{})
	c.closed = false
}

// NewIdemCloseChan makes a new IdemCloseChan.
func NewIdemCloseChan() *IdemCloseChan {
	return &IdemCloseChan{
		Chan: make(chan struct{}),
	}
}

var ErrAlreadyClosed = fmt.Errorf("Chan already closed")

// Close returns ErrAlreadyClosed if it has been
// called before. It never closes IdemClose.Chan more
// than once, so it is safe to ignore the returned
// error value. Close() is safe for concurrent access by multiple
// goroutines. Close returns nil after the first time
// it is called.
func (c *IdemCloseChan) Close() error {
	c.mut.Lock()
	defer c.mut.Unlock()
	if !c.closed {
		close(c.Chan)
		c.closed = true
		return nil
	}
	return ErrAlreadyClosed
}

// IsClosed tells you if Chan is already closed or not.
func (c *IdemCloseChan) IsClosed() bool {
	c.mut.Lock()
	defer c.mut.Unlock()
	return c.closed
}

// Halter helps shutdown a goroutine, and manage
// overall lifecycle of a resource.
type Halter struct {

	// Ready is closed when
	// the resouce embedding the Halter is ready.
	Ready IdemCloseChan

	// The owning goutine should call Done.Close() as its last
	// actual once it has received the ReqStop() signal.
	Done IdemCloseChan

	// Other goroutines call ReqStop.Close() in order
	// to request that the owning goroutine stop immediately.
	// The owning goroutine should select on ReqStop.Chan
	// in order to recognize shutdown requests.
	ReqStop IdemCloseChan

	// Err represents the "return value" of the
	// function launched in the goroutine.
	// To avoid races, it should be read only
	// after Done has been closed. Goroutine
	// functions should set Err (if non nil)
	// prior to calling Done.Close().
	Err error
}

func NewHalter() *Halter {
	return &Halter{
		Ready:   *NewIdemCloseChan(),
		Done:    *NewIdemCloseChan(),
		ReqStop: *NewIdemCloseChan(),
	}
}

// RequestStop closes the h.ReqStop channel
// if it has not already done so. Safe for
// multiple goroutine access.
func (h *Halter) RequestStop() {
	h.ReqStop.Close()
}

// MarkReady closes the h.Ready channel
// if it has not already done so. Safe for
// multiple goroutine access.
func (h *Halter) MarkReady() {
	h.Done.Close()
}

// MarkDone closes the h.Done channel
// if it has not already done so. Safe for
// multiple goroutine access.
func (h *Halter) MarkDone() {
	h.Done.Close()
}

// IsStopRequested returns true iff h.ReqStop has been Closed().
func (h *Halter) IsStopRequested() bool {
	return h.ReqStop.IsClosed()
}

// IsDone returns true iff h.Done has been Closed().
func (h *Halter) IsDone() bool {
	return h.Done.IsClosed()
}

// MAD provides a link between context.Context
//   and Halter.
// MAD stands for mutual assured destruction.
// When ctx is cancelled, then halt will be too.
// When halt is done, then cancelctx will be called.
func MAD(ctx context.Context, cancelctx context.CancelFunc, halt *Halter) {
	go func() {
		cchan := ctx.Done()
		hchan1 := halt.ReqStop.Chan
		hchan2 := halt.Done.Chan
		cDone := false
		hDone := false
		for {
			select {
			case <-cchan:
				halt.ReqStop.Close()
				halt.Done.Close()
				cDone = true
				cchan = nil
			case <-hchan1:
				hDone = true
				cancelctx()
				hchan1 = nil
				hchan2 = nil
			case <-hchan2:
				hDone = true
				cancelctx()
				hchan1 = nil
				hchan2 = nil
			}
			if cDone && hDone {
				return
			}
		}
	}()
}
<commit_msg>atg. Halter has RunStatus() and DoneCh() methods<commit_after>package ssh

import (
	"context"
	"fmt"
	"sync"
)

// IdemCloseChan can have Close() called on it
// multiple times, and it will only close
// Chan once.
type IdemCloseChan struct {
	Chan   chan struct{}
	closed bool
	mut    sync.Mutex
}

// Reinit re-allocates the Chan, assinging
// a new channel and reseting the state
// as if brand new.
func (c *IdemCloseChan) Reinit() {
	c.mut.Lock()
	defer c.mut.Unlock()
	c.Chan = make(chan struct{})
	c.closed = false
}

// NewIdemCloseChan makes a new IdemCloseChan.
func NewIdemCloseChan() *IdemCloseChan {
	return &IdemCloseChan{
		Chan: make(chan struct{}),
	}
}

var ErrAlreadyClosed = fmt.Errorf("Chan already closed")

// Close returns ErrAlreadyClosed if it has been
// called before. It never closes IdemClose.Chan more
// than once, so it is safe to ignore the returned
// error value. Close() is safe for concurrent access by multiple
// goroutines. Close returns nil after the first time
// it is called.
func (c *IdemCloseChan) Close() error {
	c.mut.Lock()
	defer c.mut.Unlock()
	if !c.closed {
		close(c.Chan)
		c.closed = true
		return nil
	}
	return ErrAlreadyClosed
}

// IsClosed tells you if Chan is already closed or not.
func (c *IdemCloseChan) IsClosed() bool {
	c.mut.Lock()
	defer c.mut.Unlock()
	return c.closed
}

// Halter helps shutdown a goroutine, and manage
// overall lifecycle of a resource.
type Halter struct {

	// Ready is closed when
	// the resouce embedding the Halter is ready.
	Ready IdemCloseChan

	// The owning goutine should call Done.Close() as its last
	// actual once it has received the ReqStop() signal.
	Done IdemCloseChan

	// Other goroutines call ReqStop.Close() in order
	// to request that the owning goroutine stop immediately.
	// The owning goroutine should select on ReqStop.Chan
	// in order to recognize shutdown requests.
	ReqStop IdemCloseChan

	// Err represents the "return value" of the
	// function launched in the goroutine.
	// To avoid races, it should be read only
	// after Done has been closed. Goroutine
	// functions should set Err (if non nil)
	// prior to calling Done.Close().
	Err error
}

func NewHalter() *Halter {
	return &Halter{
		Ready:   *NewIdemCloseChan(),
		Done:    *NewIdemCloseChan(),
		ReqStop: *NewIdemCloseChan(),
	}
}

// RequestStop closes the h.ReqStop channel
// if it has not already done so. Safe for
// multiple goroutine access.
func (h *Halter) RequestStop() {
	h.ReqStop.Close()
}

// MarkReady closes the h.Ready channel
// if it has not already done so. Safe for
// multiple goroutine access.
func (h *Halter) MarkReady() {
	h.Done.Close()
}

// MarkDone closes the h.Done channel
// if it has not already done so. Safe for
// multiple goroutine access.
func (h *Halter) MarkDone() {
	h.Done.Close()
}

// IsStopRequested returns true iff h.ReqStop has been Closed().
func (h *Halter) IsStopRequested() bool {
	return h.ReqStop.IsClosed()
}

// IsDone returns true iff h.Done has been Closed().
func (h *Halter) IsDone() bool {
	return h.Done.IsClosed()
}

// MAD provides a link between context.Context
//   and Halter.
// MAD stands for mutual assured destruction.
// When ctx is cancelled, then halt will be too.
// When halt is done, then cancelctx will be called.
func MAD(ctx context.Context, cancelctx context.CancelFunc, halt *Halter) {
	go func() {
		cchan := ctx.Done()
		hchan1 := halt.ReqStop.Chan
		hchan2 := halt.Done.Chan
		cDone := false
		hDone := false
		for {
			select {
			case <-cchan:
				halt.ReqStop.Close()
				halt.Done.Close()
				cDone = true
				cchan = nil
			case <-hchan1:
				hDone = true
				cancelctx()
				hchan1 = nil
				hchan2 = nil
			case <-hchan2:
				hDone = true
				cancelctx()
				hchan1 = nil
				hchan2 = nil
			}
			if cDone && hDone {
				return
			}
		}
	}()
}

// RunStatus returns a nil err unless done is true.
func (h *Halter) RunStatus() (ready, reqStop, done bool, err error) {
	ready = h.Ready.IsClosed()
	reqStop = h.ReqStop.IsClosed()
	done = h.Done.IsClosed()
	if done {
		err = h.Err
	}
	return
}

// DoneCh is a lazy way of getting h.Done.Chan, but
// may satisfy an interface.
func (h *Halter) DoneCh() <-chan struct{} {
	return h.Done.Chan
}
<|endoftext|>


<commit_before>package commands

import (
	"crypto/sha256"
	"fmt"
	consulapi "github.com/hashicorp/consul/api"
	"github.com/spf13/cobra"
	"log"
	"os"
	"strconv"
	"strings"
)

var outCmd = &cobra.Command{
	Use:   "out",
	Short: "Write a file based on key data.",
	Long:  `out is for writing a file based on a Consul key.`,
	Run:   outRun,
}

func outRun(cmd *cobra.Command, args []string) {
	checkFlags()

	key_data := KeyDataPath(KeyLocation)
	key_checksum := KeyChecksumPath(KeyLocation)

	// Get the KV data out of Consul.
	KVData := get(key_data)

	// Get the Checksum data out of Consul.
	Checksum := get(key_checksum)

	// Is the data long enough?
	longEnough := lengthCheck(KVData)
	log.Print("out: longEnough='", strconv.FormatBool(longEnough), "'")

	// Does the checksum match?
	checksumMatch := checksumCheck(KVData, Checksum)
	log.Print("out: checksumMatch='", strconv.FormatBool(checksumMatch), "'")

	// If the data is long enough and the checksum matches, write the file.
	if longEnough && checksumMatch {
		writeFile(KVData)
	} else {
		log.Print("Could not write file.")
	}
}

func writeFile(data string) bool {
	return true
}

func lengthCheck(data string) bool {
	var length int
	if strings.ContainsAny(data, "\n") {
		length = strings.Count(data, "\n")
	} else {
		length = 1
	}
	log.Print("out: length='", length, "' min_length='", MinFileLength, "'")
	if length >= MinFileLength {
		return true
	} else {
		return false
	}
}

func computeChecksum(data string) string {
	data_bytes := []byte(data)
	computed_checksum := sha256.Sum256(data_bytes)
	final_checksum := fmt.Sprintf("%x\n", computed_checksum)
	log.Print("out: computed_checksum='", final_checksum, "'")
	return final_checksum
}

func checksumCheck(data string, checksum string) bool {
	computed_checksum := computeChecksum(data)
	log.Print("out: checksum='", checksum, "' computed_checksum='", computed_checksum, "'")
	if computed_checksum == checksum {
		return true
	} else {
		return false
	}
}

func KeyDataPath(key string) string {
	full_path := fmt.Sprint(PrefixLocation, "/", key, "/data")
	log.Print("out: path='data' full_path='", full_path, "'")
	return full_path
}

func KeyChecksumPath(key string) string {
	full_path := fmt.Sprint(PrefixLocation, "/", key, "/checksum")
	log.Print("out: path='checksum' full_path='", full_path, "'")
	return full_path
}

func get(key string) string {
	var value string
	config := consulapi.DefaultConfig()
	config.Address = ConsulServer
	consul, err := consulapi.NewClient(config)
	kv := consul.KV()
	pair, _, err := kv.Get(key, nil)
	if err != nil {
		panic(err)
	} else {
		value = string(pair.Value[:])
		log.Print("out: key='", key, "' value='", value, "'")
	}
	return value
}

func checkFlags() {
	log.Print("out: Checking cli flags.")
	if KeyLocation == "" {
		fmt.Println("Need a key location in -k")
		os.Exit(1)
	}
	if FiletoWrite == "" {
		fmt.Println("Need a file to write in -f")
		os.Exit(1)
	}
	log.Print("out: Required cli flags present.")
}

var KeyLocation string
var FiletoWrite string
var PrefixLocation string
var ConsulServer string
var MinFileLength int

func init() {
	RootCmd.AddCommand(outCmd)
	outCmd.Flags().StringVarP(&PrefixLocation, "prefix", "p", "kvexpress", "prefix for the key")
	outCmd.Flags().StringVarP(&KeyLocation, "key", "k", "", "key to pull data from")
	outCmd.Flags().StringVarP(&FiletoWrite, "file", "f", "", "where to write the data")
	outCmd.Flags().StringVarP(&ConsulServer, "server", "s", "localhost:8500", "Consul server location")
	outCmd.Flags().IntVarP(&MinFileLength, "length", "l", 10, "minimum amount of lines in the file")
}
<commit_msg>Trim any new lines that would cause checksums not to match.<commit_after>package commands

import (
	"crypto/sha256"
	"fmt"
	consulapi "github.com/hashicorp/consul/api"
	"github.com/spf13/cobra"
	"log"
	"os"
	"strconv"
	"strings"
)

var outCmd = &cobra.Command{
	Use:   "out",
	Short: "Write a file based on key data.",
	Long:  `out is for writing a file based on a Consul key.`,
	Run:   outRun,
}

func outRun(cmd *cobra.Command, args []string) {
	checkFlags()

	key_data := KeyDataPath(KeyLocation)
	key_checksum := KeyChecksumPath(KeyLocation)

	// Get the KV data out of Consul.
	KVData := get(key_data)

	// Get the Checksum data out of Consul.
	Checksum := get(key_checksum)

	// Is the data long enough?
	longEnough := lengthCheck(KVData)
	log.Print("out: longEnough='", strconv.FormatBool(longEnough), "'")

	// Does the checksum match?
	checksumMatch := checksumCheck(KVData, Checksum)
	log.Print("out: checksumMatch='", strconv.FormatBool(checksumMatch), "'")

	// If the data is long enough and the checksum matches, write the file.
	if longEnough && checksumMatch {
		writeFile(KVData)
	} else {
		log.Print("Could not write file.")
	}
}

func writeFile(data string) bool {
	return true
}

func lengthCheck(data string) bool {
	var length int
	if strings.ContainsAny(data, "\n") {
		length = strings.Count(data, "\n")
	} else {
		length = 1
	}
	log.Print("out: length='", length, "' min_length='", MinFileLength, "'")
	if length >= MinFileLength {
		return true
	} else {
		return false
	}
}

func computeChecksum(data string) string {
	data_bytes := []byte(data)
	computed_checksum := sha256.Sum256(data_bytes)
	final_checksum := fmt.Sprintf("%x\n", computed_checksum)
	log.Print("out: computed_checksum='", final_checksum, "'")
	return final_checksum
}

func checksumCheck(data string, checksum string) bool {
	computed_checksum := computeChecksum(data)
	log.Print("out: checksum='", checksum, "' computed_checksum='", computed_checksum, "'")
	if strings.TrimSpace(computed_checksum) == strings.TrimSpace(checksum) {
		return true
	} else {
		return false
	}
}

func KeyDataPath(key string) string {
	full_path := fmt.Sprint(PrefixLocation, "/", key, "/data")
	log.Print("out: path='data' full_path='", full_path, "'")
	return full_path
}

func KeyChecksumPath(key string) string {
	full_path := fmt.Sprint(PrefixLocation, "/", key, "/checksum")
	log.Print("out: path='checksum' full_path='", full_path, "'")
	return full_path
}

func get(key string) string {
	var value string
	config := consulapi.DefaultConfig()
	config.Address = ConsulServer
	consul, err := consulapi.NewClient(config)
	kv := consul.KV()
	pair, _, err := kv.Get(key, nil)
	if err != nil {
		panic(err)
	} else {
		value = string(pair.Value[:])
		log.Print("out: key='", key, "' value='", value, "'")
	}
	return value
}

func checkFlags() {
	log.Print("out: Checking cli flags.")
	if KeyLocation == "" {
		fmt.Println("Need a key location in -k")
		os.Exit(1)
	}
	if FiletoWrite == "" {
		fmt.Println("Need a file to write in -f")
		os.Exit(1)
	}
	log.Print("out: Required cli flags present.")
}

var KeyLocation string
var FiletoWrite string
var PrefixLocation string
var ConsulServer string
var MinFileLength int

func init() {
	RootCmd.AddCommand(outCmd)
	outCmd.Flags().StringVarP(&PrefixLocation, "prefix", "p", "kvexpress", "prefix for the key")
	outCmd.Flags().StringVarP(&KeyLocation, "key", "k", "", "key to pull data from")
	outCmd.Flags().StringVarP(&FiletoWrite, "file", "f", "", "where to write the data")
	outCmd.Flags().StringVarP(&ConsulServer, "server", "s", "localhost:8500", "Consul server location")
	outCmd.Flags().IntVarP(&MinFileLength, "length", "l", 10, "minimum amount of lines in the file")
}
<|endoftext|>


<commit_before>// Copyright 2012 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"
	"testing"
)

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

type PointeeTest struct {}
func init()                     { RegisterTestSuite(&PointeeTest{}) }

func TestPointee(t *testing.T) { RunTests(t) }

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

func (t *PointeeTest) Description() {
	wrapped := &fakeMatcher{nil, "taco"}
	matcher := Pointee(wrapped)

	ExpectEq("pointee(taco)", matcher.Description())
}

func (t *PointeeTest) CandidateIsNotAPointer() {
	matcher := Pointee(HasSubstr(""))
	err := matcher.Matches([]byte{})

	ExpectThat(err, Error(Equals("which is not a pointer")))
	ExpectTrue(isFatal(err))
}

func (t *PointeeTest) CandidateIsANilPointer() {
	ExpectEq("TODO", "")
}

func (t *PointeeTest) CallsWrapped() {
	ExpectEq("TODO", "")
}

func (t *PointeeTest) WrappedReturnsTrue() {
	ExpectEq("TODO", "")
}

func (t *PointeeTest) WrappedReturnsNonFatalError() {
	ExpectEq("TODO", "")
}

func (t *PointeeTest) WrappedReturnsFatalError() {
	ExpectEq("TODO", "")
}
<commit_msg>PointeeTest.CandidateIsANilPointer<commit_after>// Copyright 2012 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"
	"testing"
)

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

type PointeeTest struct {}
func init()                     { RegisterTestSuite(&PointeeTest{}) }

func TestPointee(t *testing.T) { RunTests(t) }

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

func (t *PointeeTest) Description() {
	wrapped := &fakeMatcher{nil, "taco"}
	matcher := Pointee(wrapped)

	ExpectEq("pointee(taco)", matcher.Description())
}

func (t *PointeeTest) CandidateIsNotAPointer() {
	matcher := Pointee(HasSubstr(""))
	err := matcher.Matches([]byte{})

	ExpectThat(err, Error(Equals("which is not a pointer")))
	ExpectTrue(isFatal(err))
}

func (t *PointeeTest) CandidateIsANilLiteral() {
	matcher := Pointee(HasSubstr(""))
	err := matcher.Matches(nil)

	ExpectThat(err, Error(Equals("which is not a pointer")))
	ExpectTrue(isFatal(err))
}

func (t *PointeeTest) CandidateIsANilPointer() {
	matcher := Pointee(HasSubstr(""))
	err := matcher.Matches((*int)(nil))

	ExpectThat(err, Error(Equals("")))
	ExpectTrue(isFatal(err))
}

func (t *PointeeTest) CallsWrapped() {
	ExpectEq("TODO", "")
}

func (t *PointeeTest) WrappedReturnsTrue() {
	ExpectEq("TODO", "")
}

func (t *PointeeTest) WrappedReturnsNonFatalError() {
	ExpectEq("TODO", "")
}

func (t *PointeeTest) WrappedReturnsFatalError() {
	ExpectEq("TODO", "")
}
<|endoftext|>


<commit_before>package jsonpointer

import (
	"compress/gzip"
	"io/ioutil"
	"os"
	"reflect"
	"testing"

	"github.com/dustin/gojson"
)

var ptests = []struct {
	path string
	exp  interface{}
}{
	{"/foo", []interface{}{"bar", "baz"}},
	{"/foo/0", "bar"},
	{"/", 0.0},
	{"/a~1b", 1.0},
	{"/c%d", 2.0},
	{"/e^f", 3.0},
	{"/g|h", 4.0},
	{"/i\\j", 5.0},
	{"/k\"l", 6.0},
	{"/ ", 7.0},
	{"/m~0n", 8.0},
	{"/g~1n~1r", "has slash, will travel"},
	{"/g/n/r", "where's tito?"},
}

func TestPointerRoot(t *testing.T) {
	got, err := Find([]byte(objSrc), "")
	if err != nil {
		t.Fatalf("Error finding root: %v", err)
	}
	if !reflect.DeepEqual([]byte(objSrc), got) {
		t.Fatalf("Error finding root, found\n%s\n, wanted\n%s",
			got, objSrc)
	}
}

func TestPointerMissing(t *testing.T) {
	got, err := Find([]byte(objSrc), "/missing")
	if err != nil {
		t.Fatalf("Error finding missing item: %v", err)
	}
	if got != nil {
		t.Fatalf("Expected nil looking for /missing, got %v",
			got)
	}
}

func TestManyPointers(t *testing.T) {
	pointers := []string{}
	exp := map[string]interface{}{}
	for _, test := range ptests {
		pointers = append(pointers, test.path)
		exp[test.path] = test.exp
	}

	rv, err := FindMany([]byte(objSrc), pointers)
	if err != nil {
		t.Fatalf("Error finding many: %v", err)
	}

	got := map[string]interface{}{}
	for k, v := range rv {
		var val interface{}
		err = json.Unmarshal(v, &val)
		if err != nil {
			t.Fatalf("Error unmarshaling %s: %v", v, err)
		}
		got[k] = val
	}

	if !reflect.DeepEqual(got, exp) {
		for k, v := range exp {
			if !reflect.DeepEqual(got[k], v) {
				t.Errorf("At %v, expected %#v, got %#v", k, v, got[k])
			}
		}
		t.Fail()
	}
}

func TestManyPointersMissing(t *testing.T) {
	got, err := FindMany([]byte(objSrc), []string{"/missing"})
	if err != nil {
		t.Fatalf("Error finding missing item: %v", err)
	}
	if len(got) != 0 {
		t.Fatalf("Expected empty looking for many /missing, got %v",
			got)
	}

}

func TestPointer(t *testing.T) {

	for _, test := range ptests {
		got, err := Find([]byte(objSrc), test.path)
		var val interface{}
		if err == nil {
			err = json.Unmarshal([]byte(got), &val)
		}
		if err != nil {
			t.Errorf("Got an error on key %v: %v", test.path, err)
			t.Fail()
		} else if !reflect.DeepEqual(val, test.exp) {
			t.Errorf("On %#v, expected %+v (%T), got %+v (%T)",
				test.path, test.exp, test.exp, val, val)
			t.Fail()
		} else {
			t.Logf("Success - got %s for %#v", got, test.path)
		}
	}
}

func TestPointerCoder(t *testing.T) {
	tests := map[string][]string{
		"/":        []string{""},
		"/a":       []string{"a"},
		"/a~1b":    []string{"a/b"},
		"/m~0n":    []string{"m~n"},
		"/ ":       []string{" "},
		"/g~1n~1r": []string{"g/n/r"},
		"/g/n/r":   []string{"g", "n", "r"},
	}

	for k, v := range tests {
		parsed := parsePointer(k)
		encoded := encodePointer(v)

		if k != encoded {
			t.Errorf("Expected to encode %#v as %#v, got %#v",
				v, k, encoded)
			t.Fail()
		}
		if !arreq(v, parsed) {
			t.Errorf("Expected to decode %#v as %#v, got %#v",
				k, v, parsed)
			t.Fail()
		}
	}
}

func BenchmarkEncodePointer(b *testing.B) {
	aPath := []string{"a", "ab", "a~0b", "a~1b", "a~0~1~0~1b"}
	for i := 0; i < b.N; i++ {
		encodePointer(aPath)
	}
}

func BenchmarkPointer(b *testing.B) {
	obj := []byte(objSrc)
	for i := 0; i < b.N; i++ {
		for _, test := range tests {
			Find(obj, test.path)
		}
	}
}

func BenchmarkManyPointer(b *testing.B) {
	pointers := []string{}
	for _, test := range ptests {
		pointers = append(pointers, test.path)
	}
	obj := []byte(objSrc)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		FindMany(obj, pointers)
	}
}

var codeJSON []byte

func init() {
	f, err := os.Open("testdata/code.json.gz")
	if err != nil {
		panic(err)
	}
	defer f.Close()
	gz, err := gzip.NewReader(f)
	if err != nil {
		panic(err)
	}
	data, err := ioutil.ReadAll(gz)
	if err != nil {
		panic(err)
	}

	codeJSON = data
}

func BenchmarkPointerLarge(b *testing.B) {
	keys := []string{
		"/tree/kids/0/kids/0/name",
		"/tree/kids/0/name",
		"/tree/kids/0/kids/0/kids/0/kids/0/kids/0/name",
	}
	b.SetBytes(int64(len(codeJSON)))

	for i := 0; i < b.N; i++ {
		found, err := FindMany(codeJSON, keys)
		if err != nil || len(found) != 3 {
			b.Fatalf("Didn't find all the things from %v/%v",
				found, err)
		}
	}
}

func BenchmarkPointerLargeShallow(b *testing.B) {
	keys := []string{
		"/tree/kids/0/kids/0/kids/0/kids/0/kids/0/name",
	}
	b.SetBytes(int64(len(codeJSON)))

	for i := 0; i < b.N; i++ {
		found, err := FindMany(codeJSON, keys)
		if err != nil || len(found) != 1 {
			b.Fatalf("Didn't find all the things: %v/%v",
				found, err)
		}
	}
}

func BenchmarkPointerLargeMissing(b *testing.B) {
	keys := []string{
		"/this/does/not/exist",
	}
	b.SetBytes(int64(len(codeJSON)))

	for i := 0; i < b.N; i++ {
		found, err := FindMany(codeJSON, keys)
		if err != nil || len(found) != 0 {
			b.Fatalf("Didn't find all the things: %v/%v",
				found, err)
		}
	}
}

func BenchmarkPointerSlow(b *testing.B) {
	keys := []string{
		"/tree/kids/0/kids/0/kids/0/kids/0/kids/0/name",
	}
	b.SetBytes(int64(len(codeJSON)))

	for i := 0; i < b.N; i++ {
		m := map[string]interface{}{}
		err := json.Unmarshal(codeJSON, &m)
		if err != nil {
			b.Fatalf("Error parsing JSON: %v", err)
		}
		Get(m, keys[0])
	}
}
<commit_msg>Test tweaks and renames.<commit_after>package jsonpointer

import (
	"compress/gzip"
	"io/ioutil"
	"os"
	"reflect"
	"testing"

	"github.com/dustin/gojson"
)

var ptests = []struct {
	path string
	exp  interface{}
}{
	{"/foo", []interface{}{"bar", "baz"}},
	{"/foo/0", "bar"},
	{"/", 0.0},
	{"/a~1b", 1.0},
	{"/c%d", 2.0},
	{"/e^f", 3.0},
	{"/g|h", 4.0},
	{"/i\\j", 5.0},
	{"/k\"l", 6.0},
	{"/ ", 7.0},
	{"/m~0n", 8.0},
	{"/g~1n~1r", "has slash, will travel"},
	{"/g/n/r", "where's tito?"},
}

func TestPointerRoot(t *testing.T) {
	got, err := Find([]byte(objSrc), "")
	if err != nil {
		t.Fatalf("Error finding root: %v", err)
	}
	if !reflect.DeepEqual([]byte(objSrc), got) {
		t.Fatalf("Error finding root, found\n%s\n, wanted\n%s",
			got, objSrc)
	}
}

func TestPointerMissing(t *testing.T) {
	got, err := Find([]byte(objSrc), "/missing")
	if err != nil {
		t.Fatalf("Error finding missing item: %v", err)
	}
	if got != nil {
		t.Fatalf("Expected nil looking for /missing, got %v",
			got)
	}
}

func TestManyPointers(t *testing.T) {
	pointers := []string{}
	exp := map[string]interface{}{}
	for _, test := range ptests {
		pointers = append(pointers, test.path)
		exp[test.path] = test.exp
	}

	rv, err := FindMany([]byte(objSrc), pointers)
	if err != nil {
		t.Fatalf("Error finding many: %v", err)
	}

	got := map[string]interface{}{}
	for k, v := range rv {
		var val interface{}
		err = json.Unmarshal(v, &val)
		if err != nil {
			t.Fatalf("Error unmarshaling %s: %v", v, err)
		}
		got[k] = val
	}

	if !reflect.DeepEqual(got, exp) {
		for k, v := range exp {
			if !reflect.DeepEqual(got[k], v) {
				t.Errorf("At %v, expected %#v, got %#v", k, v, got[k])
			}
		}
		t.Fail()
	}
}

func TestManyPointersMissing(t *testing.T) {
	got, err := FindMany([]byte(objSrc), []string{"/missing"})
	if err != nil {
		t.Fatalf("Error finding missing item: %v", err)
	}
	if len(got) != 0 {
		t.Fatalf("Expected empty looking for many /missing, got %v",
			got)
	}

}

func TestPointer(t *testing.T) {

	for _, test := range ptests {
		got, err := Find([]byte(objSrc), test.path)
		var val interface{}
		if err == nil {
			err = json.Unmarshal([]byte(got), &val)
		}
		if err != nil {
			t.Errorf("Got an error on key %v: %v", test.path, err)
			t.Fail()
		} else if !reflect.DeepEqual(val, test.exp) {
			t.Errorf("On %#v, expected %+v (%T), got %+v (%T)",
				test.path, test.exp, test.exp, val, val)
			t.Fail()
		} else {
			t.Logf("Success - got %s for %#v", got, test.path)
		}
	}
}

func TestPointerCoder(t *testing.T) {
	tests := map[string][]string{
		"/":        []string{""},
		"/a":       []string{"a"},
		"/a~1b":    []string{"a/b"},
		"/m~0n":    []string{"m~n"},
		"/ ":       []string{" "},
		"/g~1n~1r": []string{"g/n/r"},
		"/g/n/r":   []string{"g", "n", "r"},
	}

	for k, v := range tests {
		parsed := parsePointer(k)
		encoded := encodePointer(v)

		if k != encoded {
			t.Errorf("Expected to encode %#v as %#v, got %#v",
				v, k, encoded)
			t.Fail()
		}
		if !arreq(v, parsed) {
			t.Errorf("Expected to decode %#v as %#v, got %#v",
				k, v, parsed)
			t.Fail()
		}
	}
}

func BenchmarkEncodePointer(b *testing.B) {
	aPath := []string{"a", "ab", "a~0b", "a~1b", "a~0~1~0~1b"}
	for i := 0; i < b.N; i++ {
		encodePointer(aPath)
	}
}

func BenchmarkAll(b *testing.B) {
	obj := []byte(objSrc)
	for i := 0; i < b.N; i++ {
		for _, test := range tests {
			Find(obj, test.path)
		}
	}
}

func BenchmarkManyPointer(b *testing.B) {
	pointers := []string{}
	for _, test := range ptests {
		pointers = append(pointers, test.path)
	}
	obj := []byte(objSrc)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		FindMany(obj, pointers)
	}
}

var codeJSON []byte

func init() {
	f, err := os.Open("testdata/code.json.gz")
	if err != nil {
		panic(err)
	}
	defer f.Close()
	gz, err := gzip.NewReader(f)
	if err != nil {
		panic(err)
	}
	data, err := ioutil.ReadAll(gz)
	if err != nil {
		panic(err)
	}

	codeJSON = data
}

func BenchmarkLarge3Key(b *testing.B) {
	keys := []string{
		"/tree/kids/0/kids/0/name",
		"/tree/kids/0/name",
		"/tree/kids/0/kids/0/kids/0/kids/0/kids/0/name",
	}
	b.SetBytes(int64(len(codeJSON)))

	for i := 0; i < b.N; i++ {
		found, err := FindMany(codeJSON, keys)
		if err != nil || len(found) != 3 {
			b.Fatalf("Didn't find all the things from %v/%v",
				found, err)
		}
	}
}

func BenchmarkLargeShallow(b *testing.B) {
	keys := []string{
		"/tree/kids/0/kids/0/kids/1/kids/1/kids/3/name",
	}
	b.SetBytes(int64(len(codeJSON)))

	for i := 0; i < b.N; i++ {
		found, err := FindMany(codeJSON, keys)
		if err != nil || len(found) != 1 {
			b.Fatalf("Didn't find all the things: %v/%v",
				found, err)
		}
	}
}

func BenchmarkLargeMissing(b *testing.B) {
	keys := []string{
		"/this/does/not/exist",
	}
	b.SetBytes(int64(len(codeJSON)))

	for i := 0; i < b.N; i++ {
		found, err := FindMany(codeJSON, keys)
		if err != nil || len(found) != 0 {
			b.Fatalf("Didn't find all the things: %v/%v",
				found, err)
		}
	}
}

func BenchmarkLargeIdentity(b *testing.B) {
	keys := []string{
		"",
	}
	b.SetBytes(int64(len(codeJSON)))

	for i := 0; i < b.N; i++ {
		found, err := FindMany(codeJSON, keys)
		if err != nil || len(found) != 1 {
			b.Fatalf("Didn't find all the things: %v/%v",
				found, err)
		}
	}
}

func BenchmarkLargeBest(b *testing.B) {
	keys := []string{
		"/tree/name",
	}
	b.SetBytes(int64(len(codeJSON)))

	for i := 0; i < b.N; i++ {
		found, err := FindMany(codeJSON, keys)
		if err != nil || len(found) != 1 {
			b.Fatalf("Didn't find all the things: %v/%v",
				found, err)
		}
	}
}

func BenchmarkLargeMap(b *testing.B) {
	keys := []string{
		"/tree/kids/0/kids/0/kids/0/kids/0/kids/0/name",
	}
	b.SetBytes(int64(len(codeJSON)))

	for i := 0; i < b.N; i++ {
		m := map[string]interface{}{}
		err := json.Unmarshal(codeJSON, &m)
		if err != nil {
			b.Fatalf("Error parsing JSON: %v", err)
		}
		Get(m, keys[0])
	}
}
<|endoftext|>


<commit_before>package cli

import (
	"fmt"
	"os"
	"path"
	"runtime/pprof"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/go-utils/freezable"
	"github.com/urfave/cli"
)

var (
	// MachineWorkdir ...
	MachineWorkdir = freezable.String{}
	// MachineParamsAdditionalEnvs ...
	MachineParamsAdditionalEnvs = freezable.StringSlice{}
	// MachineConfigTypeID ...
	MachineConfigTypeID = freezable.String{}
)

func before(c *cli.Context) error {
	// Log level
	if logLevel, err := log.ParseLevel(c.String(LogLevelKey)); err != nil {
		log.Fatal("Failed to parse log level:", err)
	} else {
		log.SetLevel(logLevel)
	}

	if len(c.Args()) != 0 && c.Args().First() != "version" && !c.Bool(HelpKey) && !c.Bool(VersionKey) {
		if err := MachineWorkdir.Set(c.String(WorkdirKey)); err != nil {
			log.Fatalf("Failed to set MachineWorkdir: %s", err)
		}
		if MachineWorkdir.String() == "" {
			log.Fatalln("No Workdir specified!")
		}
	}
	MachineWorkdir.Freeze()

	if err := MachineConfigTypeID.Set(c.String(ConfigTypeIDParamKey)); err != nil {
		log.Fatalf("Failed to set MachineConfigTypeID: %s", err)
	}
	log.Debugf("MachineConfigTypeID: %s", MachineConfigTypeID)

	if err := MachineParamsAdditionalEnvs.Set(c.StringSlice(EnvironmentParamKey)); err != nil {
		log.Fatalf("Failed to set MachineParamsAdditionalEnvs: %s", err)
	}
	log.Debugf("MachineParamsAdditionalEnvs: %s", MachineParamsAdditionalEnvs)
	MachineParamsAdditionalEnvs.Freeze()

	return nil
}

func printVersion(c *cli.Context) {
	fmt.Fprintf(c.App.Writer, "%v\n", c.App.Version)
}

// Run the CLI
func Run() {
	cli.VersionPrinter = printVersion

	app := cli.NewApp()
	app.Name = path.Base(os.Args[0])
	app.Usage = "bitrise-machine"
	app.Version = "0.9.11-pre15"

	app.Author = ""
	app.Email = ""

	app.Before = before

	app.Flags = appFlags
	app.Commands = commands

	if cpuProfileFilePath := os.Getenv(CPUProfileFilePathEnvKey); cpuProfileFilePath != "" {
		log.Infof("Enabling CPU Profiler, writing results into file: %s", cpuProfileFilePath)
		f, err := os.Create(cpuProfileFilePath)
		if err != nil {
			log.Fatalf("CPU Profile: failed to create file: %s", err)
		}
		if err := pprof.StartCPUProfile(f); err != nil {
			log.Fatalf("CPU Profile: failed to start CPU profiler: %s", err)
		}
		defer pprof.StopCPUProfile()
	}

	if err := app.Run(os.Args); err != nil {
		log.Fatal("Finished with error:", err)
	}
}
<commit_msg>0.9.11<commit_after>package cli

import (
	"fmt"
	"os"
	"path"
	"runtime/pprof"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/go-utils/freezable"
	"github.com/urfave/cli"
)

var (
	// MachineWorkdir ...
	MachineWorkdir = freezable.String{}
	// MachineParamsAdditionalEnvs ...
	MachineParamsAdditionalEnvs = freezable.StringSlice{}
	// MachineConfigTypeID ...
	MachineConfigTypeID = freezable.String{}
)

func before(c *cli.Context) error {
	// Log level
	if logLevel, err := log.ParseLevel(c.String(LogLevelKey)); err != nil {
		log.Fatal("Failed to parse log level:", err)
	} else {
		log.SetLevel(logLevel)
	}

	if len(c.Args()) != 0 && c.Args().First() != "version" && !c.Bool(HelpKey) && !c.Bool(VersionKey) {
		if err := MachineWorkdir.Set(c.String(WorkdirKey)); err != nil {
			log.Fatalf("Failed to set MachineWorkdir: %s", err)
		}
		if MachineWorkdir.String() == "" {
			log.Fatalln("No Workdir specified!")
		}
	}
	MachineWorkdir.Freeze()

	if err := MachineConfigTypeID.Set(c.String(ConfigTypeIDParamKey)); err != nil {
		log.Fatalf("Failed to set MachineConfigTypeID: %s", err)
	}
	log.Debugf("MachineConfigTypeID: %s", MachineConfigTypeID)

	if err := MachineParamsAdditionalEnvs.Set(c.StringSlice(EnvironmentParamKey)); err != nil {
		log.Fatalf("Failed to set MachineParamsAdditionalEnvs: %s", err)
	}
	log.Debugf("MachineParamsAdditionalEnvs: %s", MachineParamsAdditionalEnvs)
	MachineParamsAdditionalEnvs.Freeze()

	return nil
}

func printVersion(c *cli.Context) {
	fmt.Fprintf(c.App.Writer, "%v\n", c.App.Version)
}

// Run the CLI
func Run() {
	cli.VersionPrinter = printVersion

	app := cli.NewApp()
	app.Name = path.Base(os.Args[0])
	app.Usage = "bitrise-machine"
	app.Version = "0.9.11"

	app.Author = ""
	app.Email = ""

	app.Before = before

	app.Flags = appFlags
	app.Commands = commands

	if cpuProfileFilePath := os.Getenv(CPUProfileFilePathEnvKey); cpuProfileFilePath != "" {
		log.Infof("Enabling CPU Profiler, writing results into file: %s", cpuProfileFilePath)
		f, err := os.Create(cpuProfileFilePath)
		if err != nil {
			log.Fatalf("CPU Profile: failed to create file: %s", err)
		}
		if err := pprof.StartCPUProfile(f); err != nil {
			log.Fatalf("CPU Profile: failed to start CPU profiler: %s", err)
		}
		defer pprof.StopCPUProfile()
	}

	if err := app.Run(os.Args); err != nil {
		log.Fatal("Finished with error:", err)
	}
}
<|endoftext|>


<commit_before>package cli

import (
	"context"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/pkg/errors"

	"golang.org/x/crypto/ssh/terminal"

	"github.com/elpinal/coco3/config"
	"github.com/elpinal/coco3/eval"
	"github.com/elpinal/coco3/gate"
	"github.com/elpinal/coco3/parser"

	"github.com/elpinal/coco3/extra"
	eparser "github.com/elpinal/coco3/extra/parser"

	"github.com/jmoiron/sqlx"
	_ "github.com/mattn/go-sqlite3"
)

type CLI struct {
	In  io.Reader
	Out io.Writer
	Err io.Writer

	*config.Config

	db *sqlx.DB

	exitCh chan int
	doneCh chan struct{} // to ensure exiting just after exitCh received

	execute1 func([]byte) error
}

func (c *CLI) Run(args []string) int {
	f := flag.NewFlagSet("coco3", flag.ContinueOnError)
	f.SetOutput(c.Err)
	f.Usage = func() {
		c.Err.Write([]byte("coco3 is a shell.\n"))
		c.Err.Write([]byte("Usage:\n"))
		f.PrintDefaults()
	}

	if c.Config == nil {
		c.Config = &config.Config{}
	}
	c.Config.Init()
	flagC := f.String("c", "", "take first argument as a command to execute")
	flagE := f.Bool("extra", c.Config.Extra, "switch to extra mode")
	if err := f.Parse(args); err != nil {
		return 2
	}
	return c.run(f.Args(), flagC, flagE)
}

func (c *CLI) run(args []string, flagC *string, flagE *bool) int {
	c.exitCh = make(chan int)
	c.doneCh = make(chan struct{})
	defer close(c.doneCh)

	for _, alias := range c.Config.Alias {
		eval.DefAlias(alias[0], alias[1])
	}

	for k, v := range c.Config.Env {
		err := os.Setenv(k, v)
		if err != nil {
			c.errorln(err)
			return 1
		}
	}

	setpath(c.Config.Paths)

	if *flagE {
		// If -extra flag is on, enable extra mode on any command executions.
		c.execute1 = c.executeExtra
	} else {
		c.execute1 = c.execute
	}

	if len(c.Config.StartUpCommand) > 0 {
		done := make(chan struct{})
		go func() {
			if err := c.execute1(c.Config.StartUpCommand); err != nil {
				c.printExecError(err)
				c.exitCh <- 1
			}
			close(done)
		}()
		select {
		case code := <-c.exitCh:
			return code
		case <-done:
		}
	}

	if *flagC != "" {
		go func() {
			if err := c.execute1([]byte(*flagC)); err != nil {
				c.printExecError(err)
				c.exitCh <- 1
				return
			}
			c.exitCh <- 0
		}()
		return <-c.exitCh
	}

	if len(args) > 0 {
		n := c.runFiles(args)
		return n
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	histRunes, err := c.getHistory(c.Config.HistFile)
	if err != nil {
		c.errorln(err)
		return 1
	}
	g := gate.NewContext(ctx, c.Config, c.In, c.Out, c.Err, histRunes)
	go func(ctx context.Context) {
		for {
			if err := c.interact(g); err != nil {
				c.printExecError(err)
				g.Clear()
			}
			select {
			case <-ctx.Done():
				return
			default:
			}
		}
	}(ctx)
	return <-c.exitCh
}

func (c *CLI) errorf(s string, a ...interface{}) {
	fmt.Fprintf(c.Err, s, a...)
}

func (c *CLI) errorln(s ...interface{}) {
	fmt.Fprintln(c.Err, s...)
}

func (c *CLI) errorp(s ...interface{}) {
	fmt.Fprint(c.Err, s...)
}

func (c *CLI) getHistory(filename string) ([][]rune, error) {
	db, err := sqlx.Connect("sqlite3", filename)
	if err != nil {
		return nil, errors.Wrap(err, "connecting history file")
	}
	_, err = db.Exec(schema)
	if err != nil {
		return nil, errors.Wrap(err, "initializing history file")
	}
	var history []string
	err = db.Select(&history, "select line from command_info")
	if err != nil {
		return nil, errors.Wrap(err, "restoring history")
	}
	// TODO: Is this way proper?
	c.db = db
	return sanitizeHistory(history), nil
}

func (c *CLI) printExecError(err error) {
	if pe, ok := err.(*eparser.ParseError); ok {
		c.errorln(pe.Verbose())
	} else {
		c.errorln(err)
	}
}

// setpath sets the PATH environment variable.
func setpath(args []string) {
	if len(args) == 0 {
		return
	}
	paths := filepath.SplitList(os.Getenv("PATH"))
	var newPaths []string
	for _, path := range paths {
		if contains(args, path) {
			continue
		}
		newPaths = append(newPaths, path)
	}
	newPaths = append(args, newPaths...)
	os.Setenv("PATH", strings.Join(newPaths, string(filepath.ListSeparator)))
}

func contains(xs []string, s string) bool {
	for _, x := range xs {
		if x == s {
			return true
		}
	}
	return false
}

func sanitizeHistory(history []string) [][]rune {
	histRunes := make([][]rune, 0, len(history))
	for _, line := range history {
		if line == "" {
			continue
		}
		l := len(histRunes)
		s := []rune(line)
		if l > 0 && compareRunes(histRunes[l-1], s) {
			continue
		}
		histRunes = append(histRunes, s)
	}
	return histRunes
}

func compareRunes(r1, r2 []rune) bool {
	if len(r1) != len(r2) {
		return false
	}
	for i, r := range r1 {
		if r2[i] != r {
			return false
		}
	}
	return true
}

func (c *CLI) interact(g gate.Gate) error {
	r, end, err := c.read(g)
	if err != nil {
		return err
	}
	if end {
		c.exitCh <- 0
		<-c.doneCh
		return nil
	}
	go c.writeHistory(r)
	if err := c.execute1([]byte(string(r))); err != nil {
		return err
	}
	g.Clear()
	return nil
}

func (c *CLI) read(g gate.Gate) ([]rune, bool, error) {
	defer c.Out.Write([]byte{'\n'})
	oldState, err := terminal.MakeRaw(0)
	if err != nil {
		panic(err)
	}
	defer func() {
		if err := terminal.Restore(0, oldState); err != nil {
			c.errorln(err)
		}
	}()
	r, end, err := g.Read()
	if err != nil {
		return nil, false, err
	}
	return r, end, nil
}

func (c *CLI) writeHistory(r []rune) {
	startTime := time.Now()
	_, err := c.db.Exec("insert into command_info (time, line) values ($1, $2)", startTime, string(r))
	if err != nil {
		c.errorf("saving history: %v\n", err)
		c.exitCh <- 1
	}
}

const schema = `
create table if not exists command_info (
    time datetime,
    line text
)`

func (c *CLI) execute(b []byte) error {
	f, err := parser.ParseSrc(b)
	if err != nil {
		return err
	}
	e := eval.New(c.In, c.Out, c.Err, c.db)
	err = e.Eval(f.Lines)
	select {
	case code := <-e.ExitCh:
		c.exitCh <- code
		<-c.doneCh
	default:
	}
	return err
}

func (c *CLI) executeExtra(b []byte) error {
	cmd, err := eparser.Parse(b)
	if err != nil {
		return err
	}
	e := extra.New(extra.Option{DB: c.db})
	err = e.Eval(cmd)
	if err == nil {
		return nil
	}
	if pe, ok := err.(*eparser.ParseError); ok {
		pe.Src = string(b)
	}
	return err
}

func (c *CLI) runFiles(files []string) int {
	for _, file := range files {
		b, err := ioutil.ReadFile(file)
		if err != nil {
			c.errorln(err)
			return 1
		}
		if err := c.execute1(b); err != nil {
			c.errorln(err)
			return 1
		}
	}
	return 0
}
<commit_msg>Use more useful error messages<commit_after>package cli

import (
	"context"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/pkg/errors"

	"golang.org/x/crypto/ssh/terminal"

	"github.com/elpinal/coco3/config"
	"github.com/elpinal/coco3/eval"
	"github.com/elpinal/coco3/gate"
	"github.com/elpinal/coco3/parser"

	"github.com/elpinal/coco3/extra"
	eparser "github.com/elpinal/coco3/extra/parser"

	"github.com/jmoiron/sqlx"
	_ "github.com/mattn/go-sqlite3"
)

type CLI struct {
	In  io.Reader
	Out io.Writer
	Err io.Writer

	*config.Config

	db *sqlx.DB

	exitCh chan int
	doneCh chan struct{} // to ensure exiting just after exitCh received

	execute1 func([]byte) error
}

func (c *CLI) Run(args []string) int {
	f := flag.NewFlagSet("coco3", flag.ContinueOnError)
	f.SetOutput(c.Err)
	f.Usage = func() {
		c.Err.Write([]byte("coco3 is a shell.\n"))
		c.Err.Write([]byte("Usage:\n"))
		f.PrintDefaults()
	}

	if c.Config == nil {
		c.Config = &config.Config{}
	}
	c.Config.Init()
	flagC := f.String("c", "", "take first argument as a command to execute")
	flagE := f.Bool("extra", c.Config.Extra, "switch to extra mode")
	if err := f.Parse(args); err != nil {
		return 2
	}
	return c.run(f.Args(), flagC, flagE)
}

func (c *CLI) run(args []string, flagC *string, flagE *bool) int {
	c.exitCh = make(chan int)
	c.doneCh = make(chan struct{})
	defer close(c.doneCh)

	for _, alias := range c.Config.Alias {
		eval.DefAlias(alias[0], alias[1])
	}

	for k, v := range c.Config.Env {
		err := os.Setenv(k, v)
		if err != nil {
			c.errorln(err)
			return 1
		}
	}

	setpath(c.Config.Paths)

	if *flagE {
		// If -extra flag is on, enable extra mode on any command executions.
		c.execute1 = c.executeExtra
	} else {
		c.execute1 = c.execute
	}

	if len(c.Config.StartUpCommand) > 0 {
		done := make(chan struct{})
		go func() {
			if err := c.execute1(c.Config.StartUpCommand); err != nil {
				c.printExecError(err)
				c.exitCh <- 1
			}
			close(done)
		}()
		select {
		case code := <-c.exitCh:
			return code
		case <-done:
		}
	}

	if *flagC != "" {
		go func() {
			if err := c.execute1([]byte(*flagC)); err != nil {
				c.printExecError(err)
				c.exitCh <- 1
				return
			}
			c.exitCh <- 0
		}()
		return <-c.exitCh
	}

	if len(args) > 0 {
		n := c.runFiles(args)
		return n
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	histRunes, err := c.getHistory(c.Config.HistFile)
	if err != nil {
		c.errorln(err)
		return 1
	}
	g := gate.NewContext(ctx, c.Config, c.In, c.Out, c.Err, histRunes)
	go func(ctx context.Context) {
		for {
			if err := c.interact(g); err != nil {
				c.printExecError(err)
				g.Clear()
			}
			select {
			case <-ctx.Done():
				return
			default:
			}
		}
	}(ctx)
	return <-c.exitCh
}

func (c *CLI) errorf(s string, a ...interface{}) {
	fmt.Fprintf(c.Err, s, a...)
}

func (c *CLI) errorln(s ...interface{}) {
	fmt.Fprintln(c.Err, s...)
}

func (c *CLI) errorp(s ...interface{}) {
	fmt.Fprint(c.Err, s...)
}

func (c *CLI) getHistory(filename string) ([][]rune, error) {
	db, err := sqlx.Connect("sqlite3", filename)
	if err != nil {
		return nil, errors.Wrap(err, "connecting history file")
	}
	_, err = db.Exec(schema)
	if err != nil {
		return nil, errors.Wrap(err, "initializing history file")
	}
	var history []string
	err = db.Select(&history, "select line from command_info")
	if err != nil {
		return nil, errors.Wrap(err, "restoring history")
	}
	// TODO: Is this way proper?
	c.db = db
	return sanitizeHistory(history), nil
}

func (c *CLI) printExecError(err error) {
	if pe, ok := err.(*eparser.ParseError); ok {
		c.errorln(pe.Verbose())
	} else {
		c.errorln(err)
	}
}

// setpath sets the PATH environment variable.
func setpath(args []string) {
	if len(args) == 0 {
		return
	}
	paths := filepath.SplitList(os.Getenv("PATH"))
	var newPaths []string
	for _, path := range paths {
		if contains(args, path) {
			continue
		}
		newPaths = append(newPaths, path)
	}
	newPaths = append(args, newPaths...)
	os.Setenv("PATH", strings.Join(newPaths, string(filepath.ListSeparator)))
}

func contains(xs []string, s string) bool {
	for _, x := range xs {
		if x == s {
			return true
		}
	}
	return false
}

func sanitizeHistory(history []string) [][]rune {
	histRunes := make([][]rune, 0, len(history))
	for _, line := range history {
		if line == "" {
			continue
		}
		l := len(histRunes)
		s := []rune(line)
		if l > 0 && compareRunes(histRunes[l-1], s) {
			continue
		}
		histRunes = append(histRunes, s)
	}
	return histRunes
}

func compareRunes(r1, r2 []rune) bool {
	if len(r1) != len(r2) {
		return false
	}
	for i, r := range r1 {
		if r2[i] != r {
			return false
		}
	}
	return true
}

func (c *CLI) interact(g gate.Gate) error {
	r, end, err := c.read(g)
	if err != nil {
		return err
	}
	if end {
		c.exitCh <- 0
		<-c.doneCh
		return nil
	}
	go c.writeHistory(r)
	if err := c.execute1([]byte(string(r))); err != nil {
		return err
	}
	g.Clear()
	return nil
}

func (c *CLI) read(g gate.Gate) ([]rune, bool, error) {
	defer c.Out.Write([]byte{'\n'})
	oldState, err := terminal.MakeRaw(0)
	if err != nil {
		panic(err)
	}
	defer func() {
		if err := terminal.Restore(0, oldState); err != nil {
			c.errorln(err)
		}
	}()
	r, end, err := g.Read()
	if err != nil {
		return nil, false, err
	}
	return r, end, nil
}

func (c *CLI) writeHistory(r []rune) {
	startTime := time.Now()
	_, err := c.db.Exec("insert into command_info (time, line) values ($1, $2)", startTime, string(r))
	if err != nil {
		c.errorf("saving history: %v\n", err)
		c.exitCh <- 1
	}
}

const schema = `
create table if not exists command_info (
    time datetime,
    line text
)`

func (c *CLI) execute(b []byte) error {
	f, err := parser.ParseSrc(b)
	if err != nil {
		return err
	}
	e := eval.New(c.In, c.Out, c.Err, c.db)
	err = e.Eval(f.Lines)
	select {
	case code := <-e.ExitCh:
		c.exitCh <- code
		<-c.doneCh
	default:
	}
	return err
}

func (c *CLI) executeExtra(b []byte) error {
	cmd, err := eparser.Parse(b)
	if err != nil {
		return err
	}
	e := extra.New(extra.Option{DB: c.db})
	err = e.Eval(cmd)
	if err == nil {
		return nil
	}
	if pe, ok := err.(*eparser.ParseError); ok {
		pe.Src = string(b)
	}
	return err
}

func (c *CLI) runFiles(files []string) int {
	for _, file := range files {
		b, err := ioutil.ReadFile(file)
		if err != nil {
			c.errorln(err)
			return 1
		}
		if err := c.execute1(b); err != nil {
			c.printExecError(err)
			return 1
		}
	}
	return 0
}
<|endoftext|>


<commit_before>package cli

import (
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/envman/envman"
	"github.com/codegangsta/cli"
)

const (
	defaultEnvStoreName string = ".envstore.yml"
)

var (
	stdinValue string
)

func isPipedData() bool {
	if stat, err := os.Stdin.Stat(); err != nil {
		return false
	} else if (stat.Mode() & os.ModeCharDevice) == 0 {
		return true
	}
	return false
}

func envStorePathInCurrentDir() (string, error) {
	return filepath.Abs(path.Join("./", defaultEnvStoreName))
}

func before(c *cli.Context) error {
	// Log level
	if logLevel, err := log.ParseLevel(c.String(LogLevelKey)); err != nil {
		log.Fatal("[BITRISE_CLI] - Failed to parse log level:", err)
	} else {
		log.SetLevel(logLevel)
	}

	// Befor parsing cli, and running command
	// we need to decide wich path will be used by envman
	envman.CurrentEnvStoreFilePath = c.String(PathKey)
	if envman.CurrentEnvStoreFilePath == "" {
		if path, err := envStorePathInCurrentDir(); err != nil {
			log.Fatal("[ENVMAN] - Failed to set envman work path in current dir:", err)
		} else {
			envman.CurrentEnvStoreFilePath = path
		}
	}

	envman.ToolMode = c.Bool(ToolKey)
	if envman.ToolMode {
		log.Info("[ENVMAN] - Tool mode on")
	}

	return nil
}

func printVersion(c *cli.Context) {
	fmt.Fprintf(c.App.Writer, "%v\n", c.App.Version)
}

// Run the Envman CLI.
func Run() {
	// Read piped data
	if isPipedData() {
		if bytes, err := ioutil.ReadAll(os.Stdin); err != nil {
			log.Error("[ENVMAN] - Failed to read stdin:", err)
		} else if len(bytes) > 0 {
			stdinValue = string(bytes)
		}
	}

	// Parse cl
	cli.VersionPrinter = printVersion

	app := cli.NewApp()
	app.Name = path.Base(os.Args[0])
	app.Usage = "Environment variable manager"
	app.Version = "0.9.5"

	app.Author = ""
	app.Email = ""

	app.Before = before

	app.Flags = flags
	app.Commands = commands

	if err := app.Run(os.Args); err != nil {
		log.Fatal("[ENVMAN] - Finished:", err)
	}
}
<commit_msg>start of v0.9.6<commit_after>package cli

import (
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/envman/envman"
	"github.com/codegangsta/cli"
)

const (
	defaultEnvStoreName string = ".envstore.yml"
)

var (
	stdinValue string
)

func isPipedData() bool {
	if stat, err := os.Stdin.Stat(); err != nil {
		return false
	} else if (stat.Mode() & os.ModeCharDevice) == 0 {
		return true
	}
	return false
}

func envStorePathInCurrentDir() (string, error) {
	return filepath.Abs(path.Join("./", defaultEnvStoreName))
}

func before(c *cli.Context) error {
	// Log level
	if logLevel, err := log.ParseLevel(c.String(LogLevelKey)); err != nil {
		log.Fatal("[BITRISE_CLI] - Failed to parse log level:", err)
	} else {
		log.SetLevel(logLevel)
	}

	// Befor parsing cli, and running command
	// we need to decide wich path will be used by envman
	envman.CurrentEnvStoreFilePath = c.String(PathKey)
	if envman.CurrentEnvStoreFilePath == "" {
		if path, err := envStorePathInCurrentDir(); err != nil {
			log.Fatal("[ENVMAN] - Failed to set envman work path in current dir:", err)
		} else {
			envman.CurrentEnvStoreFilePath = path
		}
	}

	envman.ToolMode = c.Bool(ToolKey)
	if envman.ToolMode {
		log.Info("[ENVMAN] - Tool mode on")
	}

	return nil
}

func printVersion(c *cli.Context) {
	fmt.Fprintf(c.App.Writer, "%v\n", c.App.Version)
}

// Run the Envman CLI.
func Run() {
	// Read piped data
	if isPipedData() {
		if bytes, err := ioutil.ReadAll(os.Stdin); err != nil {
			log.Error("[ENVMAN] - Failed to read stdin:", err)
		} else if len(bytes) > 0 {
			stdinValue = string(bytes)
		}
	}

	// Parse cl
	cli.VersionPrinter = printVersion

	app := cli.NewApp()
	app.Name = path.Base(os.Args[0])
	app.Usage = "Environment variable manager"
	app.Version = "0.9.6"

	app.Author = ""
	app.Email = ""

	app.Before = before

	app.Flags = flags
	app.Commands = commands

	if err := app.Run(os.Args); err != nil {
		log.Fatal("[ENVMAN] - Finished:", err)
	}
}
<|endoftext|>


<commit_before>package resources

import . "github.com/jagregory/cfval/schema"

var autoScalingTag = Resource{
	AwsType: "AutoScaling Tag",
	Properties: map[string]Schema{
		"Key": Schema{
			Type:     TypeString,
			Required: true,
		},

		"Value": Schema{
			Type:     TypeString,
			Required: true,
		},

		"PropagateAtLaunch": Schema{
			Type: TypeBool,
		},
	},
}

var metricsCollection = Resource{
	AwsType:    "Auto Scaling MetricsCollection",
	Properties: map[string]Schema{
	// TODO
	},
}

var notificationConfiguration = Resource{
	AwsType:    "Auto Scaling NotificationConfiguration",
	Properties: map[string]Schema{
	// TODO
	},
}

func AutoScalingGroup() Resource {
	return Resource{
		AwsType: "AWS::AutoScaling::AutoScalingGroup",
		Properties: map[string]Schema{
			"AvailabilityZones": Schema{
				Array:        true,
				Type:         TypeString,
				ValidateFunc: availabilityZone,
			},

			"Cooldown": Schema{
				Type: TypeString,
			},

			"DesiredCapacity": Schema{
				Type: TypeString,
			},

			"HealthCheckGracePeriod": Schema{
				Type: TypeInteger,
			},

			"HealthCheckType": Schema{
				Type:         TypeString,
				ValidateFunc: EnumValidate("EC2", "ELB"),
			},

			"InstanceId": Schema{
				Type: TypeString,
			},

			"LaunchConfigurationName": Schema{
				Type: TypeString,
			},

			"LoadBalancerNames": Schema{
				Type:  TypeString,
				Array: true,
			},

			"MaxSize": Schema{
				Type: TypeString,
			},

			"MetricsCollection": Schema{
				Type:  metricsCollection,
				Array: true,
			},

			"MinSize": Schema{
				Type: TypeString,
			},

			"NotificationConfigurations": Schema{
				Type:  notificationConfiguration,
				Array: true,
			},

			"PlacementGroup": Schema{
				Type: TypeString,
			},

			"Tags": Schema{
				Type:  autoScalingTag,
				Array: true,
			},

			"TerminationPolicies": Schema{
				Type:  TypeString,
				Array: true,
			},

			"VPCZoneIdentifier": Schema{
				Type:  TypeString,
				Array: true,
			},
		},
	}
}

func LaunchConfiguration() Resource {
	return Resource{
		AwsType: "AWS::AutoScaling::LaunchConfiguration",
		Properties: map[string]Schema{
			// "AssociatePublicIpAddress" : Boolean,
			// "BlockDeviceMappings" : [ BlockDeviceMapping, ... ],
			// "ClassicLinkVPCId" : String,
			// "ClassicLinkVPCSecurityGroups" : [ String, ... ],
			// "EbsOptimized" : Boolean,

			"IamInstanceProfile": Schema{
				Type: TypeString,
			},

			"ImageId": Schema{
				Type: TypeString,
			},

			// "InstanceId" : String,
			// "InstanceMonitoring" : Boolean,

			"InstanceType": Schema{
				Type: TypeString,
			},

			// "KernelId" : String,
			"KeyName": Schema{
				Type: TypeString,
			},

			// "PlacementTenancy" : String,
			// "RamDiskId" : String,

			"SecurityGroups": Schema{
				Type:  TypeString,
				Array: true,
			},

			// "SpotPrice" : String,

			"UserData": Schema{
				Type: TypeString,
			},
		},
	}
}
<commit_msg>More autoscaling properties<commit_after>package resources

import . "github.com/jagregory/cfval/schema"

var autoScalingTag = Resource{
	AwsType: "AutoScaling Tag",
	Properties: map[string]Schema{
		"Key": Schema{
			Type:     TypeString,
			Required: true,
		},

		"Value": Schema{
			Type:     TypeString,
			Required: true,
		},

		"PropagateAtLaunch": Schema{
			Type: TypeBool,
		},
	},
}

var metricsCollection = Resource{
	AwsType: "Auto Scaling MetricsCollection",
	Properties: map[string]Schema{
		"Granularity": Schema{
			Type:     TypeString,
			Required: true,
		},

		"Metrics": Schema{
			Type:  TypeString,
			Array: true,
		},
	},
}

var notificationConfiguration = Resource{
	AwsType: "Auto Scaling NotificationConfiguration",
	Properties: map[string]Schema{
		"NotificationTypes": Schema{
			Type:         TypeString,
			Required:     true,
			Array:        true,
			ValidateFunc: EnumValidate("autoscaling:EC2_INSTANCE_LAUNCH", "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", "autoscaling:EC2_INSTANCE_TERMINATE", "autoscaling:EC2_INSTANCE_TERMINATE_ERROR", "autoscaling:TEST_NOTIFICATION"),
		},

		"TopicARN": Schema{
			Type:     TypeString,
			Required: true,
		},
	},
}

func AutoScalingGroup() Resource {
	return Resource{
		AwsType: "AWS::AutoScaling::AutoScalingGroup",
		Properties: map[string]Schema{
			"AvailabilityZones": Schema{
				Array:          true,
				Type:           TypeString,
				ValidateFunc:   availabilityZone,
				RequiredUnless: []string{"VPCZoneIdentifier"},
			},

			"Cooldown": Schema{
				Type: TypeString,
			},

			"DesiredCapacity": Schema{
				Type: TypeString,
			},

			"HealthCheckGracePeriod": Schema{
				Type: TypeInteger,
			},

			"HealthCheckType": Schema{
				Type:         TypeString,
				ValidateFunc: EnumValidate("EC2", "ELB"),
			},

			"InstanceId": Schema{
				Type:           TypeString,
				RequiredUnless: []string{"LaunchConfigurationName"},
			},

			"LaunchConfigurationName": Schema{
				Type:           TypeString,
				RequiredUnless: []string{"InstanceId"},
			},

			"LoadBalancerNames": Schema{
				Type:  TypeString,
				Array: true,
			},

			"MaxSize": Schema{
				Type: TypeString,
			},

			"MetricsCollection": Schema{
				Type:  metricsCollection,
				Array: true,
			},

			"MinSize": Schema{
				Type: TypeString,
			},

			"NotificationConfigurations": Schema{
				Type:  notificationConfiguration,
				Array: true,
			},

			"PlacementGroup": Schema{
				Type: TypeString,
			},

			"Tags": Schema{
				Type:  autoScalingTag,
				Array: true,
			},

			"TerminationPolicies": Schema{
				Type:  TypeString,
				Array: true,
			},

			"VPCZoneIdentifier": Schema{
				Type:           TypeString,
				Array:          true,
				RequiredUnless: []string{"AvailabilityZones"},
			},
		},
	}
}

func LaunchConfiguration() Resource {
	return Resource{
		AwsType: "AWS::AutoScaling::LaunchConfiguration",
		Properties: map[string]Schema{
			// "AssociatePublicIpAddress" : Boolean,
			// "BlockDeviceMappings" : [ BlockDeviceMapping, ... ],
			// "ClassicLinkVPCId" : String,
			// "ClassicLinkVPCSecurityGroups" : [ String, ... ],
			// "EbsOptimized" : Boolean,

			"IamInstanceProfile": Schema{
				Type: TypeString,
			},

			"ImageId": Schema{
				Type: TypeString,
			},

			// "InstanceId" : String,
			// "InstanceMonitoring" : Boolean,

			"InstanceType": Schema{
				Type: TypeString,
			},

			// "KernelId" : String,
			"KeyName": Schema{
				Type: TypeString,
			},

			// "PlacementTenancy" : String,
			// "RamDiskId" : String,

			"SecurityGroups": Schema{
				Type:  TypeString,
				Array: true,
			},

			// "SpotPrice" : String,

			"UserData": Schema{
				Type: TypeString,
			},
		},
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package pprof

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"regexp"
	"strconv"
	"strings"
	"time"
)

type readState int

const (
	ignore readState = iota
	samplesHeader
	samples
	locations
	mappings
)

// funcID is the ID of a given Location in the pprof raw output.
type funcID int

type rawParser struct {
	// err is the first error encountered by the parser.
	err error

	state    readState
	funcName map[funcID]string
	records  []*stackRecord
}

// ParseRaw parses the raw pprof output and returns call stacks.
func ParseRaw(input []byte) ([]byte, error) {
	parser := newRawParser()
	if err := parser.parse(input); err != nil {
		return nil, err
	}

	// TODO(prashantv): Refactor interfaces so we use streams.
	buf := &bytes.Buffer{}
	if err := parser.print(buf); err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

func newRawParser() *rawParser {
	return &rawParser{
		funcName: make(map[funcID]string),
	}
}

func (p *rawParser) parse(input []byte) error {
	reader := bufio.NewReader(bytes.NewReader(input))

	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				if p.state < locations {
					p.setError(fmt.Errorf("parser ended before processing locations, state: %v", p.state))
				}
				break
			}
			return err
		}

		p.processLine(strings.TrimSpace(line))
	}

	return p.err
}

func (p *rawParser) setError(err error) {
	if p.err != nil {
		return
	}
	p.err = err
}

func (p *rawParser) processLine(line string) {
	switch p.state {
	case ignore:
		if strings.HasPrefix(line, "Samples") {
			p.state = samplesHeader
			return
		}
	case samplesHeader:
		p.state = samples
	case samples:
		if strings.HasPrefix(line, "Locations") {
			p.state = locations
			return
		}
		p.addSample(line)
	case locations:
		if strings.HasPrefix(line, "Mappings") {
			p.state = mappings
			return
		}
		p.addLocation(line)
	case mappings:
		// Nothing to process.
	}
}

// print prints out the stack traces collected from the raw pprof output.
func (p *rawParser) print(w io.Writer) error {
	for _, r := range p.records {
		r.Serialize(p.funcName, w)
		fmt.Fprintln(w)
	}
	if wc, ok := w.(io.WriteCloser); ok {
		return wc.Close()
	}
	return nil
}

func (p *rawParser) parseInt(s string) int {
	v, err := strconv.Atoi(s)
	if err != nil {
		p.setError(err)
		return 0
	}

	return v
}

// addSample parses a sample that looks like:
//   1   10000000: 1 2 3 4
// and creates a stackRecord for it.
func (p *rawParser) addSample(line string) {
	// Parse a sample which looks like:
	parts := splitBySpace(line)
	if len(parts) < 3 {
		p.setError(fmt.Errorf("malformed sample line: %v", line))
		return
	}

	samples := p.parseInt(parts[0])
	duration := p.parseInt(strings.TrimSuffix(parts[1], ":"))

	var stack []funcID
	for _, fIDStr := range parts[2:] {
		stack = append(stack, p.toFuncID(fIDStr))
	}

	p.records = append(p.records, &stackRecord{samples, time.Duration(duration), stack})
}

// addLocation parses a location that looks like:
//   292: 0x49dee1 github.com/uber/tchannel/golang.(*Frame).ReadIn :0 s=0
// and creates a mapping from funcID to function name.
func (p *rawParser) addLocation(line string) {
	parts := splitBySpace(line)
	if len(parts) < 3 {
		p.setError(fmt.Errorf("malformed location line: %v", line))
		return
	}
	funcID := p.toFuncID(strings.TrimSuffix(parts[0], ":"))
	p.funcName[funcID] = parts[2]
}

type stackRecord struct {
	samples  int
	duration time.Duration
	stack    []funcID
}

func getFunctionName(funcNames map[funcID]string, funcID funcID) string {
	if funcName, ok := funcNames[funcID]; ok {
		return funcName
	}
	return fmt.Sprintf("missing-function-%v", funcID)
}

// Serialize serializes a call stack for a given stackRecord given the funcID mapping.
func (r *stackRecord) Serialize(funcNames map[funcID]string, w io.Writer) {
	for _, funcID := range r.stack {
		fmt.Fprintln(w, getFunctionName(funcNames, funcID))
	}
	fmt.Fprintln(w, r.samples)
}

// toFuncID converts a string like "8" to a funcID.
func (p *rawParser) toFuncID(s string) funcID {
	return funcID(p.parseInt(s))
}

var spaceSplitter = regexp.MustCompile(`\s+`)

// splitBySpace splits values separated by 1 or more spaces.
func splitBySpace(s string) []string {
	return spaceSplitter.Split(strings.TrimSpace(s), -1)
}
<commit_msg>Unexport stackRecord.Serialize<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package pprof

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"regexp"
	"strconv"
	"strings"
	"time"
)

type readState int

const (
	ignore readState = iota
	samplesHeader
	samples
	locations
	mappings
)

// funcID is the ID of a given Location in the pprof raw output.
type funcID int

type rawParser struct {
	// err is the first error encountered by the parser.
	err error

	state    readState
	funcName map[funcID]string
	records  []*stackRecord
}

// ParseRaw parses the raw pprof output and returns call stacks.
func ParseRaw(input []byte) ([]byte, error) {
	parser := newRawParser()
	if err := parser.parse(input); err != nil {
		return nil, err
	}

	// TODO(prashantv): Refactor interfaces so we use streams.
	buf := &bytes.Buffer{}
	if err := parser.print(buf); err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

func newRawParser() *rawParser {
	return &rawParser{
		funcName: make(map[funcID]string),
	}
}

func (p *rawParser) parse(input []byte) error {
	reader := bufio.NewReader(bytes.NewReader(input))

	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				if p.state < locations {
					p.setError(fmt.Errorf("parser ended before processing locations, state: %v", p.state))
				}
				break
			}
			return err
		}

		p.processLine(strings.TrimSpace(line))
	}

	return p.err
}

func (p *rawParser) setError(err error) {
	if p.err != nil {
		return
	}
	p.err = err
}

func (p *rawParser) processLine(line string) {
	switch p.state {
	case ignore:
		if strings.HasPrefix(line, "Samples") {
			p.state = samplesHeader
			return
		}
	case samplesHeader:
		p.state = samples
	case samples:
		if strings.HasPrefix(line, "Locations") {
			p.state = locations
			return
		}
		p.addSample(line)
	case locations:
		if strings.HasPrefix(line, "Mappings") {
			p.state = mappings
			return
		}
		p.addLocation(line)
	case mappings:
		// Nothing to process.
	}
}

// print prints out the stack traces collected from the raw pprof output.
func (p *rawParser) print(w io.Writer) error {
	for _, r := range p.records {
		r.serialize(p.funcName, w)
		fmt.Fprintln(w)
	}
	if wc, ok := w.(io.WriteCloser); ok {
		return wc.Close()
	}
	return nil
}

func (p *rawParser) parseInt(s string) int {
	v, err := strconv.Atoi(s)
	if err != nil {
		p.setError(err)
		return 0
	}

	return v
}

// addSample parses a sample that looks like:
//   1   10000000: 1 2 3 4
// and creates a stackRecord for it.
func (p *rawParser) addSample(line string) {
	// Parse a sample which looks like:
	parts := splitBySpace(line)
	if len(parts) < 3 {
		p.setError(fmt.Errorf("malformed sample line: %v", line))
		return
	}

	samples := p.parseInt(parts[0])
	duration := p.parseInt(strings.TrimSuffix(parts[1], ":"))

	var stack []funcID
	for _, fIDStr := range parts[2:] {
		stack = append(stack, p.toFuncID(fIDStr))
	}

	p.records = append(p.records, &stackRecord{samples, time.Duration(duration), stack})
}

// addLocation parses a location that looks like:
//   292: 0x49dee1 github.com/uber/tchannel/golang.(*Frame).ReadIn :0 s=0
// and creates a mapping from funcID to function name.
func (p *rawParser) addLocation(line string) {
	parts := splitBySpace(line)
	if len(parts) < 3 {
		p.setError(fmt.Errorf("malformed location line: %v", line))
		return
	}
	funcID := p.toFuncID(strings.TrimSuffix(parts[0], ":"))
	p.funcName[funcID] = parts[2]
}

type stackRecord struct {
	samples  int
	duration time.Duration
	stack    []funcID
}

func getFunctionName(funcNames map[funcID]string, funcID funcID) string {
	if funcName, ok := funcNames[funcID]; ok {
		return funcName
	}
	return fmt.Sprintf("missing-function-%v", funcID)
}

// serialize serializes a call stack for a given stackRecord given the funcID mapping.
func (r *stackRecord) serialize(funcNames map[funcID]string, w io.Writer) {
	for _, funcID := range r.stack {
		fmt.Fprintln(w, getFunctionName(funcNames, funcID))
	}
	fmt.Fprintln(w, r.samples)
}

// toFuncID converts a string like "8" to a funcID.
func (p *rawParser) toFuncID(s string) funcID {
	return funcID(p.parseInt(s))
}

var spaceSplitter = regexp.MustCompile(`\s+`)

// splitBySpace splits values separated by 1 or more spaces.
func splitBySpace(s string) []string {
	return spaceSplitter.Split(strings.TrimSpace(s), -1)
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"

	// Alias this because we call our connection couchbase
	cb "github.com/couchbaselabs/go-couchbase"
	"github.com/couchbaselabs/go-couchbase/util"
)

var couchbase *cb.Bucket

const ddocKey = "/@ddocVersion"
const ddocVersion = 3
const designDoc = `
{
    "spatialInfos": [],
    "viewInfos": [
        {
            "map": "function (doc, meta) {\n  if (doc.type === \"file\") {\n    var toEmit = {};\n    toEmit[doc.oid] = meta.id;\n    if (doc.older) {\n      for (var i = 0; i < doc.older.length; i++) {\n        toEmit[doc.older[i].oid] = meta.id;\n      }\n    }\n    for (var k in toEmit) {\n      emit([k, \"file\", meta.id], null);\n    }\n  } else if (doc.type === \"blob\") {\n    var replicas=0;\n    for (var node in doc.nodes) {\n      replicas++;\n      emit([doc.oid, \"blob\", node], null);\n    }\n    if (replicas === 0) {\n      emit([doc.oid, \"blob\", \"\"], null);\n    }\n  }\n}",
            "name": "file_blobs",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Ffile_blobs",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Ffile_blobs"
        },
        {
            "map": "function (doc, meta) {\n  if(doc.type == \"file\") {  \n    var idarr = meta.id.split(\"/\");\n    emit(idarr, doc.length);\n  }\n}",
            "name": "file_browse",
            "reduce": "_stats",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Ffile_browse",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Ffile_browse"
        },
        {
            "map": "function (doc, meta) {\n  if (doc.type === 'blob') {\n    emit(doc.garbage ? 'garbage' : 'live', doc.length);\n  }\n}",
            "name": "garbage",
            "reduce": "_stats",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fgarbage",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fgarbage"
        },
        {
            "map": "function (doc, meta) {\n  if (doc.type === \"blob\") {\n    for (var n in doc.nodes) {\n      emit(n, null);\n    }\n  }\n}",
            "name": "node_blobs",
            "reduce": "_count",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fnode_blobs",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fnode_blobs"
        },
        {
            "map": "function (doc, meta) {\n  if (doc.type === \"node\") {\n    emit(meta.id.substring(1), 0);\n  } else if (doc.type === \"blob\") {\n    for (var n in doc.nodes) {\n      emit(n, doc.length);\n    }\n  }\n}",
            "name": "node_size",
            "reduce": "_sum",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fnode_size",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fnode_size"
        },
        {
            "map": "function (doc, meta) {\n  if (doc.type === \"blob\" && !doc.garbage) {\n    var nreps = 0;\n    for (var x in doc.nodes) {\n      nreps++;\n    }\n    emit(nreps, null);\n  }\n}",
            "name": "repcounts",
            "reduce": "_count",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Frepcounts",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Frepcounts"
        }
    ],
    "views": {
        "file_blobs": {
            "map": "function (doc, meta) {\n  if (doc.type === \"file\") {\n    var toEmit = {};\n    toEmit[doc.oid] = doc.name ? doc.name : meta.id;\n    if (doc.older) {\n      for (var i = 0; i < doc.older.length; i++) {\n        toEmit[doc.older[i].oid] = doc.name ? doc.name : meta.id;\n      }\n    }\n    for (var k in toEmit) {\n      emit([k, \"file\", doc.name ? doc.name : meta.id], null);\n    }\n  } else if (doc.type === \"blob\") {\n    var replicas=0;\n    for (var node in doc.nodes) {\n      replicas++;\n      emit([doc.oid, \"blob\", node], null);\n    }\n    if (replicas === 0) {\n      emit([doc.oid, \"blob\", \"\"], null);\n    }\n  }\n}"
        },
        "file_browse": {
            "map": "function (doc, meta) {\n  if(doc.type == \"file\") {  \n    var idarr = (doc.name ? doc.name : meta.id).split(\"/\");\n    emit(idarr, doc.length);\n  }\n}",
            "reduce": "_stats"
        },
        "garbage": {
            "map": "function (doc, meta) {\n  if (doc.type === 'blob') {\n    emit(doc.garbage ? 'garbage' : 'live', doc.length);\n  }\n}",
            "reduce": "_stats"
        },
        "node_blobs": {
            "map": "function (doc, meta) {\n  if (doc.type === \"blob\") {\n    for (var n in doc.nodes) {\n      emit(n, null);\n    }\n  }\n}",
            "reduce": "_count"
        },
        "node_size": {
            "map": "function (doc, meta) {\n  if (doc.type === \"node\") {\n    emit(meta.id.substring(1), 0);\n  } else if (doc.type === \"blob\") {\n    for (var n in doc.nodes) {\n      emit(n, doc.length);\n    }\n  }\n}",
            "reduce": "_sum"
        },
        "repcounts": {
            "map": "function (doc, meta) {\n  if (doc.type === \"blob\" && !doc.garbage) {\n    var nreps = 0;\n    for (var x in doc.nodes) {\n      nreps++;\n    }\n    emit(nreps, null);\n  }\n}",
            "reduce": "_count"
        }
    }
}
`

func dbConnect() (*cb.Bucket, error) {
	cb.HTTPClient = &http.Client{
		Transport: TimeoutTransport(*viewTimeout),
	}

	log.Printf("Connecting to couchbase bucket %v at %v",
		*couchbaseBucket, *couchbaseServer)
	rv, err := cb.GetBucket(*couchbaseServer, "default", *couchbaseBucket)
	if err != nil {
		return nil, err
	}

	return rv, couchbaseutil.UpdateView(rv, "cbfs",
		ddocKey, designDoc, ddocVersion)
}
<commit_msg>Updating to new go-couchbase import <commit_after>package main

import (
	"log"
	"net/http"

	// Alias this because we call our connection couchbase
	cb "github.com/couchbase/go-couchbase"
	"github.com/couchbase/go-couchbase/util"
)

var couchbase *cb.Bucket

const ddocKey = "/@ddocVersion"
const ddocVersion = 3
const designDoc = `
{
    "spatialInfos": [],
    "viewInfos": [
        {
            "map": "function (doc, meta) {\n  if (doc.type === \"file\") {\n    var toEmit = {};\n    toEmit[doc.oid] = meta.id;\n    if (doc.older) {\n      for (var i = 0; i < doc.older.length; i++) {\n        toEmit[doc.older[i].oid] = meta.id;\n      }\n    }\n    for (var k in toEmit) {\n      emit([k, \"file\", meta.id], null);\n    }\n  } else if (doc.type === \"blob\") {\n    var replicas=0;\n    for (var node in doc.nodes) {\n      replicas++;\n      emit([doc.oid, \"blob\", node], null);\n    }\n    if (replicas === 0) {\n      emit([doc.oid, \"blob\", \"\"], null);\n    }\n  }\n}",
            "name": "file_blobs",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Ffile_blobs",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Ffile_blobs"
        },
        {
            "map": "function (doc, meta) {\n  if(doc.type == \"file\") {  \n    var idarr = meta.id.split(\"/\");\n    emit(idarr, doc.length);\n  }\n}",
            "name": "file_browse",
            "reduce": "_stats",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Ffile_browse",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Ffile_browse"
        },
        {
            "map": "function (doc, meta) {\n  if (doc.type === 'blob') {\n    emit(doc.garbage ? 'garbage' : 'live', doc.length);\n  }\n}",
            "name": "garbage",
            "reduce": "_stats",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fgarbage",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fgarbage"
        },
        {
            "map": "function (doc, meta) {\n  if (doc.type === \"blob\") {\n    for (var n in doc.nodes) {\n      emit(n, null);\n    }\n  }\n}",
            "name": "node_blobs",
            "reduce": "_count",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fnode_blobs",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fnode_blobs"
        },
        {
            "map": "function (doc, meta) {\n  if (doc.type === \"node\") {\n    emit(meta.id.substring(1), 0);\n  } else if (doc.type === \"blob\") {\n    for (var n in doc.nodes) {\n      emit(n, doc.length);\n    }\n  }\n}",
            "name": "node_size",
            "reduce": "_sum",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fnode_size",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Fnode_size"
        },
        {
            "map": "function (doc, meta) {\n  if (doc.type === \"blob\" && !doc.garbage) {\n    var nreps = 0;\n    for (var x in doc.nodes) {\n      nreps++;\n    }\n    emit(nreps, null);\n  }\n}",
            "name": "repcounts",
            "reduce": "_count",
            "removeLink": "#removeView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Frepcounts",
            "viewLink": "#showView=cbfs%2F_design%252Fdev_cbfs%2F_view%2Frepcounts"
        }
    ],
    "views": {
        "file_blobs": {
            "map": "function (doc, meta) {\n  if (doc.type === \"file\") {\n    var toEmit = {};\n    toEmit[doc.oid] = doc.name ? doc.name : meta.id;\n    if (doc.older) {\n      for (var i = 0; i < doc.older.length; i++) {\n        toEmit[doc.older[i].oid] = doc.name ? doc.name : meta.id;\n      }\n    }\n    for (var k in toEmit) {\n      emit([k, \"file\", doc.name ? doc.name : meta.id], null);\n    }\n  } else if (doc.type === \"blob\") {\n    var replicas=0;\n    for (var node in doc.nodes) {\n      replicas++;\n      emit([doc.oid, \"blob\", node], null);\n    }\n    if (replicas === 0) {\n      emit([doc.oid, \"blob\", \"\"], null);\n    }\n  }\n}"
        },
        "file_browse": {
            "map": "function (doc, meta) {\n  if(doc.type == \"file\") {  \n    var idarr = (doc.name ? doc.name : meta.id).split(\"/\");\n    emit(idarr, doc.length);\n  }\n}",
            "reduce": "_stats"
        },
        "garbage": {
            "map": "function (doc, meta) {\n  if (doc.type === 'blob') {\n    emit(doc.garbage ? 'garbage' : 'live', doc.length);\n  }\n}",
            "reduce": "_stats"
        },
        "node_blobs": {
            "map": "function (doc, meta) {\n  if (doc.type === \"blob\") {\n    for (var n in doc.nodes) {\n      emit(n, null);\n    }\n  }\n}",
            "reduce": "_count"
        },
        "node_size": {
            "map": "function (doc, meta) {\n  if (doc.type === \"node\") {\n    emit(meta.id.substring(1), 0);\n  } else if (doc.type === \"blob\") {\n    for (var n in doc.nodes) {\n      emit(n, doc.length);\n    }\n  }\n}",
            "reduce": "_sum"
        },
        "repcounts": {
            "map": "function (doc, meta) {\n  if (doc.type === \"blob\" && !doc.garbage) {\n    var nreps = 0;\n    for (var x in doc.nodes) {\n      nreps++;\n    }\n    emit(nreps, null);\n  }\n}",
            "reduce": "_count"
        }
    }
}
`

func dbConnect() (*cb.Bucket, error) {
	cb.HTTPClient = &http.Client{
		Transport: TimeoutTransport(*viewTimeout),
	}

	log.Printf("Connecting to couchbase bucket %v at %v",
		*couchbaseBucket, *couchbaseServer)
	rv, err := cb.GetBucket(*couchbaseServer, "default", *couchbaseBucket)
	if err != nil {
		return nil, err
	}

	return rv, couchbaseutil.UpdateView(rv, "cbfs",
		ddocKey, designDoc, ddocVersion)
}
<|endoftext|>


<commit_before>package main

import (
  . "github.com/onsi/ginkgo"
  . "github.com/onsi/gomega"
  "testing"
    "io"
  "net/http"
  "net/http/httptest"
    "github.com/codegangsta/martini"
    "github.com/codegangsta/martini-contrib/render"
    "github.com/codegangsta/martini-contrib/binding"

)

var (
  response *httptest.ResponseRecorder
)

func TestMain(t *testing.T) {
  RegisterFailHandler(Fail)
  RunSpecs(t, "Main Suite")
}

func Request(method string, route string, handler martini.Handler) {
  m := martini.Classic()
  m.Get(route, handler)
  m.Use(render.Renderer())
  request, _ := http.NewRequest(method, route, nil)
  response = httptest.NewRecorder()
  m.ServeHTTP(response, request)
}

// func PostRequest(method string, route string, handler martini.Handler, body io.Reader) {
//   m := martini.Classic()
//   m.Post(route, binding.Json(Todo{}), handler)
//   m.Use(render.Renderer())
//   request, _ := http.NewRequest(method, route, body)
//   response = httptest.NewRecorder()
//   m.ServeHTTP(response, request)
// }<commit_msg>fighting wercker<commit_after>package main

import (
  . "github.com/onsi/ginkgo"
  . "github.com/onsi/gomega"
  "testing"
    //"io"
  "net/http"
  "net/http/httptest"
    "github.com/codegangsta/martini"
    "github.com/codegangsta/martini-contrib/render"
    //"github.com/codegangsta/martini-contrib/binding"

)

var (
  response *httptest.ResponseRecorder
)

func TestMain(t *testing.T) {
  RegisterFailHandler(Fail)
  RunSpecs(t, "Main Suite")
}

func Request(method string, route string, handler martini.Handler) {
  m := martini.Classic()
  m.Get(route, handler)
  m.Use(render.Renderer())
  request, _ := http.NewRequest(method, route, nil)
  response = httptest.NewRecorder()
  m.ServeHTTP(response, request)
}

// func PostRequest(method string, route string, handler martini.Handler, body io.Reader) {
//   m := martini.Classic()
//   m.Post(route, binding.Json(Todo{}), handler)
//   m.Use(render.Renderer())
//   request, _ := http.NewRequest(method, route, body)
//   response = httptest.NewRecorder()
//   m.ServeHTTP(response, request)
// }<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/fatih/color"
)

func logInfo(v ...interface{}) {
	fmt.Println(color.YellowString("[INFO]\t"), fmt.Sprint(v...))
}

func logError(v ...interface{}) {
	fmt.Println(color.RedString("[ERROR]\t%v"), fmt.Sprint(v...))
}
<commit_msg>refactor(log): uses standard `log.Logger` for logging<commit_after>package main

import (
	"fmt"
	"github.com/fatih/color"
	"log"
	"os"
)

var logger *log.Logger

func currentLogger() *log.Logger {
	if logger == nil {
		logger = log.New(os.Stdout, "", 0)
	}

	return logger
}

func logInfo(v ...interface{}) {
	currentLogger().Println(color.YellowString("[INFO]\t"), fmt.Sprint(v...))
}

func logError(v ...interface{}) {
	currentLogger().Println(color.RedString("[ERROR]\t"), fmt.Sprint(v...))
}
<|endoftext|>


<commit_before>package docindexing

import (
	"container/list"
	"sync"
	"runtime"
)

// Highest level inverted index structure
type InvertedIndex struct {
	Terms map[string]*TermEntry
	TermCount int
	IndexLock *sync.Mutex

}

// Stores terms and their respective document entries
type TermEntry struct {
	Term string
	Frequency int
	Documents *list.List
	EntryLock *sync.Mutex
}

// Stores document metadata as well as additional term information
type DocumentEntry struct {
	Name string
	Path string
	Size int
	Frequency int
	Positions *list.List
}

// Constructs new inverted index
func NewIndex() *InvertedIndex {
	return &InvertedIndex{Terms: make(map[string]*TermEntry), TermCount: 0, IndexLock: &sync.Mutex{}}
}

// Adds new term entry to the index
func (ind *InvertedIndex) AddTerm(term string) {
	ind.IndexLock.Lock()
	// Make sure we aren't overwriting existing term
	if _, found := ind.Terms[term]; !found {
		ind.Terms[term] = &TermEntry{Term: term, Frequency: 0, Documents: list.New(), EntryLock: &sync.Mutex{}}
		ind.TermCount++;
	}
	ind.IndexLock.Unlock()
	runtime.Gosched()
}

// Adds new document entry to given term entry
func (ind *InvertedIndex) AddDocument(term string, document *DocumentEntry) {
	// Make sure term is in index
	if _, found := ind.Terms[term]; found {
		ind.Terms[term].EntryLock.Lock()
		ind.Terms[term].Frequency += document.Frequency
		ind.Terms[term].Documents.PushBack(document)
		ind.Terms[term].EntryLock.Unlock()
		runtime.Gosched()
	}
}<commit_msg>Made small change to doc adding<commit_after>package docindexing

import (
	"container/list"
	"sync"
	"runtime"
)

// Highest level inverted index structure
type InvertedIndex struct {
	Terms map[string]*TermEntry
	TermCount int
	IndexLock *sync.Mutex

}

// Stores terms and their respective document entries
type TermEntry struct {
	Term string
	Frequency int
	Documents *list.List
	EntryLock *sync.Mutex
}

// Stores document metadata as well as additional term information
type DocumentEntry struct {
	Name string
	Path string
	Size int
	Frequency int
	Positions *list.List
}

// Constructs new inverted index
func NewIndex() *InvertedIndex {
	return &InvertedIndex{Terms: make(map[string]*TermEntry), TermCount: 0, IndexLock: &sync.Mutex{}}
}

// Adds new term entry to the index
func (ind *InvertedIndex) AddTerm(term string) {
	ind.IndexLock.Lock()
	// Make sure we aren't overwriting existing term
	if _, found := ind.Terms[term]; !found {
		ind.Terms[term] = &TermEntry{Term: term, Frequency: 0, Documents: list.New(), EntryLock: &sync.Mutex{}}
		ind.TermCount++;
	}
	ind.IndexLock.Unlock()
	runtime.Gosched()
}

// Adds new document entry to given term entry
func (ind *InvertedIndex) AddDocument(term string, document *DocumentEntry) {
	// Make sure term is in index
	ind.AddTerm(term)

	// Safely add document to term list
	ind.Terms[term].EntryLock.Lock()
	ind.Terms[term].Frequency += document.Frequency
	ind.Terms[term].Documents.PushBack(document)
	ind.Terms[term].EntryLock.Unlock()
	runtime.Gosched()
}<|endoftext|>