<commit_before>package lifecycle

import (
	"log"
	"os"
	"os/signal"
	"runtime"
	"sync"
	"syscall"
	"time"

	"github.com/fastly/go-utils/executable"
	"github.com/fastly/go-utils/stopper"
	"github.com/fastly/go-utils/vlog"
)

const traceSignal = syscall.SIGUSR1

// A Lifecycle manages some boilerplate for running daemons.
type Lifecycle struct {
	m           sync.Mutex
	interrupt   chan os.Signal
	fatalQuit   chan struct{}
	killFuncs   []func()
	uninstaller stopper.Stopper
}

// New creates a new Lifecycle. This should be called after validating
// parameters but before starting work or allocating external resources. A
// startup message is displayed and shutdown handlers for SIGINT and SIGTERM
// are registered.
//
// If New is passed 'true' for singleProcess, it will wait for existing duplicate
// processes to exit before returning.
func New(singleProcess bool) *Lifecycle {
	l := Lifecycle{
		interrupt:   make(chan os.Signal, 1),
		fatalQuit:   make(chan struct{}, 1),
		uninstaller: InstallStackTracer(),
	}

	// make sigint trigger a clean shutdown
	signal.Notify(l.interrupt, os.Interrupt)
	signal.Notify(l.interrupt, syscall.SIGTERM)
	signal.Notify(l.interrupt, syscall.SIGHUP)

	if singleProcess && executable.NowRunning() {
		vlog.VLogf("Waiting for existing %s processes to exit...", os.Args[0])
		for executable.NowRunning() {
			select {
			case <-l.interrupt:
				log.Fatalf("Aborting")
			case <-time.After(100 * time.Millisecond):
			}
		}
	}

	return &l
}

// RunWhenKilled blocks until a shutdown signal is received, then executes
// finalizer and only returns either after it has finished or another
// shutdown signal is received. If timeout is non-zero, RunWhenKilled will
// force shutdown if the finalizer cannot complete within the timeout duration.
//
// RunWhenKilled should only be called once with a master function to run
// on program shutdown.
//
// RunWhenKilled runs the finalizer before any deferred AddKillFunc functions.
// This is so that the finalizer can begin the shutdown process that any
// other AddKillFunc functions can rely on.
func (l *Lifecycle) RunWhenKilled(finalizer func(), timeout time.Duration) {
	vlog.VLogf("%s started", os.Args[0])
	select {
	case sig := <-l.interrupt:
		vlog.VLogf("Caught signal %q, shutting down", sig)
	case <-l.fatalQuit:
		vlog.VLogf("Caught fatal quit, shutting down")
	}

	defer l.uninstaller.Stop()

	// wait for either confirmation that we finished or another interrupt
	shutdown := make(chan struct{}, 1)
	go func() {
		if finalizer != nil {
			finalizer()
		}
		for i := len(l.killFuncs) - 1; i >= 0; i-- {
			l.killFuncs[i]()
		}
		close(shutdown)
	}()
	var t <-chan time.Time
	if timeout > 0 {
		t = time.After(timeout)
	}
	select {
	case <-shutdown:
		vlog.VLogf("Shutdown complete, goodbye")
		os.Exit(0)
	case <-t:
		vlog.VLogf("Shutdown timeout exceeded (%v)", timeout)
		os.Exit(1)
	case <-l.interrupt:
		vlog.VLogf("Second interrupt, exiting")
		os.Exit(1)
	}
}

// AddKillFunc will add f to the list of functions to be ran
// when the lifecycle is killed. Functions passed to AddKillFunc
// are ran in reverse order, much like defer. If the lifecycle
// is being killed ad the same time AddKillFunc is called, the
// passed function will not be called.
func (l *Lifecycle) AddKillFunc(f func()) {
	l.m.Lock()
	defer l.m.Unlock()
	l.killFuncs = append(l.killFuncs, f)
}

// FatalQuit will kill the lifecycle to continue into the RunWhenKilled function.
func (l *Lifecycle) FatalQuit() {
	l.fatalQuit <- struct{}{}
}

// for debugging, show goroutine trace on receipt of USR1. uninstall by calling
// Stop on the returned object
func InstallStackTracer() stopper.Stopper {
	signals := make(chan os.Signal, 1)
	signal.Notify(signals, traceSignal)
	stopper := stopper.NewChanStopper()
	go func() {
		defer func() {
			signal.Stop(signals)
			close(signals)
		}()
		for {
			select {
			case <-signals:
				log.Print(GetStackTrace(true))
			case <-stopper.Chan:
				return
			}
		}
	}()
	return stopper
}

// GetStackTrace returns a string containing the unabbreviated value of
// runtime.Stack(all). Be aware that this function may stop the world multiple
// times in order to obtain the full trace.
func GetStackTrace(all bool) string {
	b := make([]byte, 1<<10)
	for {
		if n := runtime.Stack(b, all); n < len(b) {
			return string(b[:n])
		}
		b = make([]byte, len(b)*2)
	}
}
<commit_msg>lifecycle: remove using uninstaller by default so that programs can use SIGUSR1<commit_after>package lifecycle

import (
	"log"
	"os"
	"os/signal"
	"runtime"
	"sync"
	"syscall"
	"time"

	"github.com/fastly/go-utils/executable"
	"github.com/fastly/go-utils/stopper"
	"github.com/fastly/go-utils/vlog"
)

const traceSignal = syscall.SIGUSR1

// A Lifecycle manages some boilerplate for running daemons.
type Lifecycle struct {
	m           sync.Mutex
	interrupt   chan os.Signal
	fatalQuit   chan struct{}
	killFuncs   []func()
}

// New creates a new Lifecycle. This should be called after validating
// parameters but before starting work or allocating external resources. A
// startup message is displayed and shutdown handlers for SIGINT and SIGTERM
// are registered.
//
// If New is passed 'true' for singleProcess, it will wait for existing duplicate
// processes to exit before returning.
func New(singleProcess bool) *Lifecycle {
	l := Lifecycle{
		interrupt:   make(chan os.Signal, 1),
		fatalQuit:   make(chan struct{}, 1),
	}

	// make sigint trigger a clean shutdown
	signal.Notify(l.interrupt, os.Interrupt)
	signal.Notify(l.interrupt, syscall.SIGTERM)
	signal.Notify(l.interrupt, syscall.SIGHUP)

	if singleProcess && executable.NowRunning() {
		vlog.VLogf("Waiting for existing %s processes to exit...", os.Args[0])
		for executable.NowRunning() {
			select {
			case <-l.interrupt:
				log.Fatalf("Aborting")
			case <-time.After(100 * time.Millisecond):
			}
		}
	}

	return &l
}

// RunWhenKilled blocks until a shutdown signal is received, then executes
// finalizer and only returns either after it has finished or another
// shutdown signal is received. If timeout is non-zero, RunWhenKilled will
// force shutdown if the finalizer cannot complete within the timeout duration.
//
// RunWhenKilled should only be called once with a master function to run
// on program shutdown.
//
// RunWhenKilled runs the finalizer before any deferred AddKillFunc functions.
// This is so that the finalizer can begin the shutdown process that any
// other AddKillFunc functions can rely on.
func (l *Lifecycle) RunWhenKilled(finalizer func(), timeout time.Duration) {
	vlog.VLogf("%s started", os.Args[0])
	select {
	case sig := <-l.interrupt:
		vlog.VLogf("Caught signal %q, shutting down", sig)
	case <-l.fatalQuit:
		vlog.VLogf("Caught fatal quit, shutting down")
	}

	// wait for either confirmation that we finished or another interrupt
	shutdown := make(chan struct{}, 1)
	go func() {
		if finalizer != nil {
			finalizer()
		}
		for i := len(l.killFuncs) - 1; i >= 0; i-- {
			l.killFuncs[i]()
		}
		close(shutdown)
	}()
	var t <-chan time.Time
	if timeout > 0 {
		t = time.After(timeout)
	}
	select {
	case <-shutdown:
		vlog.VLogf("Shutdown complete, goodbye")
		os.Exit(0)
	case <-t:
		vlog.VLogf("Shutdown timeout exceeded (%v)", timeout)
		os.Exit(1)
	case <-l.interrupt:
		vlog.VLogf("Second interrupt, exiting")
		os.Exit(1)
	}
}

// AddKillFunc will add f to the list of functions to be ran
// when the lifecycle is killed. Functions passed to AddKillFunc
// are ran in reverse order, much like defer. If the lifecycle
// is being killed ad the same time AddKillFunc is called, the
// passed function will not be called.
func (l *Lifecycle) AddKillFunc(f func()) {
	l.m.Lock()
	defer l.m.Unlock()
	l.killFuncs = append(l.killFuncs, f)
}

// FatalQuit will kill the lifecycle to continue into the RunWhenKilled function.
func (l *Lifecycle) FatalQuit() {
	l.fatalQuit <- struct{}{}
}

// for debugging, show goroutine trace on receipt of USR1. uninstall by calling
// Stop on the returned object
func InstallStackTracer() stopper.Stopper {
	signals := make(chan os.Signal, 1)
	signal.Notify(signals, traceSignal)
	stopper := stopper.NewChanStopper()
	go func() {
		defer func() {
			signal.Stop(signals)
			close(signals)
		}()
		for {
			select {
			case <-signals:
				log.Print(GetStackTrace(true))
			case <-stopper.Chan:
				return
			}
		}
	}()
	return stopper
}

// GetStackTrace returns a string containing the unabbreviated value of
// runtime.Stack(all). Be aware that this function may stop the world multiple
// times in order to obtain the full trace.
func GetStackTrace(all bool) string {
	b := make([]byte, 1<<10)
	for {
		if n := runtime.Stack(b, all); n < len(b) {
			return string(b[:n])
		}
		b = make([]byte, len(b)*2)
	}
}
<|endoftext|>


<commit_before>package boltqueue

import (
	"encoding/binary"
	"encoding/json"

	"github.com/DavidHuie/httpq/Godeps/_workspace/src/github.com/boltdb/bolt"
)

type BoltQueue struct {
	conn *bolt.DB
}

func NewBoltQueue(conn *bolt.DB) *BoltQueue {
	return &BoltQueue{conn}
}

type queueMetadata struct {
	Head uint64
	Last uint64
}

var (
	metadataBucketName = []byte("b")
	metadataKey        = []byte("m")
	dataBucketName     = []byte("d")
)

func getMetadata(b *bolt.Bucket) (*queueMetadata, error) {
	var metadata queueMetadata
	value := b.Get(metadataKey)

	// Create metadata if it doesn't exist
	if value == nil {
		metadata = queueMetadata{}
		bytes, err := json.Marshal(metadata)
		if err != nil {
			return nil, err
		}
		if err := b.Put(metadataKey, bytes); err != nil {
			return nil, err
		}
	} else {
		if err := json.Unmarshal(value, &metadata); err != nil {
			return nil, err
		}
	}

	return &metadata, nil
}

func (b *BoltQueue) Push(bytes []byte) error {
	return b.conn.Update(func(tx *bolt.Tx) error {
		mbucket, err := tx.CreateBucketIfNotExists(metadataBucketName)
		if err != nil {
			return err
		}
		dbucket, err := tx.CreateBucketIfNotExists(dataBucketName)
		if err != nil {
			return err
		}

		metadata, err := getMetadata(mbucket)
		if err != nil {
			return err
		}

		// Update metadata to reflect new data location
		metadata.Last += 1

		// Update recently initialized metadatas
		if metadata.Head == 0 {
			metadata.Head = 1
		}

		metadataBytes, err := json.Marshal(metadata)
		if err != nil {
			return err
		}
		if err := mbucket.Put(metadataKey, metadataBytes); err != nil {
			return err
		}

		// Push
		dataLocationBytes := make([]byte, 8)
		binary.PutUvarint(dataLocationBytes, metadata.Last)
		if err := dbucket.Put(dataLocationBytes, bytes); err != nil {
			return err
		}

		return nil
	})
}

func (b *BoltQueue) Pop() ([]byte, error) {
	var response []byte
	err := b.conn.Update(func(tx *bolt.Tx) error {
		mbucket, err := tx.CreateBucketIfNotExists(metadataBucketName)
		if err != nil {
			return err
		}
		dbucket, err := tx.CreateBucketIfNotExists(dataBucketName)
		if err != nil {
			return err
		}

		metadata, err := getMetadata(mbucket)
		if err != nil {
			return err
		}

		// Handle an empty queue
		if metadata.Head > metadata.Last {
			response = nil
			return nil
		}

		// Perform pop
		dataLocationBytes := make([]byte, 8)
		binary.PutUvarint(dataLocationBytes, metadata.Head)
		response = dbucket.Get(dataLocationBytes)
		if response == nil {
			return nil
		}
		if err := dbucket.Delete(dataLocationBytes); err != nil {
			return err
		}

		// Update metadata
		metadata.Head = metadata.Head + 1
		metadataBytes, err := json.Marshal(metadata)
		if err != nil {
			return err
		}
		if err := mbucket.Put(metadataKey, metadataBytes); err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return nil, err
	}

	return response, nil
}

func (b *BoltQueue) Size() (uint64, error) {
	var size uint64
	err := b.conn.Update(func(tx *bolt.Tx) error {
		mbucket, err := tx.CreateBucketIfNotExists(metadataBucketName)
		if err != nil {
			return err
		}
		metadata, err := getMetadata(mbucket)
		if err != nil {
			return err
		}

		if metadata.Head > metadata.Last {
			size = 0
			return nil
		}

		size = (metadata.Last - metadata.Head) + 1
		return nil
	})
	if err != nil {
		return 0, err
	}

	return size, nil
}
<commit_msg>Handle special case where metadata is new<commit_after>package boltqueue

import (
	"encoding/binary"
	"encoding/json"

	"github.com/DavidHuie/httpq/Godeps/_workspace/src/github.com/boltdb/bolt"
)

type BoltQueue struct {
	conn *bolt.DB
}

func NewBoltQueue(conn *bolt.DB) *BoltQueue {
	return &BoltQueue{conn}
}

type queueMetadata struct {
	Head uint64
	Last uint64
}

var (
	metadataBucketName = []byte("b")
	metadataKey        = []byte("m")
	dataBucketName     = []byte("d")
)

func getMetadata(b *bolt.Bucket) (*queueMetadata, error) {
	var metadata queueMetadata
	value := b.Get(metadataKey)

	// Create metadata if it doesn't exist
	if value == nil {
		metadata = queueMetadata{}
		bytes, err := json.Marshal(metadata)
		if err != nil {
			return nil, err
		}
		if err := b.Put(metadataKey, bytes); err != nil {
			return nil, err
		}
	} else {
		if err := json.Unmarshal(value, &metadata); err != nil {
			return nil, err
		}
	}

	return &metadata, nil
}

func (b *BoltQueue) Push(bytes []byte) error {
	return b.conn.Update(func(tx *bolt.Tx) error {
		mbucket, err := tx.CreateBucketIfNotExists(metadataBucketName)
		if err != nil {
			return err
		}
		dbucket, err := tx.CreateBucketIfNotExists(dataBucketName)
		if err != nil {
			return err
		}

		metadata, err := getMetadata(mbucket)
		if err != nil {
			return err
		}

		// Update metadata to reflect new data location
		metadata.Last += 1

		// Update recently initialized metadatas
		if metadata.Head == 0 {
			metadata.Head = 1
		}

		metadataBytes, err := json.Marshal(metadata)
		if err != nil {
			return err
		}
		if err := mbucket.Put(metadataKey, metadataBytes); err != nil {
			return err
		}

		// Push
		dataLocationBytes := make([]byte, 8)
		binary.PutUvarint(dataLocationBytes, metadata.Last)
		if err := dbucket.Put(dataLocationBytes, bytes); err != nil {
			return err
		}

		return nil
	})
}

func (b *BoltQueue) Pop() ([]byte, error) {
	var response []byte
	err := b.conn.Update(func(tx *bolt.Tx) error {
		mbucket, err := tx.CreateBucketIfNotExists(metadataBucketName)
		if err != nil {
			return err
		}
		dbucket, err := tx.CreateBucketIfNotExists(dataBucketName)
		if err != nil {
			return err
		}

		metadata, err := getMetadata(mbucket)
		if err != nil {
			return err
		}

		// Handle an empty queue
		if metadata.Head > metadata.Last {
			response = nil
			return nil
		}

		// Perform pop
		dataLocationBytes := make([]byte, 8)
		binary.PutUvarint(dataLocationBytes, metadata.Head)
		response = dbucket.Get(dataLocationBytes)
		if response == nil {
			return nil
		}
		if err := dbucket.Delete(dataLocationBytes); err != nil {
			return err
		}

		// Update metadata
		metadata.Head = metadata.Head + 1
		metadataBytes, err := json.Marshal(metadata)
		if err != nil {
			return err
		}
		if err := mbucket.Put(metadataKey, metadataBytes); err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return nil, err
	}

	return response, nil
}

func (b *BoltQueue) Size() (uint64, error) {
	var size uint64
	err := b.conn.Update(func(tx *bolt.Tx) error {
		mbucket, err := tx.CreateBucketIfNotExists(metadataBucketName)
		if err != nil {
			return err
		}
		metadata, err := getMetadata(mbucket)
		if err != nil {
			return err
		}

		if metadata.Head > metadata.Last {
			return nil
		}

		if metadata.Head == 0 && metadata.Last == 0 {
			return nil
		}

		size = (metadata.Last - metadata.Head) + 1
		return nil
	})
	if err != nil {
		return 0, err
	}

	return size, nil
}
<|endoftext|>


<commit_before>package pachyderm

import "go.pedge.io/proto/version"

const (
	// MajorVersion is the current major version for pachyderm.
	MajorVersion = 0
	// MinorVersion is the current minor version for pachyderm.
	MinorVersion = 10
	// MicroVersion is the current micro version for pachyderm.
	MicroVersion = 0
	// AdditionalVersion will be "dev" is this is a development branch, "" otherwise.
	AdditionalVersion = "dev"
)

var (
	// Version is the current version for pachyderm.
	Version = &protoversion.Version{
		Major:      MajorVersion,
		Minor:      MinorVersion,
		Micro:      MicroVersion,
		Additional: AdditionalVersion,
	}
)
<commit_msg>Bump additional version to RC1.<commit_after>package pachyderm

import "go.pedge.io/proto/version"

const (
	// MajorVersion is the current major version for pachyderm.
	MajorVersion = 0
	// MinorVersion is the current minor version for pachyderm.
	MinorVersion = 10
	// MicroVersion is the current micro version for pachyderm.
	MicroVersion = 0
	// AdditionalVersion will be "dev" is this is a development branch, "" otherwise.
	AdditionalVersion = "RC1"
)

var (
	// Version is the current version for pachyderm.
	Version = &protoversion.Version{
		Major:      MajorVersion,
		Minor:      MinorVersion,
		Micro:      MicroVersion,
		Additional: AdditionalVersion,
	}
)
<|endoftext|>


<commit_before>package router

import (
	"errors"
	"fmt"
	"regexp"
	"strings"
)

type Rule struct {
	router *Router
	path   string
	regexp *regexp.Regexp
	trace  []trace
	weight int
}

type trace struct {
	param bool
	name  string
}

var (
	ErrBound   = errors.New("rule already bound")
	ErrUnbound = errors.New("rule not bound")
)

var (
	ErrLeadingSlash      = errors.New("rules must begin with a leading slash")
	ErrVariableEmpty     = errors.New("variable must have a name")
	ErrVariableOpen      = errors.New("must surround variable with '<' and '>'")
	ErrVariableDuplicate = errors.New("duplicate variable name")
	ErrConverterOpen     = errors.New("must surround converter with '(' and ')'")
	ErrArguments         = errors.New("malformed key/value argument pairs")
)

func NewRule(path string) (*Rule, error) {
	if path == "" || path[0] != '/' {
		return nil, ErrLeadingSlash
	}
	return &Rule{path: path}, nil
}

func (r *Rule) bind(router *Router) error {
	if r.router != nil {
		return ErrBound
	}
	r.router = router
	return r.compile()
}

func (r *Rule) compile() error {
	var parts []string
	var names []string

	if r.router == nil {
		return ErrUnbound
	}

	for _, segment := range splitPath(r.path) {
		if segment[0] == '<' {
			name, converter, err := r.parseParam(segment)
			if err != nil {
				return err
			}

			for _, v := range names {
				if v == name {
					return ErrVariableDuplicate
				}
			}

			part := fmt.Sprintf(`(?P<%s>%s)`, name, converter.Regexp())
			parts = append(parts, part)
			names = append(names, name)

			r.trace = append(r.trace, trace{true, name})
			r.weight += converter.Weight()

			continue
		}

		part := regexp.QuoteMeta(segment)
		parts = append(parts, part)

		r.trace = append(r.trace, trace{false, segment})
		r.weight -= len(segment)
	}

	re := fmt.Sprintf(`^/%s$`, strings.Join(parts, "/"))
	r.regexp = regexp.MustCompile(re)

	return nil
}

func (r *Rule) match(path string) (map[string]interface{}, error) {
	return nil, nil
}

// Valid parameters are in the form:
//   <var>
//   <var:converter>
//   <var:converter(arg1=val1,arg2=val2,argx=valx)>
func (r *Rule) parseParam(param string) (string, Converter, error) {
	if len(param) < 3 {
		return "", nil, ErrVariableEmpty
	}

	if param[0] != '<' || param[len(param)-1] != '>' {
		return "", nil, ErrVariableOpen
	}

	param = param[1 : len(param)-1]
	parts := strings.SplitN(param, ":", 2)

	if len(parts) < 2 {
		parts = append(parts, "default")
	}

	key, args, err := r.parseConverter(parts[1])
	if err != nil {
		return "", nil, err
	}

	converter, ok := r.router.Converters[key]
	if !ok {
		converter = r.router.Converters["default"]
	}

	return parts[0], converter(args), nil
}

func (r *Rule) parseConverter(converter string) (string, map[string]string, error) {
	parts := strings.SplitN(converter, "(", 2)
	if len(parts) == 1 {
		return parts[0], nil, nil
	}

	name := parts[0]
	more := parts[1]

	if more == "" {
		return "", nil, ErrConverterOpen
	}

	last, arguments := more[len(more)-1], more[:len(more)-1]
	if strings.Contains(more, "(") || last != ')' {
		return "", nil, ErrConverterOpen
	}

	args, err := r.parseArguments(arguments)
	if err != nil {
		return "", nil, err
	}

	return name, args, nil
}

func (r *Rule) parseArguments(arguments string) (map[string]string, error) {
	args := make(map[string]string)
	if arguments == "" {
		return args, nil
	}

	if !strings.Contains(arguments, "=") {
		return nil, ErrArguments
	}

	parts := strings.Split(arguments, ",")
	for _, arg := range parts {
		pair := strings.Split(arg, "=")
		if len(pair) != 2 || pair[1] == "" {
			return nil, ErrArguments
		}

		key := pair[0]
		args[key] = pair[1]
	}

	return args, nil
}

func splitPath(path string) []string {
	parts := strings.Split(path, "/")
	if parts[0] == "" {
		parts = parts[1:]
	}
	if parts[len(parts)-1] == "" {
		parts = parts[:len(parts)-1]
	}
	return parts
}
<commit_msg>Rename trace part.<commit_after>package router

import (
	"errors"
	"fmt"
	"regexp"
	"strings"
)

type Rule struct {
	router *Router
	path   string
	regexp *regexp.Regexp
	trace  []trace
	weight int
}

type trace struct {
	param bool
	part  string
}

var (
	ErrBound   = errors.New("rule already bound")
	ErrUnbound = errors.New("rule not bound")
)

var (
	ErrLeadingSlash      = errors.New("rules must begin with a leading slash")
	ErrVariableEmpty     = errors.New("variable must have a name")
	ErrVariableOpen      = errors.New("must surround variable with '<' and '>'")
	ErrVariableDuplicate = errors.New("duplicate variable name")
	ErrConverterOpen     = errors.New("must surround converter with '(' and ')'")
	ErrArguments         = errors.New("malformed key/value argument pairs")
)

func NewRule(path string) (*Rule, error) {
	if path == "" || path[0] != '/' {
		return nil, ErrLeadingSlash
	}
	return &Rule{path: path}, nil
}

func (r *Rule) bind(router *Router) error {
	if r.router != nil {
		return ErrBound
	}
	r.router = router
	return r.compile()
}

func (r *Rule) compile() error {
	var parts []string
	var names []string

	if r.router == nil {
		return ErrUnbound
	}

	for _, segment := range splitPath(r.path) {
		if segment[0] == '<' {
			name, converter, err := r.parseParam(segment)
			if err != nil {
				return err
			}

			for _, v := range names {
				if v == name {
					return ErrVariableDuplicate
				}
			}

			part := fmt.Sprintf(`(?P<%s>%s)`, name, converter.Regexp())
			parts = append(parts, part)
			names = append(names, name)

			r.trace = append(r.trace, trace{true, name})
			r.weight += converter.Weight()

			continue
		}

		part := regexp.QuoteMeta(segment)
		parts = append(parts, part)

		r.trace = append(r.trace, trace{false, segment})
		r.weight -= len(segment)
	}

	re := fmt.Sprintf(`^/%s$`, strings.Join(parts, "/"))
	r.regexp = regexp.MustCompile(re)

	return nil
}

func (r *Rule) match(path string) (map[string]interface{}, error) {
	return nil, nil
}

// Valid parameters are in the form:
//   <var>
//   <var:converter>
//   <var:converter(arg1=val1,arg2=val2,argx=valx)>
func (r *Rule) parseParam(param string) (string, Converter, error) {
	if len(param) < 3 {
		return "", nil, ErrVariableEmpty
	}

	if param[0] != '<' || param[len(param)-1] != '>' {
		return "", nil, ErrVariableOpen
	}

	param = param[1 : len(param)-1]
	parts := strings.SplitN(param, ":", 2)

	if len(parts) < 2 {
		parts = append(parts, "default")
	}

	key, args, err := r.parseConverter(parts[1])
	if err != nil {
		return "", nil, err
	}

	converter, ok := r.router.Converters[key]
	if !ok {
		converter = r.router.Converters["default"]
	}

	return parts[0], converter(args), nil
}

func (r *Rule) parseConverter(converter string) (string, map[string]string, error) {
	parts := strings.SplitN(converter, "(", 2)
	if len(parts) == 1 {
		return parts[0], nil, nil
	}

	name := parts[0]
	more := parts[1]

	if more == "" {
		return "", nil, ErrConverterOpen
	}

	last, arguments := more[len(more)-1], more[:len(more)-1]
	if strings.Contains(more, "(") || last != ')' {
		return "", nil, ErrConverterOpen
	}

	args, err := r.parseArguments(arguments)
	if err != nil {
		return "", nil, err
	}

	return name, args, nil
}

func (r *Rule) parseArguments(arguments string) (map[string]string, error) {
	args := make(map[string]string)
	if arguments == "" {
		return args, nil
	}

	if !strings.Contains(arguments, "=") {
		return nil, ErrArguments
	}

	parts := strings.Split(arguments, ",")
	for _, arg := range parts {
		pair := strings.Split(arg, "=")
		if len(pair) != 2 || pair[1] == "" {
			return nil, ErrArguments
		}

		key := pair[0]
		args[key] = pair[1]
	}

	return args, nil
}

func splitPath(path string) []string {
	parts := strings.Split(path, "/")
	if parts[0] == "" {
		parts = parts[1:]
	}
	if parts[len(parts)-1] == "" {
		parts = parts[:len(parts)-1]
	}
	return parts
}
<|endoftext|>


<commit_before>package onvif

import (
	"bytes"
	"crypto/sha1"
	"encoding/base64"
	"errors"
	"io/ioutil"
	"net/http"
	"net/url"
	"regexp"
	"time"

	"github.com/clbanning/mxj"
	"github.com/satori/go.uuid"
)

var httpClient = &http.Client{Timeout: time.Second * 5}

// SOAP contains data for SOAP request
type SOAP struct {
	Body     string
	XMLNs    []string
	User     string
	Password string
	TokenAge time.Duration
}

// SendRequest sends SOAP request to xAddr
func (soap SOAP) SendRequest(xaddr string) (mxj.Map, error) {
	// Create SOAP request
	request := soap.createRequest()

	// Make sure URL valid and add authentication in xAddr
	urlXAddr, err := url.Parse(xaddr)
	if err != nil {
		return nil, err
	}

	if soap.User != "" {
		urlXAddr.User = url.UserPassword(soap.User, soap.Password)
	}

	// Create HTTP request
	buffer := bytes.NewBuffer([]byte(request))
	req, err := http.NewRequest("POST", urlXAddr.String(), buffer)
	req.Header.Set("Content-Type", "application/soap+xml")
	req.Header.Set("Charset", "utf-8")

	// Send request
	resp, err := httpClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	// Read response body
	responseBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	// Parse XML to map
	mapXML, err := mxj.NewMapXml(responseBody)
	if err != nil {
		return nil, err
	}

	// Check if SOAP returns fault
	fault, err := mapXML.ValueForPathString("Envelope.Body.Fault.Reason.Text.#text")
	if err != nil && fault != "" {
		return nil, errors.New(fault)
	}

	return mapXML, nil
}

func (soap SOAP) createRequest() string {
	// Create request envelope
	request := `<?xml version="1.0" encoding="UTF-8"?>`
	request += `<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"`

	// Set XML namespace
	for _, namespace := range soap.XMLNs {
		request += " " + namespace
	}
	request += ">"

	// Set request header
	if soap.User != "" {
		request += "<s:header>" + soap.createUserToken() + "</s:header>"
	}

	// Set request body
	request += "<s:Body>" + soap.Body + "</s:Body>"

	// Close request envelope
	request += "</s:Envelope>"

	// Clean request
	request = regexp.MustCompile(`\>\s+\<`).ReplaceAllString(request, "><")
	request = regexp.MustCompile(`\s+`).ReplaceAllString(request, " ")

	return request
}

func (soap SOAP) createUserToken() string {
	nonce := uuid.NewV4().Bytes()
	nonce64 := base64.StdEncoding.EncodeToString(nonce)
	timestamp := time.Now().Add(soap.TokenAge).UTC().Format(time.RFC3339)
	token := string(nonce) + timestamp + soap.Password

	sha := sha1.New()
	sha.Write([]byte(token))
	shaToken := sha.Sum(nil)
	shaDigest64 := base64.StdEncoding.EncodeToString(shaToken)

	return `<Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
  		<UsernameToken>
    		<Username>` + soap.User + `</Username>
    		<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">` + shaDigest64 + `</Password>
    		<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">` + nonce64 + `</Nonce>
    		<Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">` + timestamp + `</Created>
		</UsernameToken>
	</Security>`
}
<commit_msg>Check for error response<commit_after>package onvif

import (
	"bytes"
	"crypto/sha1"
	"encoding/base64"
	"errors"
	"io/ioutil"
	"net/http"
	"net/url"
	"regexp"
	"time"

	"github.com/clbanning/mxj"
	"github.com/satori/go.uuid"
)

var httpClient = &http.Client{Timeout: time.Second * 5}

// SOAP contains data for SOAP request
type SOAP struct {
	Body     string
	XMLNs    []string
	User     string
	Password string
	TokenAge time.Duration
}

// SendRequest sends SOAP request to xAddr
func (soap SOAP) SendRequest(xaddr string) (mxj.Map, error) {
	// Create SOAP request
	request := soap.createRequest()

	// Make sure URL valid and add authentication in xAddr
	urlXAddr, err := url.Parse(xaddr)
	if err != nil {
		return nil, err
	}

	if soap.User != "" {
		urlXAddr.User = url.UserPassword(soap.User, soap.Password)
	}

	// Create HTTP request
	buffer := bytes.NewBuffer([]byte(request))
	req, err := http.NewRequest("POST", urlXAddr.String(), buffer)
	req.Header.Set("Content-Type", "application/soap+xml")
	req.Header.Set("Charset", "utf-8")

	// Send request
	resp, err := httpClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	// Read response body
	responseBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	// Parse XML to map
	mapXML, err := mxj.NewMapXml(responseBody)
	if err != nil {
		return nil, err
	}

	// Check if SOAP returns fault
	fault, _ := mapXML.ValueForPathString("Envelope.Body.Fault.Reason.Text.#text")
	if fault != "" {
		return nil, errors.New(fault)
	}

	return mapXML, nil
}

func (soap SOAP) createRequest() string {
	// Create request envelope
	request := `<?xml version="1.0" encoding="UTF-8"?>`
	request += `<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"`

	// Set XML namespace
	for _, namespace := range soap.XMLNs {
		request += " " + namespace
	}
	request += ">"

	// Set request header
	if soap.User != "" {
		request += "<s:header>" + soap.createUserToken() + "</s:header>"
	}

	// Set request body
	request += "<s:Body>" + soap.Body + "</s:Body>"

	// Close request envelope
	request += "</s:Envelope>"

	// Clean request
	request = regexp.MustCompile(`\>\s+\<`).ReplaceAllString(request, "><")
	request = regexp.MustCompile(`\s+`).ReplaceAllString(request, " ")

	return request
}

func (soap SOAP) createUserToken() string {
	nonce := uuid.NewV4().Bytes()
	nonce64 := base64.StdEncoding.EncodeToString(nonce)
	timestamp := time.Now().Add(soap.TokenAge).UTC().Format(time.RFC3339)
	token := string(nonce) + timestamp + soap.Password

	sha := sha1.New()
	sha.Write([]byte(token))
	shaToken := sha.Sum(nil)
	shaDigest64 := base64.StdEncoding.EncodeToString(shaToken)

	return `<Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
  		<UsernameToken>
    		<Username>` + soap.User + `</Username>
    		<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">` + shaDigest64 + `</Password>
    		<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">` + nonce64 + `</Nonce>
    		<Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">` + timestamp + `</Created>
		</UsernameToken>
	</Security>`
}
<|endoftext|>


<commit_before>package raft

//------------------------------------------------------------------------------
//
// Typedefs
//
//------------------------------------------------------------------------------

type uint64Slice []uint64

//------------------------------------------------------------------------------
//
// Functions
//
//------------------------------------------------------------------------------

//--------------------------------------
// uint64
//--------------------------------------

func (p uint64Slice) Len() int           { return len(p) }
func (p uint64Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p uint64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
<commit_msg>sort the commitindex of peers in descending order<commit_after>package raft

//------------------------------------------------------------------------------
//
// Typedefs
//
//------------------------------------------------------------------------------

type uint64Slice []uint64

//------------------------------------------------------------------------------
//
// Functions
//
//------------------------------------------------------------------------------

//--------------------------------------
// uint64
//--------------------------------------

func (p uint64Slice) Len() int           { return len(p) }
func (p uint64Slice) Less(i, j int) bool { return p[i] > p[j] } // descending order
func (p uint64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
<|endoftext|>


<commit_before>// Copyright (c) 2013 ActiveState Software Inc. All rights reserved.

package tail

import (
	"bufio"
	"fmt"
	"github.com/ActiveState/tail/util"
	"github.com/ActiveState/tail/watch"
	"io"
	"io/ioutil"
	"launchpad.net/tomb"
	"log"
	"os"
	"time"
)

var (
	ErrStop = fmt.Errorf("tail should now stop")
)

type Line struct {
	Text string
	Time time.Time
	Err  error // Error from tail
}

// NewLine returns a Line with present time.
func NewLine(text string) *Line {
	return &Line{text, time.Now(), nil}
}

// SeekInfo represents arguments to `os.Seek`
type SeekInfo struct {
	Offset int64
	Whence int // os.SEEK_*
}

// Config is used to specify how a file must be tailed.
type Config struct {
	// File-specifc
	Location  *SeekInfo // Seek to this location before tailing
	ReOpen    bool      // Reopen recreated files (tail -F)
	MustExist bool      // Fail early if the file does not exist
	Poll      bool      // Poll for file changes instead of using inotify
	LimitRate int64     // Maximum read rate (lines per second)

	// Generic IO
	Follow      bool // Continue looking for new lines (tail -f)
	MaxLineSize int  // If non-zero, split longer lines into multiple lines

	// Logger, when nil, is set to tail.DefaultLogger
	// To disable logging: set field to tail.DiscardingLogger
	Logger *log.Logger
}

type Tail struct {
	Filename string
	Lines    chan *Line
	Config

	file    *os.File
	reader  *bufio.Reader
	watcher watch.FileWatcher
	changes *watch.FileChanges
	rateMon *RateMonitor

	tomb.Tomb // provides: Done, Kill, Dying
}

var (
	// DefaultLogger is used when Config.Logger == nil
	DefaultLogger = log.New(os.Stderr, "", log.LstdFlags)
	// DiscardingLogger can be used to disable logging output
	DiscardingLogger = log.New(ioutil.Discard, "", 0)
)

// TailFile begins tailing the file. Output stream is made available
// via the `Tail.Lines` channel. To handle errors during tailing,
// invoke the `Wait` or `Err` method after finishing reading from the
// `Lines` channel.
func TailFile(filename string, config Config) (*Tail, error) {
	if config.ReOpen && !config.Follow {
		util.Fatal("cannot set ReOpen without Follow.")
	}

	t := &Tail{
		Filename: filename,
		Lines:    make(chan *Line),
		Config:   config,
	}

	// when Logger was not specified in config, use default logger
	if t.Logger == nil {
		t.Logger = log.New(os.Stderr, "", log.LstdFlags)
	}

	t.rateMon = new(RateMonitor)

	if t.Poll {
		t.watcher = watch.NewPollingFileWatcher(filename)
	} else {
		t.watcher = watch.NewInotifyFileWatcher(filename)
	}

	if t.MustExist {
		var err error
		t.file, err = os.Open(t.Filename)
		if err != nil {
			return nil, err
		}
	}

	go t.tailFileSync()

	return t, nil
}

// Return the file's current position, like stdio's ftell().
// But this value is not very accurate.
// it may readed one line in the chan(tail.Lines),
// so it may lost one line.
func (tail *Tail) Tell() (offset int64, err error) {
	if tail.file == nil {
		return
	}
	offset, err = tail.file.Seek(0, os.SEEK_CUR)
	if err == nil {
		offset -= int64(tail.reader.Buffered())
	}
	return
}

// Stop stops the tailing activity.
func (tail *Tail) Stop() error {
	tail.Kill(nil)
	return tail.Wait()
}

func (tail *Tail) close() {
	close(tail.Lines)
	if tail.file != nil {
		tail.file.Close()
	}
}

func (tail *Tail) reopen() error {
	if tail.file != nil {
		tail.file.Close()
	}
	for {
		var err error
		tail.file, err = os.Open(tail.Filename)
		if err != nil {
			if os.IsNotExist(err) {
				tail.Logger.Printf("Waiting for %s to appear...", tail.Filename)
				if err := tail.watcher.BlockUntilExists(&tail.Tomb); err != nil {
					if err == tomb.ErrDying {
						return err
					}
					return fmt.Errorf("Failed to detect creation of %s: %s", tail.Filename, err)
				}
				continue
			}
			return fmt.Errorf("Unable to open file %s: %s", tail.Filename, err)
		}
		break
	}
	return nil
}

func (tail *Tail) readLine() ([]byte, error) {
	line, isPrefix, err := tail.reader.ReadLine()
	if !isPrefix || tail.MaxLineSize > 0 {
		return line, err
	}

	buf := append([]byte(nil), line...)
	for isPrefix && err == nil {
		line, isPrefix, err = tail.reader.ReadLine()
		buf = append(buf, line...)
	}
	return buf, err
}

func (tail *Tail) tailFileSync() {
	defer tail.Done()
	defer tail.close()

	if !tail.MustExist {
		// deferred first open.
		err := tail.reopen()
		if err != nil {
			if err != tomb.ErrDying {
				tail.Kill(err)
			}
			return
		}
	}

	// Seek to requested location on first open of the file.
	if tail.Location != nil {
		_, err := tail.file.Seek(tail.Location.Offset, tail.Location.Whence)
		tail.Logger.Printf("Seeked %s - %+v\n", tail.Filename, tail.Location)
		if err != nil {
			tail.Killf("Seek error on %s: %s", tail.Filename, err)
			return
		}
	}

	tail.reader = tail.newReader()

	// Read line by line.
	for {
		line, err := tail.readLine()

		switch err {
		case nil:
			if line != nil {
				cooloff := !tail.sendLine(line)
				if cooloff {
					// Wait a second before seeking till the end of
					// file when rate limit is reached.
					msg := fmt.Sprintf(
						"Too much log activity (more than %d lines "+
							"per second being written); waiting a second "+
							"before resuming tailing", tail.LimitRate)
					tail.Lines <- &Line{msg, time.Now(), fmt.Errorf(msg)}
					select {
					case <-time.After(time.Second):
					case <-tail.Dying():
						return
					}
					_, err := tail.file.Seek(0, 2) // Seek to fine end
					if err != nil {
						tail.Killf("Seek error on %s: %s", tail.Filename, err)
						return
					}
				}
			}
		case io.EOF:
			if !tail.Follow {
				return
			}
			// When EOF is reached, wait for more data to become
			// available. Wait strategy is based on the `tail.watcher`
			// implementation (inotify or polling).
			err := tail.waitForChanges()
			if err != nil {
				if err != ErrStop {
					tail.Kill(err)
				}
				return
			}
		default: // non-EOF error
			tail.Killf("Error reading %s: %s", tail.Filename, err)
			return
		}

		select {
		case <-tail.Dying():
			return
		default:
		}
	}
}

// waitForChanges waits until the file has been appended, deleted,
// moved or truncated. When moved or deleted - the file will be
// reopened if ReOpen is true. Truncated files are always reopened.
func (tail *Tail) waitForChanges() error {
	if tail.changes == nil {
		st, err := tail.file.Stat()
		if err != nil {
			return err
		}
		tail.changes = tail.watcher.ChangeEvents(&tail.Tomb, st)
	}

	select {
	case <-tail.changes.Modified:
		return nil
	case <-tail.changes.Deleted:
		tail.changes = nil
		if tail.ReOpen {
			// XXX: we must not log from a library.
			tail.Logger.Printf("Re-opening moved/deleted file %s ...", tail.Filename)
			if err := tail.reopen(); err != nil {
				return err
			}
			tail.Logger.Printf("Successfully reopened %s", tail.Filename)
			tail.reader = tail.newReader()
			return nil
		} else {
			tail.Logger.Printf("Stopping tail as file no longer exists: %s", tail.Filename)
			return ErrStop
		}
	case <-tail.changes.Truncated:
		// Always reopen truncated files (Follow is true)
		tail.Logger.Printf("Re-opening truncated file %s ...", tail.Filename)
		if err := tail.reopen(); err != nil {
			return err
		}
		tail.Logger.Printf("Successfully reopened truncated %s", tail.Filename)
		tail.reader = tail.newReader()
		return nil
	case <-tail.Dying():
		return ErrStop
	}
	panic("unreachable")
}

func (tail *Tail) newReader() *bufio.Reader {
	if tail.MaxLineSize > 0 {
		return bufio.NewReaderSize(tail.file, tail.MaxLineSize+2)
	} else {
		return bufio.NewReader(tail.file)
	}
}

// sendLine sends the line(s) to Lines channel, splitting longer lines
// if necessary. Return false if rate limit is reached.
func (tail *Tail) sendLine(line []byte) bool {
	now := time.Now()
	nowUnix := now.Unix()
	lines := []string{string(line)}

	// Split longer lines
	if tail.MaxLineSize > 0 && len(line) > tail.MaxLineSize {
		lines = util.PartitionString(
			string(line), tail.MaxLineSize)
	}

	for _, line := range lines {
		tail.Lines <- &Line{line, now, nil}
		rate := tail.rateMon.Tick(nowUnix)
		if tail.LimitRate > 0 && rate > tail.LimitRate {
			tail.Logger.Printf("Rate limit (%v < %v) reached on file (%v); entering 1s cooloff period.\n",
				tail.LimitRate,
				rate,
				tail.Filename)
			return false
		}
	}

	return true
}

// Cleanup removes inotify watches added by the tail package. This function is
// meant to be invoked from a process's exit handler. Linux kernel may not
// automatically remove inotify watches after the process exits.
func Cleanup() {
	watch.Cleanup()
}
<commit_msg>explain what the +2 is for /<commit_after>// Copyright (c) 2013 ActiveState Software Inc. All rights reserved.

package tail

import (
	"bufio"
	"fmt"
	"github.com/ActiveState/tail/util"
	"github.com/ActiveState/tail/watch"
	"io"
	"io/ioutil"
	"launchpad.net/tomb"
	"log"
	"os"
	"time"
)

var (
	ErrStop = fmt.Errorf("tail should now stop")
)

type Line struct {
	Text string
	Time time.Time
	Err  error // Error from tail
}

// NewLine returns a Line with present time.
func NewLine(text string) *Line {
	return &Line{text, time.Now(), nil}
}

// SeekInfo represents arguments to `os.Seek`
type SeekInfo struct {
	Offset int64
	Whence int // os.SEEK_*
}

// Config is used to specify how a file must be tailed.
type Config struct {
	// File-specifc
	Location  *SeekInfo // Seek to this location before tailing
	ReOpen    bool      // Reopen recreated files (tail -F)
	MustExist bool      // Fail early if the file does not exist
	Poll      bool      // Poll for file changes instead of using inotify
	LimitRate int64     // Maximum read rate (lines per second)

	// Generic IO
	Follow      bool // Continue looking for new lines (tail -f)
	MaxLineSize int  // If non-zero, split longer lines into multiple lines

	// Logger, when nil, is set to tail.DefaultLogger
	// To disable logging: set field to tail.DiscardingLogger
	Logger *log.Logger
}

type Tail struct {
	Filename string
	Lines    chan *Line
	Config

	file    *os.File
	reader  *bufio.Reader
	watcher watch.FileWatcher
	changes *watch.FileChanges
	rateMon *RateMonitor

	tomb.Tomb // provides: Done, Kill, Dying
}

var (
	// DefaultLogger is used when Config.Logger == nil
	DefaultLogger = log.New(os.Stderr, "", log.LstdFlags)
	// DiscardingLogger can be used to disable logging output
	DiscardingLogger = log.New(ioutil.Discard, "", 0)
)

// TailFile begins tailing the file. Output stream is made available
// via the `Tail.Lines` channel. To handle errors during tailing,
// invoke the `Wait` or `Err` method after finishing reading from the
// `Lines` channel.
func TailFile(filename string, config Config) (*Tail, error) {
	if config.ReOpen && !config.Follow {
		util.Fatal("cannot set ReOpen without Follow.")
	}

	t := &Tail{
		Filename: filename,
		Lines:    make(chan *Line),
		Config:   config,
	}

	// when Logger was not specified in config, use default logger
	if t.Logger == nil {
		t.Logger = log.New(os.Stderr, "", log.LstdFlags)
	}

	t.rateMon = new(RateMonitor)

	if t.Poll {
		t.watcher = watch.NewPollingFileWatcher(filename)
	} else {
		t.watcher = watch.NewInotifyFileWatcher(filename)
	}

	if t.MustExist {
		var err error
		t.file, err = os.Open(t.Filename)
		if err != nil {
			return nil, err
		}
	}

	go t.tailFileSync()

	return t, nil
}

// Return the file's current position, like stdio's ftell().
// But this value is not very accurate.
// it may readed one line in the chan(tail.Lines),
// so it may lost one line.
func (tail *Tail) Tell() (offset int64, err error) {
	if tail.file == nil {
		return
	}
	offset, err = tail.file.Seek(0, os.SEEK_CUR)
	if err == nil {
		offset -= int64(tail.reader.Buffered())
	}
	return
}

// Stop stops the tailing activity.
func (tail *Tail) Stop() error {
	tail.Kill(nil)
	return tail.Wait()
}

func (tail *Tail) close() {
	close(tail.Lines)
	if tail.file != nil {
		tail.file.Close()
	}
}

func (tail *Tail) reopen() error {
	if tail.file != nil {
		tail.file.Close()
	}
	for {
		var err error
		tail.file, err = os.Open(tail.Filename)
		if err != nil {
			if os.IsNotExist(err) {
				tail.Logger.Printf("Waiting for %s to appear...", tail.Filename)
				if err := tail.watcher.BlockUntilExists(&tail.Tomb); err != nil {
					if err == tomb.ErrDying {
						return err
					}
					return fmt.Errorf("Failed to detect creation of %s: %s", tail.Filename, err)
				}
				continue
			}
			return fmt.Errorf("Unable to open file %s: %s", tail.Filename, err)
		}
		break
	}
	return nil
}

func (tail *Tail) readLine() ([]byte, error) {
	line, isPrefix, err := tail.reader.ReadLine()
	if !isPrefix || tail.MaxLineSize > 0 {
		return line, err
	}

	buf := append([]byte(nil), line...)
	for isPrefix && err == nil {
		line, isPrefix, err = tail.reader.ReadLine()
		buf = append(buf, line...)
	}
	return buf, err
}

func (tail *Tail) tailFileSync() {
	defer tail.Done()
	defer tail.close()

	if !tail.MustExist {
		// deferred first open.
		err := tail.reopen()
		if err != nil {
			if err != tomb.ErrDying {
				tail.Kill(err)
			}
			return
		}
	}

	// Seek to requested location on first open of the file.
	if tail.Location != nil {
		_, err := tail.file.Seek(tail.Location.Offset, tail.Location.Whence)
		tail.Logger.Printf("Seeked %s - %+v\n", tail.Filename, tail.Location)
		if err != nil {
			tail.Killf("Seek error on %s: %s", tail.Filename, err)
			return
		}
	}

	tail.reader = tail.newReader()

	// Read line by line.
	for {
		line, err := tail.readLine()

		switch err {
		case nil:
			if line != nil {
				cooloff := !tail.sendLine(line)
				if cooloff {
					// Wait a second before seeking till the end of
					// file when rate limit is reached.
					msg := fmt.Sprintf(
						"Too much log activity (more than %d lines "+
							"per second being written); waiting a second "+
							"before resuming tailing", tail.LimitRate)
					tail.Lines <- &Line{msg, time.Now(), fmt.Errorf(msg)}
					select {
					case <-time.After(time.Second):
					case <-tail.Dying():
						return
					}
					_, err := tail.file.Seek(0, 2) // Seek to fine end
					if err != nil {
						tail.Killf("Seek error on %s: %s", tail.Filename, err)
						return
					}
				}
			}
		case io.EOF:
			if !tail.Follow {
				return
			}
			// When EOF is reached, wait for more data to become
			// available. Wait strategy is based on the `tail.watcher`
			// implementation (inotify or polling).
			err := tail.waitForChanges()
			if err != nil {
				if err != ErrStop {
					tail.Kill(err)
				}
				return
			}
		default: // non-EOF error
			tail.Killf("Error reading %s: %s", tail.Filename, err)
			return
		}

		select {
		case <-tail.Dying():
			return
		default:
		}
	}
}

// waitForChanges waits until the file has been appended, deleted,
// moved or truncated. When moved or deleted - the file will be
// reopened if ReOpen is true. Truncated files are always reopened.
func (tail *Tail) waitForChanges() error {
	if tail.changes == nil {
		st, err := tail.file.Stat()
		if err != nil {
			return err
		}
		tail.changes = tail.watcher.ChangeEvents(&tail.Tomb, st)
	}

	select {
	case <-tail.changes.Modified:
		return nil
	case <-tail.changes.Deleted:
		tail.changes = nil
		if tail.ReOpen {
			// XXX: we must not log from a library.
			tail.Logger.Printf("Re-opening moved/deleted file %s ...", tail.Filename)
			if err := tail.reopen(); err != nil {
				return err
			}
			tail.Logger.Printf("Successfully reopened %s", tail.Filename)
			tail.reader = tail.newReader()
			return nil
		} else {
			tail.Logger.Printf("Stopping tail as file no longer exists: %s", tail.Filename)
			return ErrStop
		}
	case <-tail.changes.Truncated:
		// Always reopen truncated files (Follow is true)
		tail.Logger.Printf("Re-opening truncated file %s ...", tail.Filename)
		if err := tail.reopen(); err != nil {
			return err
		}
		tail.Logger.Printf("Successfully reopened truncated %s", tail.Filename)
		tail.reader = tail.newReader()
		return nil
	case <-tail.Dying():
		return ErrStop
	}
	panic("unreachable")
}

func (tail *Tail) newReader() *bufio.Reader {
	if tail.MaxLineSize > 0 {
		// add 2 to account for newline characters
		return bufio.NewReaderSize(tail.file, tail.MaxLineSize+2)
	} else {
		return bufio.NewReader(tail.file)
	}
}

// sendLine sends the line(s) to Lines channel, splitting longer lines
// if necessary. Return false if rate limit is reached.
func (tail *Tail) sendLine(line []byte) bool {
	now := time.Now()
	nowUnix := now.Unix()
	lines := []string{string(line)}

	// Split longer lines
	if tail.MaxLineSize > 0 && len(line) > tail.MaxLineSize {
		lines = util.PartitionString(
			string(line), tail.MaxLineSize)
	}

	for _, line := range lines {
		tail.Lines <- &Line{line, now, nil}
		rate := tail.rateMon.Tick(nowUnix)
		if tail.LimitRate > 0 && rate > tail.LimitRate {
			tail.Logger.Printf("Rate limit (%v < %v) reached on file (%v); entering 1s cooloff period.\n",
				tail.LimitRate,
				rate,
				tail.Filename)
			return false
		}
	}

	return true
}

// Cleanup removes inotify watches added by the tail package. This function is
// meant to be invoked from a process's exit handler. Linux kernel may not
// automatically remove inotify watches after the process exits.
func Cleanup() {
	watch.Cleanup()
}
<|endoftext|>


<commit_before>package main

import "fmt"

func main() { fmt.Println("Hello Word") }
<commit_msg>removed test.go<commit_after><|endoftext|>


<commit_before>package registration

import (
	"bufio"
	"errors"
	"fmt"
	"os"
	"os/signal"
	"strings"
	"time"

	"github.com/koding/kite"
	"github.com/koding/kite/config"
	"github.com/koding/kite/kitekey"
	"github.com/koding/klient/protocol"
)

// WithPassword registers with the username to the given kontrolURL via the users password
func WithPassword(kontrolURL, username string) error {
	var err error

	// Open up a prompt if the username is not passed via a flag
	if username == "" {
		username, err = ask("Username:")
		if err != nil {
			return err
		}
		// User can just press enter to use the default on the prompt
		if username == "" {
			return errors.New("Username can not be empty.")
		}
	}

	k := kite.New("klient", protocol.Version)
	k.Config.Environment = protocol.Environment
	k.Config.Region = protocol.Region
	k.Config.Username = username

	// Production Koding servers are only working over HTTP
	k.Config.Transport = config.XHRPolling

	// Give a warning if an existing kite.key exists
	if _, err := kitekey.Read(); err == nil {
		result, err := ask("An existing ~/.kite/kite.key detected. Type 'yes' to override and continue:")
		if err != nil {
			return err
		}

		if result != "yes" {
			return errors.New("aborting registration")
		}
	}

	kontrol := k.NewClient(kontrolURL)
	if err := kontrol.Dial(); err != nil {
		return err
	}

	// This causes Kontrol to execute the 'kite.getPass' method (builtin method
	// in the Kite library) on our own local kite (the one we declared above)
	// method bidirectional. So once we execute this, we immediately get a
	// prompt asking for our password, which is then transfered back to
	// Kontrol.
	result, err := kontrol.TellWithTimeout("registerMachine", 5*time.Minute, username)
	if err != nil {
		return err
	}

	// If the password is correct a valid and signed `kite.key` is returned
	// back. We go and create/override the ~/.kite/kite.key with this content.
	if err := kitekey.Write(result.MustString()); err != nil {
		return err
	}

	fmt.Println("Registered successfully")
	return nil
}

// ask asks for an input from standard input and returns the result back. It is
// extracted from mitcellh/cli to be used as a standalone function.
func ask(query string) (string, error) {
	if _, err := fmt.Fprint(os.Stdout, query+" "); err != nil {
		return "", err
	}

	// Register for interrupts so that we can catch it and immediately
	// return...
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, os.Interrupt)
	defer signal.Stop(sigCh)

	// Ask for input in a go-routine so that we can ignore it.
	errCh := make(chan error, 1)
	lineCh := make(chan string, 1)
	go func() {
		r := bufio.NewReader(os.Stdin)
		line, err := r.ReadString('\n')
		if err != nil {
			errCh <- err
			return
		}

		lineCh <- strings.TrimRight(line, "\r\n")
	}()

	select {
	case err := <-errCh:
		return "", err
	case line := <-lineCh:
		return line, nil
	case <-sigCh:
		// Print a newline so that any further output starts properly
		// on a new line.
		fmt.Fprintln(os.Stdout)

		return "", errors.New("interrupted")
	}
}
<commit_msg>registration: use vendored kite<commit_after>package registration

import (
	"bufio"
	"errors"
	"fmt"
	"os"
	"os/signal"
	"strings"
	"time"

	"github.com/koding/klient/Godeps/_workspace/src/github.com/koding/kite"
	"github.com/koding/klient/Godeps/_workspace/src/github.com/koding/kite/config"
	"github.com/koding/klient/Godeps/_workspace/src/github.com/koding/kite/kitekey"
	"github.com/koding/klient/protocol"
)

// WithPassword registers with the username to the given kontrolURL via the users password
func WithPassword(kontrolURL, username string) error {
	var err error

	// Open up a prompt if the username is not passed via a flag
	if username == "" {
		username, err = ask("Username:")
		if err != nil {
			return err
		}
		// User can just press enter to use the default on the prompt
		if username == "" {
			return errors.New("Username can not be empty.")
		}
	}

	k := kite.New("klient", protocol.Version)
	k.Config.Environment = protocol.Environment
	k.Config.Region = protocol.Region
	k.Config.Username = username

	// Production Koding servers are only working over HTTP
	k.Config.Transport = config.XHRPolling

	// Give a warning if an existing kite.key exists
	if _, err := kitekey.Read(); err == nil {
		result, err := ask("An existing ~/.kite/kite.key detected. Type 'yes' to override and continue:")
		if err != nil {
			return err
		}

		if result != "yes" {
			return errors.New("aborting registration")
		}
	}

	kontrol := k.NewClient(kontrolURL)
	if err := kontrol.Dial(); err != nil {
		return err
	}

	// This causes Kontrol to execute the 'kite.getPass' method (builtin method
	// in the Kite library) on our own local kite (the one we declared above)
	// method bidirectional. So once we execute this, we immediately get a
	// prompt asking for our password, which is then transfered back to
	// Kontrol.
	result, err := kontrol.TellWithTimeout("registerMachine", 5*time.Minute, username)
	if err != nil {
		return err
	}

	// If the password is correct a valid and signed `kite.key` is returned
	// back. We go and create/override the ~/.kite/kite.key with this content.
	if err := kitekey.Write(result.MustString()); err != nil {
		return err
	}

	fmt.Println("Registered successfully")
	return nil
}

// ask asks for an input from standard input and returns the result back. It is
// extracted from mitcellh/cli to be used as a standalone function.
func ask(query string) (string, error) {
	if _, err := fmt.Fprint(os.Stdout, query+" "); err != nil {
		return "", err
	}

	// Register for interrupts so that we can catch it and immediately
	// return...
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, os.Interrupt)
	defer signal.Stop(sigCh)

	// Ask for input in a go-routine so that we can ignore it.
	errCh := make(chan error, 1)
	lineCh := make(chan string, 1)
	go func() {
		r := bufio.NewReader(os.Stdin)
		line, err := r.ReadString('\n')
		if err != nil {
			errCh <- err
			return
		}

		lineCh <- strings.TrimRight(line, "\r\n")
	}()

	select {
	case err := <-errCh:
		return "", err
	case line := <-lineCh:
		return line, nil
	case <-sigCh:
		// Print a newline so that any further output starts properly
		// on a new line.
		fmt.Fprintln(os.Stdout)

		return "", errors.New("interrupted")
	}
}
<|endoftext|>


<commit_before>package yalzo

import (
	"io"
	"strconv"
)

type TodoList struct {
	todos  []Todo
	archs  []Todo
	labels []string
	reader io.Reader
}

type Todo struct {
	label      string
	title      string
	isArchived bool
	no         int
}

type Tab int

const (
	TODO Tab = iota
	ARCHIVE
)

func (t Tab) String() string {
	switch t {
	case TODO:
		return "Todo"
	case ARCHIVE:
		return "Archive"
	}
	return "Unknown"
}

func NewTodoList(r io.Reader, ls []string) *TodoList {
	l, as, err := ReadCSV(r)
	if err != nil {
		panic(err)
	}

	return &TodoList{
		todos:  l,
		archs:  as,
		labels: ls,
		reader: r,
	}
}

func (tl *TodoList) GetList(width int, tab Tab) []string {
	lines := make([]string, 0, 100)
	lists := tl.getListInTab(tab)
	for i := 0; i < len(lists); i++ {
		lines = append(lines, lists[i].tolimitStr(width))
	}
	return lines
}

func (tl *TodoList) GetLabels() []string {
	for i := 0; i < len(tl.todos); i++ {
		label := tl.todos[i].label
		if !tl.existLabel(label) && label != "" {
			tl.labels = append(tl.labels, label)
		}
	}

	for i := 0; i < len(tl.archs); i++ {
		label := tl.archs[i].label
		if !tl.existLabel(label) && label != "" {
			tl.labels = append(tl.labels, label)
		}
	}

	return tl.labels
}

func (tl *TodoList) ChangeTitle(i int, t string, tab Tab) {
	switch tab {
	case TODO:
		(*tl).todos[i].title = t
	case ARCHIVE:
		(*tl).archs[i].title = t
	}
}

func (tl *TodoList) ChangeLabelName(i int, l string, tab Tab) {
	switch tab {
	case TODO:
		(*tl).todos[i].label = l
	case ARCHIVE:
		(*tl).archs[i].label = l
	}
}

func (tl *TodoList) Delete(n int) {
	for i := n; i < len((*tl).todos); i++ {
		(*tl).todos[i].setNumber(i)
	}
	tl.todos = append(tl.todos[:n], tl.todos[n+1:]...)
}

func (tl *TodoList) AddTodo(t string) {
	tl.todos = append(tl.todos, Todo{
		no:    len(tl.todos) + 1,
		label: "",
		title: t,
	})
}

func (tl *TodoList) MoveArchive(n int) {
	length := len(tl.todos)
	tl.todos[n].isArchived = true
	tl.todos[n].setNumber(length)
	tl.archs = append(tl.archs, tl.todos[n])
	for i := n + 1; i < len(tl.todos); i++ {
		tl.todos[i].setNumber(i - 1)
	}
	tl.todos = append(tl.todos[:n], tl.todos[n+1:]...)
}

func (tl *TodoList) MoveTodo(n int) {
	length := len(tl.todos)
	tl.archs[n].isArchived = false
	tl.archs[n].setNumber(length)
	tl.todos = append(tl.todos, tl.archs[n])
	for i := n + 1; i < length; i++ {
		tl.todos[i].setNumber(i - 1)
	}
	tl.archs = append(tl.archs[:n], tl.archs[n+1:]...)
}

func (tl *TodoList) Exchange(i1 int, i2 int) {
	(*tl).todos[i2].setNumber(i1 + 1)
	(*tl).todos[i1].setNumber(i2 + 1)

	(*tl).todos[i2], (*tl).todos[i1] = (*tl).todos[i1], (*tl).todos[i2]
}

func (t *Todo) setNumber(n int) {
	(*t).no = n
}

func (tl *TodoList) existLabel(l string) bool {
	for i := 0; i < len(tl.labels); i++ {
		if tl.labels[i] == l {
			return true
		}
	}
	return false
}

func (tl *TodoList) getListInTab(tab Tab) []Todo {
	switch tab {
	case ARCHIVE:
		return tl.archs
	case TODO:
		return tl.todos
	}
	return []Todo{}
}

func (t *Todo) tolimitStr(limit int) string {
	str := strconv.Itoa(t.no) + " [ " + t.label + " ] " + t.title
	length := len(str)
	if length > limit {
		return str[:limit]
	} else {
		return str
	}
}
<commit_msg>space paddingを追加<commit_after>package yalzo

import (
	"fmt"
	"io"
	"strconv"
)

type TodoList struct {
	todos  []Todo
	archs  []Todo
	labels []string
	reader io.Reader
}

type Todo struct {
	label      string
	title      string
	isArchived bool
	no         int
}

type Tab int

const (
	TODO Tab = iota
	ARCHIVE
)

func (t Tab) String() string {
	switch t {
	case TODO:
		return "Todo"
	case ARCHIVE:
		return "Archive"
	}
	return "Unknown"
}

func NewTodoList(r io.Reader, ls []string) *TodoList {
	l, as, err := ReadCSV(r)
	if err != nil {
		panic(err)
	}

	return &TodoList{
		todos:  l,
		archs:  as,
		labels: ls,
		reader: r,
	}
}

func (tl *TodoList) GetList(width int, tab Tab) []string {
	lines := make([]string, 0, 100)
	lists := tl.getListInTab(tab)
	for i := 0; i < len(lists); i++ {
		lines = append(lines, lists[i].tolimitStr(width))
	}
	return lines
}

func (tl *TodoList) GetLabels() []string {
	for i := 0; i < len(tl.todos); i++ {
		label := tl.todos[i].label
		if !tl.existLabel(label) && label != "" {
			tl.labels = append(tl.labels, label)
		}
	}

	for i := 0; i < len(tl.archs); i++ {
		label := tl.archs[i].label
		if !tl.existLabel(label) && label != "" {
			tl.labels = append(tl.labels, label)
		}
	}

	return tl.labels
}

func (tl *TodoList) ChangeTitle(i int, t string, tab Tab) {
	switch tab {
	case TODO:
		(*tl).todos[i].title = t
	case ARCHIVE:
		(*tl).archs[i].title = t
	}
}

func (tl *TodoList) ChangeLabelName(i int, l string, tab Tab) {
	switch tab {
	case TODO:
		(*tl).todos[i].label = l
	case ARCHIVE:
		(*tl).archs[i].label = l
	}
}

func (tl *TodoList) Delete(n int) {
	for i := n; i < len((*tl).todos); i++ {
		(*tl).todos[i].setNumber(i)
	}
	tl.todos = append(tl.todos[:n], tl.todos[n+1:]...)
}

func (tl *TodoList) AddTodo(t string) {
	tl.todos = append(tl.todos, Todo{
		no:    len(tl.todos) + 1,
		label: "",
		title: t,
	})
}

func (tl *TodoList) MoveArchive(n int) {
	length := len(tl.todos)
	tl.todos[n].isArchived = true
	tl.todos[n].setNumber(length)
	tl.archs = append(tl.archs, tl.todos[n])
	for i := n + 1; i < len(tl.todos); i++ {
		tl.todos[i].setNumber(i - 1)
	}
	tl.todos = append(tl.todos[:n], tl.todos[n+1:]...)
}

func (tl *TodoList) MoveTodo(n int) {
	length := len(tl.todos)
	tl.archs[n].isArchived = false
	tl.archs[n].setNumber(length)
	tl.todos = append(tl.todos, tl.archs[n])
	for i := n + 1; i < length; i++ {
		tl.todos[i].setNumber(i - 1)
	}
	tl.archs = append(tl.archs[:n], tl.archs[n+1:]...)
}

func (tl *TodoList) Exchange(i1 int, i2 int) {
	(*tl).todos[i2].setNumber(i1 + 1)
	(*tl).todos[i1].setNumber(i2 + 1)

	(*tl).todos[i2], (*tl).todos[i1] = (*tl).todos[i1], (*tl).todos[i2]
}

func (t *Todo) setNumber(n int) {
	(*t).no = n
}

func (tl *TodoList) existLabel(l string) bool {
	for i := 0; i < len(tl.labels); i++ {
		if tl.labels[i] == l {
			return true
		}
	}
	return false
}

func (tl *TodoList) getListInTab(tab Tab) []Todo {
	switch tab {
	case ARCHIVE:
		return tl.archs
	case TODO:
		return tl.todos
	}
	return []Todo{}
}

func (t *Todo) tolimitStr(limit int) string {
	num_s := fmt.Sprintf("%3d", t.no)
	label_s := fmt.Sprintf("%20s", t.label)
	str := num_s + " [ " + label_s + " ] " + t.title
	length := len(str)
	if length > limit {
		return str[:limit]
	} else {
		return str
	}
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"html"
	"html/template"
	"log"
	"net/http"

	"golang.org/x/crypto/bcrypt"

	"github.com/dchest/uniuri"
	"github.com/gorilla/mux"
)

const (
	PORT   = ":8080"
	LENGTH = 12
)

var templates = template.Must(template.ParseFiles("static/index.html", "static/login.html", "static/register.html", "static/todo.html", "static/edit.html", "static/add.html"))

type User struct {
	ID       int
	Email    string
	Password string
}

type Tasks struct {
	ID      int    `json:"id"`
	Title   string `json:"title"`
	Task    string `json:"task"`
	Created string `json:"created"`
	DueDate string `json:"duedate"`
	Email   string `json:"email"`
}

type Page struct {
	Tasks []Tasks
}

func checkErr(err error) {
	if err != nil {
		log.Println(err)
	}
}

func genName() string {
	name := uniuri.NewLen(LENGTH)
	db, err := sql.Open("mysql", DATABASE)
	checkErr(err)

	_, err := db.QueryRow("select name from tasks where name=?", name)
	if err != sql.ErrNoRows {
		genName()
	}
	checkErr(err)
	return name
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	err := templates.ExecuteTemplate(w, "index.html", "")
	checkErr(err)

}

func todoHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	todo := vars["id"]
	p := Page{}
	err := templates.ExecuteTemplate(w, "todo.html", &p)
	checkErr(err)

}

func addHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		err := templates.ExecuteTemplate(w, "add.html", "")
		checkErr(err)

	case "POST":
		title := r.FormValue("title")
		task := r.FormValue("task")
		duedate := r.FormValue("duedate")

	}

}

func editHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	todo := vars["id"]

}

func delHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	todo := vars["id"]

}

func finishHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	todo := vars["id"]

}

func userHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id := vars["id"]

}

func userDelHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id := vars["id"]

}

func loginHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		err := templates.ExecuteTemplate(w, "login.html", "")
		checkErr(err)
	case "POST":
		email := r.FormValue("email")
		pass := r.FormValue("pass")
	}

}

func registerHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		err := templates.ExecuteTemplate(w, "login.html", "")
		checkErr(err)
	case "POST":
		email := r.FormValue("email")
		pass := r.FormValue("pass")
		db, err := sql.Open("mysql", DATABASE)
		checkErr(err)

		defer db.Close()
		query, err := db.Prepare("INSERT into users(email, password) values(?, ?)")
		checkErr(err)
		hashedPassword, err := bcrypt.GenerateFromPassword([]byte(pass), bcrypt.DefaultCost)
		checkErr(err)

		_, err = query.Exec(html.EscapeString(email), hashedPassword)
		checkErr(err)
		http.Redirect(w, r, "/login", 302)
	}

}

func logoutHandler(w http.ResponseWriter, r *http.Request) {
	cookie := &http.Cookie{
		Name:   "session",
		Value:  "",
		Path:   "/",
		MaxAge: -1,
	}
	http.SetCookie(w, cookie)
	http.Redirect(w, r, "/", 301)

}

func resetHandler(w http.ResponseWriter, r *http.Request) {

}

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/", rootHandler)

	router.HandleFunc("/todo", todoHandler)
	router.HandleFunc("/todo/{id}", todoHandler)
	router.HandleFunc("/todo/add", addHandler)
	router.HandleFunc("/todo/edit/{id}", editHandler)
	router.HandleFunc("/todo/del/{id}", delHandler)

	router.HandleFunc("/finish/{id}", finishHandler)

	router.HandleFunc("/user", userHandler)
	router.HandleFunc("/user/{id}", userHandler)
	router.HandleFunc("/user/del/{id}", userDelHandler)

	router.HandleFunc("/register", registerHandler)
	router.HandleFunc("/login", loginHandler)
	router.HandleFunc("/logout", logoutHandler)
	router.HandleFunc("/resetpass", resetHandler)
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<commit_msg>Start work on addhandler<commit_after>package main

import (
	"database/sql"
	"html"
	"html/template"
	"log"
	"net/http"
	"time"

	"golang.org/x/crypto/bcrypt"

	"github.com/dchest/uniuri"
	"github.com/gorilla/mux"
)

const (
	PORT   = ":8080"
	LENGTH = 12
)

var templates = template.Must(template.ParseFiles("static/index.html", "static/login.html", "static/register.html", "static/todo.html", "static/edit.html", "static/add.html"))

type User struct {
	ID       int
	Email    string
	Password string
}

type Tasks struct {
	ID      int    `json:"id"`
	Title   string `json:"title"`
	Task    string `json:"task"`
	Created string `json:"created"`
	DueDate string `json:"duedate"`
	Email   string `json:"email"`
}

type Page struct {
	Tasks []Tasks
}

func checkErr(err error) {
	if err != nil {
		log.Println(err)
	}
}

func genName() string {
	name := uniuri.NewLen(LENGTH)
	db, err := sql.Open("mysql", DATABASE)
	checkErr(err)

	_, err := db.QueryRow("select name from tasks where name=?", name)
	if err != sql.ErrNoRows {
		genName()
	}
	checkErr(err)
	return name
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	err := templates.ExecuteTemplate(w, "index.html", "")
	checkErr(err)

}

func todoHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	todo := vars["id"]
	p := Page{}
	err := templates.ExecuteTemplate(w, "todo.html", &p)
	checkErr(err)

}

func addHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		err := templates.ExecuteTemplate(w, "add.html", "")
		checkErr(err)

	case "POST":
		title := r.FormValue("title")
		task := r.FormValue("task")
		duedate := r.FormValue("duedate")

		db, err := sql.Open("mysql", DATABASE)
		checkErr(err)
		query, err := db.Prepare("insert into tasks(name, title, task, duedate, created)")
		err := query.Exec(html.EscapeString(title), html.EscapeString(task), html.EscapeString(duedate), time.Now().Format("2016-02-01 15:12:52"))
		checkErr(err)

	}

}

func editHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	todo := vars["id"]

}

func delHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	todo := vars["id"]

}

func finishHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	todo := vars["id"]

}

func userHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id := vars["id"]

}

func userDelHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id := vars["id"]

}

func loginHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		err := templates.ExecuteTemplate(w, "login.html", "")
		checkErr(err)
	case "POST":
		email := r.FormValue("email")
		pass := r.FormValue("pass")
	}

}

func registerHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		err := templates.ExecuteTemplate(w, "login.html", "")
		checkErr(err)
	case "POST":
		email := r.FormValue("email")
		pass := r.FormValue("pass")
		db, err := sql.Open("mysql", DATABASE)
		checkErr(err)

		defer db.Close()
		query, err := db.Prepare("INSERT into users(email, password) values(?, ?)")
		checkErr(err)
		hashedPassword, err := bcrypt.GenerateFromPassword([]byte(pass), bcrypt.DefaultCost)
		checkErr(err)

		_, err = query.Exec(html.EscapeString(email), hashedPassword)
		checkErr(err)
		http.Redirect(w, r, "/login", 302)
	}

}

func logoutHandler(w http.ResponseWriter, r *http.Request) {
	cookie := &http.Cookie{
		Name:   "session",
		Value:  "",
		Path:   "/",
		MaxAge: -1,
	}
	http.SetCookie(w, cookie)
	http.Redirect(w, r, "/", 301)

}

func resetHandler(w http.ResponseWriter, r *http.Request) {

}

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/", rootHandler)

	router.HandleFunc("/todo", todoHandler)
	router.HandleFunc("/todo/{id}", todoHandler)
	router.HandleFunc("/todo/add", addHandler)
	router.HandleFunc("/todo/edit/{id}", editHandler)
	router.HandleFunc("/todo/del/{id}", delHandler)

	router.HandleFunc("/finish/{id}", finishHandler)

	router.HandleFunc("/user", userHandler)
	router.HandleFunc("/user/{id}", userHandler)
	router.HandleFunc("/user/del/{id}", userDelHandler)

	router.HandleFunc("/register", registerHandler)
	router.HandleFunc("/login", loginHandler)
	router.HandleFunc("/logout", logoutHandler)
	router.HandleFunc("/resetpass", resetHandler)
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<|endoftext|>


<commit_before>package hush

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"sort"
	"strings"

	"github.com/pkg/errors"

	yaml "gopkg.in/yaml.v2"
)

type T map[Path]Value

func LoadTree() (T, error) {
	hushPath, err := hushPath()
	if err != nil {
		return nil, err
	}

	_, err = os.Stat(hushPath)
	if os.IsNotExist(err) {
		warn("hush file does not exist. assuming an empty one\n")
		return T{}, nil
	}
	if err != nil {
		return nil, errors.Wrap(err, "can't stat hush file")
	}

	file, err := os.Open(hushPath)
	if err != nil {
		return nil, errors.Wrap(err, "opening hush file")
	}
	hushData, err := ioutil.ReadAll(file)
	if err != nil {
		return nil, errors.Wrap(err, "can't read hush file")
	}

	keys := make(yaml.MapSlice, 0)
	err = yaml.Unmarshal(hushData, &keys)
	if err != nil {
		return nil, errors.Wrap(err, "can't parse hush file")
	}
	tree := newT(keys)
	return tree, nil
}

func newT(items yaml.MapSlice) T {
	t := make(T, 3*len(items))
	newT_(items, []string{}, t)
	return t
}

func newT_(items yaml.MapSlice, crumbs []string, t T) {
	n := len(crumbs)
	for _, item := range items {
		key := item.Key.(string)
		crumbs = append(crumbs, key)

		switch val := item.Value.(type) {
		case string:
			p := NewPath(strings.Join(crumbs, "/"))
			t[p] = NewValue(val)
		case yaml.MapSlice:
			newT_(val, crumbs, t)
		default:
			panic(fmt.Sprintf("unexpected type: %#v", val))
		}
		crumbs = crumbs[:n] // remove final crumb
	}
}

func (t T) mapSlice() yaml.MapSlice {
	// sort by key
	kvs := make([][]string, 0, len(t))
	for p, val := range t {
		kvs = append(kvs, []string{string(p), string(val)})
	}
	sort.SliceStable(kvs, func(i, j int) bool {
		return kvs[i][0] < kvs[j][0]
	})

	var slice yaml.MapSlice
	for _, kv := range kvs {
		path := strings.Split(kv[0], "\t")
		slice = mapSlice_(slice, path, kv[1])
	}
	return slice
}

func mapSlice_(slice yaml.MapSlice, path []string, value string) yaml.MapSlice {
	if len(path) == 0 {
		panic("path should never have 0 length")
	}
	if len(path) == 1 {
		return append(slice, yaml.MapItem{
			Key:   path[0],
			Value: value,
		})
	}

	var inner yaml.MapSlice
	if len(slice) == 0 {
		slice = append(slice, yaml.MapItem{Key: path[0]})
	} else {
		final := slice[len(slice)-1]
		if final.Key.(string) == path[0] {
			inner = final.Value.(yaml.MapSlice)
		} else {
			slice = append(slice, yaml.MapItem{Key: path[0]})
		}
	}
	slice[len(slice)-1].Value = mapSlice_(inner, path[1:], value)
	return slice
}

func (t T) filter(pattern string) T {
	keep := make(T)
	for p, val := range t {
		if matches(p, pattern) {
			keep[p] = val
		}
	}
	return keep
}

func isLowercase(s string) bool {
	return s == strings.ToLower(s)
}

func matches(p Path, pattern string) bool {
	ps := strings.Split(string(p), "\t")
	patterns := strings.Split(pattern, "/")
	if len(patterns) > len(ps) {
		return false
	}

	ignoreCase := isLowercase(pattern)
	for i, pattern := range patterns {
		haystack := ps[i]
		if ignoreCase {
			haystack = strings.ToLower(haystack)
		}
		if !strings.Contains(haystack, pattern) {
			return false
		}
	}
	return true
}

func (t T) get(p Path) (Value, bool) {
	val, ok := t[p]
	return val, ok
}

func (t T) set(p Path, val Value) {
	t[p] = val.Ciphertext(encryptionKey)
}

func (tree T) encrypt() {
	for p, v := range tree {
		tree[p] = v.Ciphertext(encryptionKey)
	}
}

var encryptionKey = []byte(`0123456789abcdef`)

// Decrypt returns a copy of this tree with all leaves decrypted.
func (tree T) Decrypt() T {
	t := make(T, len(tree))
	for p, v := range tree {
		t[p] = v.Plaintext(encryptionKey)
	}
	return t
}

// Print displays a tree for human consumption.
func (tree T) Print(w io.Writer) error {
	tree = tree.Decrypt()
	slice := tree.mapSlice()
	data, err := yaml.Marshal(slice)
	if err != nil {
		return errors.Wrap(err, "printing tree")
	}

	_, err = w.Write(data)
	return err
}

// Save stores a tree to disk for permanent, private archival.
func (tree T) Save() error {
	slice := tree.mapSlice()

	data, err := yaml.Marshal(slice)
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}

	// save to temporary file
	file, err := ioutil.TempFile("", "hush-")
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}
	_, err = file.Write(data)
	file.Close()
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}

	// move temporary file over top of permanent file
	hushPath, err := hushPath()
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}
	err = os.Rename(file.Name(), hushPath)
	return errors.Wrap(err, "saving tree")
}
<commit_msg>Remove extra newline in warning<commit_after>package hush

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"sort"
	"strings"

	"github.com/pkg/errors"

	yaml "gopkg.in/yaml.v2"
)

type T map[Path]Value

func LoadTree() (T, error) {
	hushPath, err := hushPath()
	if err != nil {
		return nil, err
	}

	_, err = os.Stat(hushPath)
	if os.IsNotExist(err) {
		warn("hush file does not exist. assuming an empty one")
		return T{}, nil
	}
	if err != nil {
		return nil, errors.Wrap(err, "can't stat hush file")
	}

	file, err := os.Open(hushPath)
	if err != nil {
		return nil, errors.Wrap(err, "opening hush file")
	}
	hushData, err := ioutil.ReadAll(file)
	if err != nil {
		return nil, errors.Wrap(err, "can't read hush file")
	}

	keys := make(yaml.MapSlice, 0)
	err = yaml.Unmarshal(hushData, &keys)
	if err != nil {
		return nil, errors.Wrap(err, "can't parse hush file")
	}
	tree := newT(keys)
	return tree, nil
}

func newT(items yaml.MapSlice) T {
	t := make(T, 3*len(items))
	newT_(items, []string{}, t)
	return t
}

func newT_(items yaml.MapSlice, crumbs []string, t T) {
	n := len(crumbs)
	for _, item := range items {
		key := item.Key.(string)
		crumbs = append(crumbs, key)

		switch val := item.Value.(type) {
		case string:
			p := NewPath(strings.Join(crumbs, "/"))
			t[p] = NewValue(val)
		case yaml.MapSlice:
			newT_(val, crumbs, t)
		default:
			panic(fmt.Sprintf("unexpected type: %#v", val))
		}
		crumbs = crumbs[:n] // remove final crumb
	}
}

func (t T) mapSlice() yaml.MapSlice {
	// sort by key
	kvs := make([][]string, 0, len(t))
	for p, val := range t {
		kvs = append(kvs, []string{string(p), string(val)})
	}
	sort.SliceStable(kvs, func(i, j int) bool {
		return kvs[i][0] < kvs[j][0]
	})

	var slice yaml.MapSlice
	for _, kv := range kvs {
		path := strings.Split(kv[0], "\t")
		slice = mapSlice_(slice, path, kv[1])
	}
	return slice
}

func mapSlice_(slice yaml.MapSlice, path []string, value string) yaml.MapSlice {
	if len(path) == 0 {
		panic("path should never have 0 length")
	}
	if len(path) == 1 {
		return append(slice, yaml.MapItem{
			Key:   path[0],
			Value: value,
		})
	}

	var inner yaml.MapSlice
	if len(slice) == 0 {
		slice = append(slice, yaml.MapItem{Key: path[0]})
	} else {
		final := slice[len(slice)-1]
		if final.Key.(string) == path[0] {
			inner = final.Value.(yaml.MapSlice)
		} else {
			slice = append(slice, yaml.MapItem{Key: path[0]})
		}
	}
	slice[len(slice)-1].Value = mapSlice_(inner, path[1:], value)
	return slice
}

func (t T) filter(pattern string) T {
	keep := make(T)
	for p, val := range t {
		if matches(p, pattern) {
			keep[p] = val
		}
	}
	return keep
}

func isLowercase(s string) bool {
	return s == strings.ToLower(s)
}

func matches(p Path, pattern string) bool {
	ps := strings.Split(string(p), "\t")
	patterns := strings.Split(pattern, "/")
	if len(patterns) > len(ps) {
		return false
	}

	ignoreCase := isLowercase(pattern)
	for i, pattern := range patterns {
		haystack := ps[i]
		if ignoreCase {
			haystack = strings.ToLower(haystack)
		}
		if !strings.Contains(haystack, pattern) {
			return false
		}
	}
	return true
}

func (t T) get(p Path) (Value, bool) {
	val, ok := t[p]
	return val, ok
}

func (t T) set(p Path, val Value) {
	t[p] = val.Ciphertext(encryptionKey)
}

func (tree T) encrypt() {
	for p, v := range tree {
		tree[p] = v.Ciphertext(encryptionKey)
	}
}

var encryptionKey = []byte(`0123456789abcdef`)

// Decrypt returns a copy of this tree with all leaves decrypted.
func (tree T) Decrypt() T {
	t := make(T, len(tree))
	for p, v := range tree {
		t[p] = v.Plaintext(encryptionKey)
	}
	return t
}

// Print displays a tree for human consumption.
func (tree T) Print(w io.Writer) error {
	tree = tree.Decrypt()
	slice := tree.mapSlice()
	data, err := yaml.Marshal(slice)
	if err != nil {
		return errors.Wrap(err, "printing tree")
	}

	_, err = w.Write(data)
	return err
}

// Save stores a tree to disk for permanent, private archival.
func (tree T) Save() error {
	slice := tree.mapSlice()

	data, err := yaml.Marshal(slice)
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}

	// save to temporary file
	file, err := ioutil.TempFile("", "hush-")
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}
	_, err = file.Write(data)
	file.Close()
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}

	// move temporary file over top of permanent file
	hushPath, err := hushPath()
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}
	err = os.Rename(file.Name(), hushPath)
	return errors.Wrap(err, "saving tree")
}
<|endoftext|>


<commit_before>package violetear

import (
	"fmt"
	"strings"
)

type Trie struct {
	node    map[string]*Trie
	handler map[string]string
	level   int
}

func NewTrie() *Trie {
	t := &Trie{}
	t.node = make(map[string]*Trie)
	t.handler = make(map[string]string)
	return t
}

func (t *Trie) Set(path []string, handler string, method string, level ...bool) {
	if len(path) == 0 {
		methods := strings.Split(method, ",")
		for _, v := range methods {
			t.handler[strings.TrimSpace(v)] = handler
		}
		return
	}

	key := path[0]
	newpath := path[1:]

	val, ok := t.node[key]

	if !ok {
		val = NewTrie()
		t.node[key] = val

		// increment level
		if len(level) > 0 {
			val.level = t.level + 1
		}
	}

	// recursive call with 4 argument set to true so that level can be
	// increased by 1
	val.Set(newpath, handler, method, true)
}

func (t *Trie) Get(path []string) (level int, handler map[string]string) {

	key := path[0]
	newpath := path[1:]

	// check if the node on the trie exists and return current handler
	if val, ok := t.node[key]; ok {
		if len(newpath) == 0 {
			return val.level, val.handler
		}
		return val.Get(newpath)
	}

	///////
	fmt.Println("find the : regex")
	////

	return t.level, nil
}
<commit_msg>working without regex 	modified:   trie.go<commit_after>package violetear

import (
	"fmt"
	"strings"
)

type Trie struct {
	node    map[string]*Trie
	handler map[string]string
	level   int
}

func NewTrie() *Trie {
	t := &Trie{}
	t.node = make(map[string]*Trie)
	t.handler = make(map[string]string)
	return t
}

func (t *Trie) Set(path []string, handler string, method string, level ...bool) {
	key := path[0]
	newpath := path[1:]

	val, ok := t.node[key]

	if !ok {
		val = NewTrie()
		t.node[key] = val

		// increment level
		if len(level) > 0 {
			val.level = t.level + 1
		}
	}

	fmt.Println(val.level, key, newpath)

	if len(newpath) == 0 {
		methods := strings.Split(method, ",")
		for _, v := range methods {
			val.handler[strings.TrimSpace(v)] = handler
		}
		return
	}

	// recursive call with 4 argument set to true so that level can be
	// increased by 1 if newpath > than 1
	val.Set(newpath, handler, method, true)
}

func (t *Trie) Get(path []string) (level int, handler map[string]string) {

	key := path[0]
	newpath := path[1:]

	// check if the node on the trie exists and return current handler
	if val, ok := t.node[key]; ok {
		if len(newpath) == 0 {
			return val.level, val.handler
		}
		return val.Get(newpath)
	}

	///////
	fmt.Println("find the : regex")
	////

	return t.level, nil
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"github.com/kch42/gomcmap/mcmap"
)

type CachedRegion struct {
	Region      *mcmap.Region
	cacheChunks []*mcmap.Chunk
	cachePos    []XZPos
	cachesize   int
}

func NewCachedRegion(reg *mcmap.Region, cachesize int) *CachedRegion {
	if cachesize <= 0 {
		panic(errors.New("Cachesize must be >0"))
	}
	return &CachedRegion{
		Region:      reg,
		cacheChunks: make([]*mcmap.Chunk, cachesize),
		cachePos:    make([]XZPos, cachesize),
		cachesize:   cachesize,
	}
}

func (cr *CachedRegion) Chunk(x, z int) (*mcmap.Chunk, error) {
	pos := XZPos{x, z}

	for i, p := range cr.cachePos {
		if p == pos {
			if cr.cacheChunks[i] != nil {
				chunk := cr.cacheChunks[i]
				for j := i; j >= 1; j-- {
					cr.cacheChunks[j] = cr.cacheChunks[j-1]
					cr.cachePos[j] = cr.cachePos[j-1]
				}
				return chunk, nil
			}
		}
	}

	chunk, err := cr.Region.Chunk(x, z)
	if err != nil {
		return nil, err
	}

	if cr.cacheChunks[cr.cachesize-1] != nil {
		if err := cr.cacheChunks[cr.cachesize-1].MarkUnused(); err != nil {
			return nil, fmt.Errorf("Could not remove oldest cache element: %s", err)
		}
	}

	for i := cr.cachesize - 1; i >= 1; i-- {
		cr.cacheChunks[i] = cr.cacheChunks[i-1]
		cr.cachePos[i] = cr.cachePos[i-1]
	}
	cr.cacheChunks[0] = chunk
	cr.cachePos[0] = pos

	return chunk, nil
}

func (cr *CachedRegion) Flush() error {
	for i, chunk := range cr.cacheChunks {
		if chunk == nil {
			continue
		}

		if err := chunk.MarkUnused(); err != nil {
			return err
		}
		cr.cacheChunks[i] = nil
	}

	return nil
}
<commit_msg>Fixed saving and cache.<commit_after>package main

import (
	"errors"
	"fmt"
	"github.com/kch42/gomcmap/mcmap"
)

type CachedRegion struct {
	Region      *mcmap.Region
	cacheChunks []*mcmap.Chunk
	cachePos    []XZPos
	cachesize   int
}

func NewCachedRegion(reg *mcmap.Region, cachesize int) *CachedRegion {
	if cachesize <= 0 {
		panic(errors.New("Cachesize must be >0"))
	}
	return &CachedRegion{
		Region:      reg,
		cacheChunks: make([]*mcmap.Chunk, cachesize),
		cachePos:    make([]XZPos, cachesize),
		cachesize:   cachesize,
	}
}

func (cr *CachedRegion) Chunk(x, z int) (*mcmap.Chunk, error) {
	pos := XZPos{x, z}

	for i, p := range cr.cachePos {
		if p == pos {
			if cr.cacheChunks[i] != nil {
				chunk := cr.cacheChunks[i]
				for j := i; j >= 1; j-- {
					cr.cacheChunks[j] = cr.cacheChunks[j-1]
					cr.cachePos[j] = cr.cachePos[j-1]
				}
				cr.cacheChunks[0] = chunk
				cr.cachePos[0] = pos
				return chunk, nil
			}
		}
	}

	chunk, err := cr.Region.Chunk(x, z)
	if err != nil {
		return nil, err
	}

	if cr.cacheChunks[cr.cachesize-1] != nil {
		if err := cr.cacheChunks[cr.cachesize-1].MarkUnused(); err != nil {
			return nil, fmt.Errorf("Could not remove oldest cache element: %s", err)
		}
	}

	for i := cr.cachesize - 1; i >= 1; i-- {
		cr.cacheChunks[i] = cr.cacheChunks[i-1]
		cr.cachePos[i] = cr.cachePos[i-1]
	}
	cr.cacheChunks[0] = chunk
	cr.cachePos[0] = pos

	return chunk, nil
}

func (cr *CachedRegion) Flush() error {
	for i, chunk := range cr.cacheChunks {
		if chunk == nil {
			continue
		}

		if err := chunk.MarkUnused(); err != nil {
			return err
		}
		cr.cacheChunks[i] = nil
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Intel Corporation
//
// 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 functional

import (
	. "github.com/clearcontainers/tests"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("start", func() {
	c := NewCommand(Runtime, "start")
	c.ExitCode = 1
	ret := c.Run()
	Context("without container id", func() {
		It("should NOT return 0", func() {
			Expect(ret).NotTo(Equal(0))
		})
		It("should report an error", func() {
			Expect(c.Stderr.Len()).NotTo(Equal(0))
		})
	})
})
<commit_msg>functional: simplify start functional test<commit_after>// Copyright (c) 2017 Intel Corporation
//
// 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 functional

var _ = DescribeCommandWithoutID("start")
<|endoftext|>