<commit_before>package dax

import (
	math "github.com/dlespiau/dax/math"
)

type Color struct {
	R, G, B, A float32
}

func (color *Color) FromRGBA(r, g, b, a float32) {
	color.R = r
	color.G = g
	color.B = b
	color.A = a
}

func (color *Color) FromRGB(r, g, b float32) {
	color.FromRGBA(r, g, b, 1.0)
}

func u8toF(x uint8) float32 {
	return float32(x) / 255.
}

func (color *Color) FromRGBAu8(r, g, b, a uint8) {
	color.FromRGBA(u8toF(r), u8toF(g), u8toF(b), u8toF(a))
}

func (color *Color) FromRGBu8(r, g, b uint8) {
	color.FromRGBAu8(r, g, b, 255)
}

// The RGB <-> HSL functions could do with some benchmarking and ideas from:
//   http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv

func hue2rgb(p, q, t float32) float32 {
	if t < 0 {
		t += 1
	}
	if t > 1 {
		t -= 1
	}
	if t < 1./6 {
		return p + (q-p)*6*t
	}
	if t < 1./2 {
		return q
	}
	if t < 2./3 {
		return p + (q-p)*(2./3-t)*6
	}
	return p
}

// Initialize a color from h, s, l values.
// Conversion formula adapted from:
//   http://en.wikipedia.org/wiki/HSL_color_space
// h, s, l are in [0, 1]
func (color *Color) FromHSL(h, s, l float32) {
	color.A = 1.0

	if s == 0 {
		// achromatic
		color.R = l
		color.G = l
		color.B = l
		return
	}

	var q float32
	if l < 0.5 {
		q = l * (1 + s)
	} else {
		q = l + s - l*s
	}
	p := 2*l - q

	color.R = hue2rgb(p, q, h+1./3)
	color.G = hue2rgb(p, q, h)
	color.B = hue2rgb(p, q, h-1./3)
}

// Convert a color to HSL.
// Conversion formula adapted from:
//   http://en.wikipedia.org/wiki/HSL_color_space.
// h, s, l are in [0, 1]
func (color *Color) ToHSL() (h, s, l float32) {
	r := color.R
	g := color.G
	b := color.B

	max := math.Max(r, math.Max(g, b))
	min := math.Min(r, math.Min(g, b))

	h = float32(0.0)
	s = float32(0.0)
	l = (max + min) / 2

	if max == min {
		return
	}

	d := max - min
	if l > 0.5 {
		s = d / (2 - max - min)
	} else {
		s = d / (max + min)
	}

	switch max {
	case r:
		var k float32
		if g < b {
			k = float32(6)
		} else {
			k = float32(0)
		}
		h = (g-b)/d + k
	case g:
		h = (b-r)/d + 2
	case b:
		h = (r-g)/d + 4
	}
	h /= 6

	return
}
<commit_msg>color: Fix lint warning by using increment and decrement operators<commit_after>package dax

import (
	math "github.com/dlespiau/dax/math"
)

type Color struct {
	R, G, B, A float32
}

func (color *Color) FromRGBA(r, g, b, a float32) {
	color.R = r
	color.G = g
	color.B = b
	color.A = a
}

func (color *Color) FromRGB(r, g, b float32) {
	color.FromRGBA(r, g, b, 1.0)
}

func u8toF(x uint8) float32 {
	return float32(x) / 255.
}

func (color *Color) FromRGBAu8(r, g, b, a uint8) {
	color.FromRGBA(u8toF(r), u8toF(g), u8toF(b), u8toF(a))
}

func (color *Color) FromRGBu8(r, g, b uint8) {
	color.FromRGBAu8(r, g, b, 255)
}

// The RGB <-> HSL functions could do with some benchmarking and ideas from:
//   http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv

func hue2rgb(p, q, t float32) float32 {
	if t < 0 {
		t++
	}
	if t > 1 {
		t--
	}
	if t < 1./6 {
		return p + (q-p)*6*t
	}
	if t < 1./2 {
		return q
	}
	if t < 2./3 {
		return p + (q-p)*(2./3-t)*6
	}
	return p
}

// Initialize a color from h, s, l values.
// Conversion formula adapted from:
//   http://en.wikipedia.org/wiki/HSL_color_space
// h, s, l are in [0, 1]
func (color *Color) FromHSL(h, s, l float32) {
	color.A = 1.0

	if s == 0 {
		// achromatic
		color.R = l
		color.G = l
		color.B = l
		return
	}

	var q float32
	if l < 0.5 {
		q = l * (1 + s)
	} else {
		q = l + s - l*s
	}
	p := 2*l - q

	color.R = hue2rgb(p, q, h+1./3)
	color.G = hue2rgb(p, q, h)
	color.B = hue2rgb(p, q, h-1./3)
}

// Convert a color to HSL.
// Conversion formula adapted from:
//   http://en.wikipedia.org/wiki/HSL_color_space.
// h, s, l are in [0, 1]
func (color *Color) ToHSL() (h, s, l float32) {
	r := color.R
	g := color.G
	b := color.B

	max := math.Max(r, math.Max(g, b))
	min := math.Min(r, math.Min(g, b))

	h = float32(0.0)
	s = float32(0.0)
	l = (max + min) / 2

	if max == min {
		return
	}

	d := max - min
	if l > 0.5 {
		s = d / (2 - max - min)
	} else {
		s = d / (max + min)
	}

	switch max {
	case r:
		var k float32
		if g < b {
			k = float32(6)
		} else {
			k = float32(0)
		}
		h = (g-b)/d + k
	case g:
		h = (b-r)/d + 2
	case b:
		h = (r-g)/d + 4
	}
	h /= 6

	return
}
<|endoftext|>


<commit_before>package gockl

import (
	"io"
	"strings"
)

type Token interface {
	Raw() string
}

type ElementToken interface {
	Name() string
}

type TextToken string

func (t TextToken) Raw() string {
	return string(t)
}

type CharDataToken string

func (t CharDataToken) Raw() string {
	return string(t)
}

type CommentToken string

func (t CommentToken) Raw() string {
	return string(t)
}

type DirectiveToken string

func (t DirectiveToken) Raw() string {
	return string(t)
}

type ProcInstToken string

func (t ProcInstToken) Raw() string {
	return string(t)
}

type StartElementToken string

func (t StartElementToken) Raw() string {
	return string(t)
}

func (t StartElementToken) Name() string {
	if idx := strings.IndexAny(string(t)[1:], " \t\r\n>/"); idx > -1 {
		return string(t)[1 : 1+idx]
	}
	return string(t)[1:]
}

type EndElementToken string

func (t EndElementToken) Raw() string {
	return string(t)
}

func (t EndElementToken) Name() string {
	return string(t)[2 : len(t)-1]
}

type StartEndElementToken string

func (t StartEndElementToken) Raw() string {
	return string(t)
}

type Tokenizer struct {
	Input    string
	Position int
}

func New(input string) *Tokenizer {
	return &Tokenizer{Input: input}
}

func (me *Tokenizer) shift(end string) string {
	if pos := strings.Index(me.Input[me.Position:], end); pos > -1 {
		r := me.Input[me.Position : me.Position+pos+len(end)]
		me.Position += pos + len(end)
		return r
	}

	return me.shiftUntil("<")
}

func (me *Tokenizer) shiftUntil(next string) string {
	if pos := strings.Index(me.Input[me.Position+1:], next); pos > -1 {
		r := me.Input[me.Position : me.Position+pos+1]
		me.Position += pos + 1
		return r
	}

	r := me.Input[me.Position:]
	me.Position = len(me.Input)
	return r
}

func (me *Tokenizer) Next() (Token, error) {
	if me.Position >= len(me.Input) {
		return nil, io.EOF
	}

	if me.Position >= len(me.Input)-3 {
		goto dunno
	}

	switch me.Input[me.Position] {
	case '<':
		switch me.Input[me.Position+1] {
		case '?':
			return ProcInstToken(me.shift("?>")), nil
		case '!':
			if me.Input[me.Position+2:me.Position+4] != "--" {
				goto dunno
			}
			return CommentToken(me.shift("-->")), nil
		case '/':
			return EndElementToken(me.shift(">")), nil
		default:
			raw := me.shift(">")

			if len(raw) >= 3 && raw[len(raw)-2] == '/' {
				return StartEndElementToken(raw), nil
			}

			return StartElementToken(raw), nil
		}
	}

dunno:

	return TextToken(me.shiftUntil("<")), nil
}
<commit_msg>Add CDATA tokens.<commit_after>package gockl

import (
	"io"
	"strings"
)

type Token interface {
	Raw() string
}

type ElementToken interface {
	Name() string
}

type TextToken string

func (t TextToken) Raw() string {
	return string(t)
}

type CDATAToken string

func (t CDATAToken) Raw() string {
	return string(t)
}

type CommentToken string

func (t CommentToken) Raw() string {
	return string(t)
}

type DirectiveToken string

func (t DirectiveToken) Raw() string {
	return string(t)
}

type ProcInstToken string

func (t ProcInstToken) Raw() string {
	return string(t)
}

type StartElementToken string

func (t StartElementToken) Raw() string {
	return string(t)
}

func (t StartElementToken) Name() string {
	if idx := strings.IndexAny(string(t)[1:], " \t\r\n>/"); idx > -1 {
		return string(t)[1 : 1+idx]
	}
	return string(t)[1:]
}

type EndElementToken string

func (t EndElementToken) Raw() string {
	return string(t)
}

func (t EndElementToken) Name() string {
	return string(t)[2 : len(t)-1]
}

type StartEndElementToken string

func (t StartEndElementToken) Raw() string {
	return string(t)
}

type Tokenizer struct {
	Input    string
	Position int
}

func New(input string) *Tokenizer {
	return &Tokenizer{Input: input}
}

func (me *Tokenizer) shift(end string) string {
	if pos := strings.Index(me.Input[me.Position:], end); pos > -1 {
		r := me.Input[me.Position : me.Position+pos+len(end)]
		me.Position += pos + len(end)
		return r
	}

	return me.shiftUntil("<")
}

func (me *Tokenizer) shiftUntil(next string) string {
	if pos := strings.Index(me.Input[me.Position+1:], next); pos > -1 {
		r := me.Input[me.Position : me.Position+pos+1]
		me.Position += pos + 1
		return r
	}

	r := me.Input[me.Position:]
	me.Position = len(me.Input)
	return r
}

func (me *Tokenizer) has(next string) bool {
	return me.Position+len(next) <= len(me.Input) && me.Input[me.Position:me.Position+len(next)] == next
}

func (me *Tokenizer) Next() (Token, error) {
	if me.Position >= len(me.Input) {
		return nil, io.EOF
	}

	if me.Position >= len(me.Input)-3 {
		goto dunno
	}

	switch me.Input[me.Position] {
	case '<':
		switch me.Input[me.Position+1] {
		case '?':
			return ProcInstToken(me.shift("?>")), nil
		case '!':
			if me.has("<![CDATA[") {
				return CDATAToken(me.shift("]]>")), nil
			}
			if me.Input[me.Position+2:me.Position+4] != "--" {
				goto dunno
			}
			return CommentToken(me.shift("-->")), nil
		case '/':
			return EndElementToken(me.shift(">")), nil
		default:
			raw := me.shift(">")

			if len(raw) >= 3 && raw[len(raw)-2] == '/' {
				return StartEndElementToken(raw), nil
			}

			return StartElementToken(raw), nil
		}
	}

dunno:

	return TextToken(me.shiftUntil("<")), nil
}
<|endoftext|>


<commit_before>/*
 * gocli
 * Copyright (c) 2015 Yieldbot, Inc. (http://github.com/yieldbot/gocli)
 * For the full copyright and license information, please view the LICENSE.txt file.
 */

// Package gocli is a CLI library that provides subcommand handling, tidy usage and version printing.
package gocli

import (
	"flag"
	"fmt"
	"log"
	"os"
	"runtime"
)

// Cli represent command line interface
type Cli struct {
	// AppName is the app name
	AppName string

	// AppVersion is the app version
	AppVersion string

	// AppDesc is the app description
	AppDesc string

	// Command is the subcommand for the app
	Command string

	// CommandArgs contains the args of the subcommand
	CommandArgs []string

	// CommandList contains the subcommand list of the app
	CommandList map[string]string

	// LogOut is logger for stdout
	LogOut *log.Logger

	// LogErr is logger for stderr
	LogErr *log.Logger

	// Flags contains flags
	//Flags map[string]string
}

// Init initializes Cli instance
func (cl *Cli) Init() {

	// Init flag
	if !flag.Parsed() {
		flag.Parse()
	}

	// Init loggers
	cl.LogOut = log.New(os.Stdout, "", log.LstdFlags)
	cl.LogErr = log.New(os.Stderr, "", log.LstdFlags)

	// Init flags
	// cl.Flags = make(map[string]string)
	// flag.VisitAll(func(f *flag.Flag) {
	//  cl.Flags[f.Name] = f.Value.String()
	// })

	// Init args
	// If length of the args more than one
	if len(os.Args) > 1 {

		// Iterate the args
		for _, arg := range os.Args {

			// If the arg is in command list then
			if _, ok := cl.CommandList[arg]; ok {
				cl.Command = arg // set as command
			} else {
				// Otherwise add it to args
				if cl.Command != "" {
					cl.CommandArgs = append(cl.CommandArgs, arg)
				}
			}
		}
	}
}

// PrintVersion prints version information
func (cl Cli) PrintVersion(extra bool) {
	var ver string

	if extra == true {
		ver += fmt.Sprintf("App version : %s\n", cl.AppVersion)
		ver += fmt.Sprintf("Go version  : %s", runtime.Version())
	} else {
		ver = fmt.Sprintf("%s", cl.AppVersion)
	}

	fmt.Println(ver)
}

// PrintUsage prints usage info
// Usage format follows common convention for Go apps
func (cl Cli) PrintUsage() {

	// Init vars
	type flagInfo struct {
		nameu    string
		name     string
		usage    string
		defValue string
	}

	flagList := make(map[string]*flagInfo)
	maxlen := 0

	// Find max length by command list
	if len(cl.CommandList) > 0 {
		for c := range cl.CommandList {
			if len(c) > maxlen {
				maxlen = len(c)
			}
		}
	}

	// Iterate flags
	flag.VisitAll(func(f *flag.Flag) {

		// Set key by the flag usage for grouping
		key := fmt.Sprint(f.Usage)

		// Init usage name
		nameu := "-" + f.Name
		if len(f.Name) > 2 {
			nameu = "-" + nameu
		}

		// If the flag exists then
		if _, ok := flagList[key]; ok {
			// Merge names
			flagList[key].nameu += ", " + nameu
		} else {
			// Otherwise add the flag
			flagList[key] = &flagInfo{
				nameu:    nameu,
				name:     f.Name,
				usage:    f.Usage,
				defValue: f.DefValue,
			}
		}

		// Check and set maximum length for alignment
		if len(flagList[key].nameu) > maxlen {
			maxlen = len(flagList[key].nameu)
		}
	})

	// Add usage header and description
	usage := "Usage: " + cl.AppName + " [OPTIONS] COMMAND [arg...]\n\n"
	if cl.AppDesc != "" {
		usage += cl.AppDesc + "\n\n"
	}

	// Add options
	if len(flagList) > 0 {
		usage += "Options:\n"
		for _, f := range flagList {
			usage += "  " + strPadRight(f.nameu, " ", maxlen) + " : " + f.usage
			if f.defValue != "false" {
				usage += " (default \"" + f.defValue + "\")"
			}
			usage += "\n"
		}
	}

	// Add commands
	if len(cl.CommandList) > 0 {
		usage += "\nCommands:\n"
		for cn, cv := range cl.CommandList {
			usage += "  " + strPadRight(cn, " ", maxlen) + " : " + cv + "\n"
		}
	}

	fmt.Println(usage)
}

// strPadRight provides padding for strings
func strPadRight(str, pad string, length int) string {
	for {
		str += pad
		if len(str) > length {
			return str[0:length]
		}
	}
}
<commit_msg>Ignore test flags<commit_after>/*
 * gocli
 * Copyright (c) 2015 Yieldbot, Inc. (http://github.com/yieldbot/gocli)
 * For the full copyright and license information, please view the LICENSE.txt file.
 */

// Package gocli is a CLI library that provides subcommand handling, tidy usage and version printing.
package gocli

import (
	"flag"
	"fmt"
	"log"
	"os"
	"runtime"
	"strings"
)

// Cli represent command line interface
type Cli struct {
	// AppName is the app name
	AppName string

	// AppVersion is the app version
	AppVersion string

	// AppDesc is the app description
	AppDesc string

	// Command is the subcommand for the app
	Command string

	// CommandArgs contains the args of the subcommand
	CommandArgs []string

	// CommandList contains the subcommand list of the app
	CommandList map[string]string

	// LogOut is logger for stdout
	LogOut *log.Logger

	// LogErr is logger for stderr
	LogErr *log.Logger

	// Flags contains flags
	//Flags map[string]string
}

// Init initializes Cli instance
func (cl *Cli) Init() {

	// Init flag
	if !flag.Parsed() {
		flag.Parse()
	}

	// Init loggers
	cl.LogOut = log.New(os.Stdout, "", log.LstdFlags)
	cl.LogErr = log.New(os.Stderr, "", log.LstdFlags)

	// Init flags
	// cl.Flags = make(map[string]string)
	// flag.VisitAll(func(f *flag.Flag) {
	//  cl.Flags[f.Name] = f.Value.String()
	// })

	// Init args
	// If length of the args more than one
	if len(os.Args) > 1 {

		// Iterate the args
		for _, arg := range os.Args {

			// If the arg is in command list then
			if _, ok := cl.CommandList[arg]; ok {
				cl.Command = arg // set as command
			} else {
				// Otherwise add it to args
				if cl.Command != "" {
					cl.CommandArgs = append(cl.CommandArgs, arg)
				}
			}
		}
	}
}

// PrintVersion prints version information
func (cl Cli) PrintVersion(extra bool) {
	var ver string

	if extra == true {
		ver += fmt.Sprintf("App version : %s\n", cl.AppVersion)
		ver += fmt.Sprintf("Go version  : %s", runtime.Version())
	} else {
		ver = fmt.Sprintf("%s", cl.AppVersion)
	}

	fmt.Println(ver)
}

// PrintUsage prints usage info
// Usage format follows common convention for Go apps
func (cl Cli) PrintUsage() {

	// Init vars
	type flagInfo struct {
		nameu    string
		name     string
		usage    string
		defValue string
	}

	flagList := make(map[string]*flagInfo)
	maxlen := 0

	// Find max length by command list
	if len(cl.CommandList) > 0 {
		for c := range cl.CommandList {
			if len(c) > maxlen {
				maxlen = len(c)
			}
		}
	}

	// Iterate flags
	flag.VisitAll(func(f *flag.Flag) {

		// If flag name doesn't start with `test.` then
		if strings.Index(f.Name, "test.") != 0 {

			// Set key by the flag usage for grouping
			key := fmt.Sprint(f.Usage)

			// Init usage name
			nameu := "-" + f.Name
			if len(f.Name) > 2 {
				nameu = "-" + nameu
			}

			// If the flag exists then
			if _, ok := flagList[key]; ok {
				// Merge names
				flagList[key].nameu += ", " + nameu
			} else {
				// Otherwise add the flag
				flagList[key] = &flagInfo{
					nameu:    nameu,
					name:     f.Name,
					usage:    f.Usage,
					defValue: f.DefValue,
				}
			}

			// Check and set maximum length for alignment
			if len(flagList[key].nameu) > maxlen {
				maxlen = len(flagList[key].nameu)
			}
		}
	})

	// Add usage header and description
	usage := "Usage: " + cl.AppName + " [OPTIONS] COMMAND [arg...]\n\n"
	if cl.AppDesc != "" {
		usage += cl.AppDesc + "\n\n"
	}

	// Add options
	if len(flagList) > 0 {
		usage += "Options:\n"
		for _, f := range flagList {
			usage += "  " + strPadRight(f.nameu, " ", maxlen) + " : " + f.usage
			if f.defValue != "false" {
				usage += " (default \"" + f.defValue + "\")"
			}
			usage += "\n"
		}
	}

	// Add commands
	if len(cl.CommandList) > 0 {
		usage += "\nCommands:\n"
		for cn, cv := range cl.CommandList {
			usage += "  " + strPadRight(cn, " ", maxlen) + " : " + cv + "\n"
		}
	}

	fmt.Println(usage)
}

// strPadRight provides padding for strings
func strPadRight(str, pad string, length int) string {
	for {
		str += pad
		if len(str) > length {
			return str[0:length]
		}
	}
}
<|endoftext|>


<commit_before>package tester

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

	"crypto/md5"

	"github.com/dave/courtney"
	"github.com/dave/courtney/tester/merge"
	"github.com/dave/patsy/vos"
	"github.com/pkg/errors"
	"golang.org/x/tools/cover"
)

func New(env vos.Env, paths *courtney.PathCache) *Tester {
	t := &Tester{
		env:   env,
		paths: paths,
	}
	t.previousWd, _ = t.env.Getwd()
	return t
}

type Tester struct {
	env        vos.Env
	cover      string
	Results    []*cover.Profile
	previousWd string
	paths      *courtney.PathCache
}

func (t *Tester) Test(packages []courtney.PackageSpec) error {

	t.cover = filepath.Join(packages[0].Dir, ".coverage")

	os.RemoveAll(t.cover)
	defer os.RemoveAll(t.cover)

	if _, err := os.Stat(t.cover); os.IsNotExist(err) {
		if err := os.Mkdir(t.cover, 0777); err != nil {
			return errors.Wrapf(err, "Error creating temporary coverage dir %s", t.cover)
		}
	}

	for _, spec := range packages {
		if err := t.processDir(spec.Dir, packages); err != nil {
			return err
		}
	}

	//if scan {
	//	t.processExcludes()
	//}

	return nil
}

func (t *Tester) Save() error {
	if t.Results == nil {
		fmt.Println("No results")
		return nil
	}
	f, err := os.Create(filepath.Join(t.previousWd, "coverage.out"))
	if err != nil {
		return errors.Wrapf(err, "Error creating output coverage file coverage.out")
	}
	defer f.Close()
	merge.DumpProfiles(t.Results, f)
	return nil
}

func (t *Tester) ProcessExcludes(excludes map[string]map[int]bool) error {
	var processed []*cover.Profile

	for _, p := range t.Results {

		// Filenames in t.Results are in go package form. We need to convert to
		// filepaths before use
		fpath, err := t.paths.GoNameToFilePath(p.FileName)
		if err != nil {
			return err
		}

		f, ok := excludes[fpath]
		if !ok {
			// no excludes in this file - add the profile unchanged
			processed = append(processed, p)
			continue
		}
		var blocks []cover.ProfileBlock
		for _, b := range p.Blocks {
			excluded := false
			for line := b.StartLine; line <= b.EndLine; line++ {
				if ex, ok := f[line]; ok && ex {
					excluded = true
					break
				}
			}
			if !excluded {
				blocks = append(blocks, b)
			}
		}
		profile := &cover.Profile{
			FileName: p.FileName,
			Mode:     p.Mode,
			Blocks:   blocks,
		}
		processed = append(processed, profile)
	}
	t.Results = processed
	return nil
}

func (t *Tester) processDir(dir string, all []courtney.PackageSpec) error {

	coverageFilename := fmt.Sprintf("%x", md5.Sum([]byte(dir))) + ".out"
	coverageFilepath := filepath.Join(t.cover, coverageFilename)

	files, err := ioutil.ReadDir(dir)
	if err != nil {
		return errors.Wrapf(err, "Error reading files from %s", dir)
	}

	foundTest := false
	for _, f := range files {
		if strings.HasSuffix(f.Name(), "_test.go") {
			foundTest = true
		}
	}
	if !foundTest {
		return nil
	}

	os.Chdir(dir)
	//fmt.Println("dir:", dir)
	//fi, _ := ioutil.ReadDir(dir)
	//for _, f := range fi {
	//	fmt.Println(f.Name())
	//}

	var allpkgs []string
	for _, s := range all {
		allpkgs = append(allpkgs, s.Path)
	}
	coverParam := fmt.Sprintf("-coverpkg=%s", strings.Join(allpkgs, ","))
	outParam := fmt.Sprintf("-coverprofile=%s", coverageFilepath)
	exe := exec.Command("go", "test", outParam, coverParam)
	exe.Env = t.env.Environ()
	b, err := exe.CombinedOutput()
	if strings.Contains(string(b), "no buildable Go source files in") {
		return nil
	}
	if err != nil {
		return errors.Wrapf(err, "Error executing test \nOutput:[\n%s]\n", b)
	}
	//by, _ := ioutil.ReadFile(coverageFilepath)
	//fmt.Println("coverage:", string(by))
	return t.processCoverageFile(coverageFilepath)
}

func (t *Tester) processCoverageFile(filename string) error {
	profiles, err := cover.ParseProfiles(filename)
	if err != nil {
		return err
	}
	for _, p := range profiles {
		if t.Results, err = merge.AddProfile(t.Results, p); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Include all blocks that have coverage<commit_after>package tester

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

	"crypto/md5"

	"github.com/dave/courtney"
	"github.com/dave/courtney/tester/merge"
	"github.com/dave/patsy/vos"
	"github.com/pkg/errors"
	"golang.org/x/tools/cover"
)

func New(env vos.Env, paths *courtney.PathCache) *Tester {
	t := &Tester{
		env:   env,
		paths: paths,
	}
	t.previousWd, _ = t.env.Getwd()
	return t
}

type Tester struct {
	env        vos.Env
	cover      string
	Results    []*cover.Profile
	previousWd string
	paths      *courtney.PathCache
}

func (t *Tester) Test(packages []courtney.PackageSpec) error {

	t.cover = filepath.Join(packages[0].Dir, ".coverage")

	os.RemoveAll(t.cover)
	defer os.RemoveAll(t.cover)

	if _, err := os.Stat(t.cover); os.IsNotExist(err) {
		if err := os.Mkdir(t.cover, 0777); err != nil {
			return errors.Wrapf(err, "Error creating temporary coverage dir %s", t.cover)
		}
	}

	for _, spec := range packages {
		if err := t.processDir(spec.Dir, packages); err != nil {
			return err
		}
	}

	//if scan {
	//	t.processExcludes()
	//}

	return nil
}

func (t *Tester) Save() error {
	if t.Results == nil {
		fmt.Println("No results")
		return nil
	}
	f, err := os.Create(filepath.Join(t.previousWd, "coverage.out"))
	if err != nil {
		return errors.Wrapf(err, "Error creating output coverage file coverage.out")
	}
	defer f.Close()
	merge.DumpProfiles(t.Results, f)
	return nil
}

func (t *Tester) ProcessExcludes(excludes map[string]map[int]bool) error {
	var processed []*cover.Profile

	for _, p := range t.Results {

		// Filenames in t.Results are in go package form. We need to convert to
		// filepaths before use
		fpath, err := t.paths.GoNameToFilePath(p.FileName)
		if err != nil {
			return err
		}

		f, ok := excludes[fpath]
		if !ok {
			// no excludes in this file - add the profile unchanged
			processed = append(processed, p)
			continue
		}
		var blocks []cover.ProfileBlock
		for _, b := range p.Blocks {
			excluded := false
			for line := b.StartLine; line <= b.EndLine; line++ {
				if ex, ok := f[line]; ok && ex {
					excluded = true
					break
				}
			}
			if !excluded || b.Count > 0 {
				// include blocks that are not excluded
				// also include any blocks that have coverage
				blocks = append(blocks, b)
			}
		}
		profile := &cover.Profile{
			FileName: p.FileName,
			Mode:     p.Mode,
			Blocks:   blocks,
		}
		processed = append(processed, profile)
	}
	t.Results = processed
	return nil
}

func (t *Tester) processDir(dir string, all []courtney.PackageSpec) error {

	coverageFilename := fmt.Sprintf("%x", md5.Sum([]byte(dir))) + ".out"
	coverageFilepath := filepath.Join(t.cover, coverageFilename)

	files, err := ioutil.ReadDir(dir)
	if err != nil {
		return errors.Wrapf(err, "Error reading files from %s", dir)
	}

	foundTest := false
	for _, f := range files {
		if strings.HasSuffix(f.Name(), "_test.go") {
			foundTest = true
		}
	}
	if !foundTest {
		return nil
	}

	os.Chdir(dir)
	//fmt.Println("dir:", dir)
	//fi, _ := ioutil.ReadDir(dir)
	//for _, f := range fi {
	//	fmt.Println(f.Name())
	//}

	var allpkgs []string
	for _, s := range all {
		allpkgs = append(allpkgs, s.Path)
	}
	coverParam := fmt.Sprintf("-coverpkg=%s", strings.Join(allpkgs, ","))
	outParam := fmt.Sprintf("-coverprofile=%s", coverageFilepath)
	exe := exec.Command("go", "test", outParam, coverParam)
	exe.Env = t.env.Environ()
	b, err := exe.CombinedOutput()
	if strings.Contains(string(b), "no buildable Go source files in") {
		return nil
	}
	if err != nil {
		return errors.Wrapf(err, "Error executing test \nOutput:[\n%s]\n", b)
	}
	//by, _ := ioutil.ReadFile(coverageFilepath)
	//fmt.Println("coverage:", string(by))
	return t.processCoverageFile(coverageFilepath)
}

func (t *Tester) processCoverageFile(filename string) error {
	profiles, err := cover.ParseProfiles(filename)
	if err != nil {
		return err
	}
	for _, p := range profiles {
		if t.Results, err = merge.AddProfile(t.Results, p); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package subchal

import (
    "testing"
)

func Test_LoadStoptimes(t *testing.T) {
    t.Parallel()
    SetTestLogger(t)

    stops, _, _ := LoadStops("../test-data/stops.txt")
    stoptimes, err := LoadStoptimes("../test-data/stop_times.txt", stops)

    switch false {
    case err == nil:
        t.Log("Got error from LoadStoptimes():", err)
        t.FailNow()
    case len(stoptimes) == len(stops):
        t.Log("Didn't load stoptimes for enough stops")
        t.FailNow()
    }

    for stopID, stSlice := range stoptimes {
        for _, st := range stSlice {
            if st.Stop.StopID != stopID {
                t.Log("Stoptime at stop", st.Stop.StopID, "doesn't match stoptimes key", stopID)
                t.FailNow()
            }
            if st.Stop.IsStation() {
                t.Log("Stoptime at stop", st.Stop.StopID, "is a station rather than a stop")
                t.FailNow()
            }
        }
    }
}
<commit_msg>Wrote ParseTime() test<commit_after>package subchal

import (
    "testing"
    "time"
)

func Test_LoadStoptimes(t *testing.T) {
    t.Parallel()
    SetTestLogger(t)

    stops, _, _ := LoadStops("../test-data/stops.txt")
    stoptimes, err := LoadStoptimes("../test-data/stop_times.txt", stops)

    switch false {
    case err == nil:
        t.Log("Got error from LoadStoptimes():", err)
        t.FailNow()
    case len(stoptimes) == len(stops):
        t.Log("Didn't load stoptimes for enough stops")
        t.FailNow()
    }

    for stopID, stSlice := range stoptimes {
        for _, st := range stSlice {
            if st.Stop.StopID != stopID {
                t.Log("Stoptime at stop", st.Stop.StopID, "doesn't match stoptimes key", stopID)
                t.FailNow()
            }
            if st.Stop.IsStation() {
                t.Log("Stoptime at stop", st.Stop.StopID, "is a station rather than a stop")
                t.FailNow()
            }
        }
    }
}

func Test_ParseTime(t *testing.T) {
    t.Parallel()
    SetTestLogger(t)

    rslt, err := ParseTime("00:00:00")
    switch false {
    case err == nil:
        t.Log("Got error from ParseTime:", err)
        t.FailNow()
    case VerifyZeroDay(rslt) && rslt.Hour() == 0 && rslt.Minute() == 0 && rslt.Second() == 0:
        t.Log("ParseTime produced an incorrect time:", rslt.Format("2006-01-02 15:04:05 MST"))
        t.FailNow()
    }

    rslt, err = ParseTime("13:59:06")
    switch false {
    case err == nil:
        t.Log("Got error from ParseTime:", err)
        t.FailNow()
    case VerifyZeroDay(rslt) && rslt.Hour() == 13 && rslt.Minute() == 59 && rslt.Second() == 6:
        t.Log("ParseTime produced an incorrect time:", rslt.Format("2006-01-02 15:04:05 MST"))
        t.FailNow()
    }

    rslt, err = ParseTime("25:00:14")
    switch false {
    case err == nil:
        t.Log("Got error from ParseTime:", err)
        t.FailNow()
    case VerifyZeroDay(rslt) && rslt.Hour() == 1 && rslt.Minute() == 0 && rslt.Second() == 14:
        t.Log("ParseTime produced an incorrect time:", rslt.Format("2006-01-02 15:04:05 MST"))
        t.FailNow()
    }
}

// Verifies that the given time.Time occurs on the zero day (0000-01-01)
func VerifyZeroDay(t time.Time) bool {
    return (t.Year() == 0 && t.YearDay() == 1)
}

<|endoftext|>


<commit_before>/*

   Copyright 2016 Wenhui Shen <www.webx.top>

   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 captcha

import (
	"bytes"
	"strconv"
	"strings"

	"github.com/webx-top/captcha"
	"github.com/webx-top/echo"
)

var DefaultOptions = &Options{
	EnableImage:    true,
	EnableAudio:    true,
	EnableDownload: true,
	AudioLangs:     []string{`zh`, `ru`, `en`},
}

type Options struct {
	EnableImage    bool
	EnableAudio    bool
	EnableDownload bool
	AudioLangs     []string
	Prefix         string
}

func (o Options) Wrapper(e echo.RouteRegister) {
	if o.AudioLangs == nil || len(o.AudioLangs) == 0 {
		o.AudioLangs = []string{`zh`, `ru`, `en`}
	}
	if len(o.Prefix) == 0 {
		o.Prefix = `/captcha`
	} else {
		o.Prefix = strings.TrimRight(o.Prefix, "/")
	}
	e.Get(o.Prefix+"/*", Captcha(&o))
}

func Captcha(opts ...*Options) func(echo.Context) error {
	var o *Options
	if len(opts) > 0 {
		o = opts[0]
	}
	if o == nil {
		o = DefaultOptions
	}
	return func(ctx echo.Context) (err error) {
		var id, ext string
		param := ctx.P(0)
		if p := strings.LastIndex(param, `.`); p > 0 {
			id = param[0:p]
			ext = param[p:]
		}
		if len(ext) == 0 || len(id) == 0 {
			return echo.ErrNotFound
		}
		if len(ctx.Query("reload")) > 0 {
			captcha.Reload(id)
		}
		w := ctx.Response()
		header := w.Header()
		download := o.EnableDownload && len(ctx.Query("download")) > 0
		b := bytes.NewBufferString(``)
		switch ext {
		case ".png":
			if !o.EnableImage {
				return echo.ErrNotFound
			}
			if download {
				header.Set(echo.HeaderContentType, "application/octet-stream")
			} else {
				header.Set(echo.HeaderContentType, "image/png")
			}
			err = captcha.WriteImage(b, id, captcha.StdWidth, captcha.StdHeight)
		case ".wav":
			if !o.EnableAudio {
				return echo.ErrNotFound
			}
			lang := strings.ToLower(ctx.Query("lang"))
			supported := false
			for _, supportedLang := range o.AudioLangs {
				if supportedLang == lang {
					supported = true
					break
				}
			}
			if !supported && len(o.AudioLangs) > 0 {
				lang = o.AudioLangs[0]
			}
			var au *captcha.Audio
			au, err = captcha.GetAudio(id, lang)
			if err != nil {
				return
			}
			if download {
				header.Set(echo.HeaderContentType, "application/octet-stream")
			} else {
				header.Set(echo.HeaderContentType, "audio/x-wav")
			}
			header.Set("Content-Length", strconv.Itoa(au.EncodedLen()))
			_, err = au.WriteTo(b)
		default:
			return nil
		}
		if err != nil {
			return
		}
		return ctx.Blob(b.Bytes())
	}
}
<commit_msg>update<commit_after>/*

   Copyright 2016 Wenhui Shen <www.webx.top>

   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 captcha

import (
	"bytes"
	"strconv"
	"strings"

	"github.com/webx-top/captcha"
	"github.com/webx-top/echo"
)

var DefaultOptions = &Options{
	EnableImage:    true,
	EnableAudio:    true,
	EnableDownload: true,
	AudioLangs:     []string{`zh`, `ru`, `en`},
	CookieName:     `captchaId`,
	HeaderName:     `X-Captcha-ID`,
}

type Options struct {
	EnableImage    bool
	EnableAudio    bool
	EnableDownload bool
	AudioLangs     []string
	Prefix         string
	CookieName     string
	HeaderName     string
}

func (o Options) Wrapper(e echo.RouteRegister) {
	if o.AudioLangs == nil || len(o.AudioLangs) == 0 {
		o.AudioLangs = []string{`zh`, `ru`, `en`}
	}
	if len(o.Prefix) == 0 {
		o.Prefix = `/captcha`
	} else {
		o.Prefix = strings.TrimRight(o.Prefix, "/")
	}
	e.Get(o.Prefix+"/*", Captcha(&o))
}

func Captcha(opts ...*Options) func(echo.Context) error {
	var o *Options
	if len(opts) > 0 {
		o = opts[0]
	}
	if o == nil {
		o = DefaultOptions
	}
	if len(o.CookieName) == 0 {
		o.CookieName = DefaultOptions.CookieName
	}
	if len(o.HeaderName) == 0 {
		o.HeaderName = DefaultOptions.HeaderName
	}
	return func(ctx echo.Context) (err error) {
		var id, ext string
		param := ctx.P(0)
		if p := strings.LastIndex(param, `.`); p > 0 {
			id = param[0:p]
			ext = param[p:]
		}
		if len(ext) == 0 || len(id) == 0 {
			return echo.ErrNotFound
		}
		ids := []string{id}
		if len(o.CookieName) > 0 {
			ids = append(ids, ctx.GetCookie(o.CookieName))
		}
		if len(o.HeaderName) > 0 {
			ids = append(ids, ctx.Header(o.HeaderName))
		}
		w := ctx.Response()
		header := w.Header()
		if len(ctx.Query("reload")) > 0 {
			var ok bool
			for _, id := range ids {
				if captcha.Reload(id) {
					ok = true
					ids = []string{id}
					break
				}
			}
			if !ok {
				if len(o.CookieName) > 0 {
					id = captcha.New()
					ids = []string{id}
					ctx.SetCookie(o.CookieName, id)
				} else if len(o.HeaderName) > 0 {
					id = captcha.New()
					ids = []string{id}
					header.Set(o.HeaderName, id)
				}
			}
		}
		download := o.EnableDownload && len(ctx.Query("download")) > 0
		b := bytes.NewBufferString(``)
		switch ext {
		case ".png":
			if !o.EnableImage {
				return echo.ErrNotFound
			}
			for _, id := range ids {
				if len(id) == 0 {
					continue
				}
				err = captcha.WriteImage(b, id, captcha.StdWidth, captcha.StdHeight)
				if err == nil || err != captcha.ErrNotFound {
					break
				}
			}
			if err != nil {
				if err == captcha.ErrNotFound {
					return echo.ErrNotFound
				}
				return
			}
			if download {
				header.Set(echo.HeaderContentType, "application/octet-stream")
			} else {
				header.Set(echo.HeaderContentType, "image/png")
			}
		case ".wav":
			if !o.EnableAudio {
				return echo.ErrNotFound
			}
			lang := strings.ToLower(ctx.Query("lang"))
			supported := false
			for _, supportedLang := range o.AudioLangs {
				if supportedLang == lang {
					supported = true
					break
				}
			}
			if !supported && len(o.AudioLangs) > 0 {
				lang = o.AudioLangs[0]
			}
			var au *captcha.Audio
			for _, id := range ids {
				if len(id) == 0 {
					continue
				}
				au, err = captcha.GetAudio(id, lang)
				if err == nil || err != captcha.ErrNotFound {
					break
				}
			}
			if err != nil {
				if err == captcha.ErrNotFound {
					return echo.ErrNotFound
				}
				return
			}
			length := strconv.Itoa(au.EncodedLen())
			_, err = au.WriteTo(b)
			if err != nil {
				return err
			}
			if download {
				header.Set(echo.HeaderContentType, "application/octet-stream")
			} else {
				header.Set(echo.HeaderContentType, "audio/x-wav")
			}
			header.Set("Content-Length", length)
		default:
			return nil
		}
		return ctx.Blob(b.Bytes())
	}
}
<|endoftext|>


<commit_before>package plugin

import (
	"net/rpc"

	"github.com/hashicorp/go-plugin"
	"github.com/hashicorp/vault/logical"
	log "github.com/mgutz/logxi/v1"
)

// backendPluginClient implements logical.Backend and is the
// go-plugin client.
type backendPluginClient struct {
	broker       *plugin.MuxBroker
	client       *rpc.Client
	pluginClient *plugin.Client

	system logical.SystemView
	logger log.Logger
}

// HandleRequestArgs is the args for HandleRequest method.
type HandleRequestArgs struct {
	StorageID uint32
	Request   *logical.Request
}

// HandleRequestReply is the reply for HandleRequest method.
type HandleRequestReply struct {
	Response *logical.Response
	Error    *plugin.BasicError
}

// SpecialPathsReply is the reply for SpecialPaths method.
type SpecialPathsReply struct {
	Paths *logical.Paths
}

// SystemReply is the reply for System method.
type SystemReply struct {
	SystemView logical.SystemView
	Error      *plugin.BasicError
}

// HandleExistenceCheckArgs is the args for HandleExistenceCheck method.
type HandleExistenceCheckArgs struct {
	StorageID uint32
	Request   *logical.Request
}

// HandleExistenceCheckReply is the reply for HandleExistenceCheck method.
type HandleExistenceCheckReply struct {
	CheckFound bool
	Exists     bool
	Error      *plugin.BasicError
}

// SetupArgs is the args for Setup method.
type SetupArgs struct {
	StorageID uint32
	LoggerID  uint32
	SysViewID uint32
	Config    map[string]string
}

// SetupReply is the reply for Setup method.
type SetupReply struct {
	Error *plugin.BasicError
}

// TypeReply is the reply for the Type method.
type TypeReply struct {
	Type logical.BackendType
}

// RegisterLicenseArgs is the args for the RegisterLicense method.
type RegisterLicenseArgs struct {
	License interface{}
}

// RegisterLicenseReply is the reply for the RegisterLicense method.
type RegisterLicenseReply struct {
	Error *plugin.BasicError
}

func (b *backendPluginClient) HandleRequest(req *logical.Request) (*logical.Response, error) {
	args := &HandleRequestArgs{
		Request: req,
	}
	var reply HandleRequestReply

	err := b.client.Call("Plugin.HandleRequest", args, &reply)
	if err != nil {
		return nil, err
	}
	if reply.Error != nil {
		if reply.Error.Error() == logical.ErrUnsupportedOperation.Error() {
			return nil, logical.ErrUnsupportedOperation
		}
		return nil, reply.Error
	}

	return reply.Response, nil
}

func (b *backendPluginClient) SpecialPaths() *logical.Paths {
	var reply SpecialPathsReply
	err := b.client.Call("Plugin.SpecialPaths", new(interface{}), &reply)
	if err != nil {
		return nil
	}

	return reply.Paths
}

// System returns vault's system view. The backend client stores the view during
// Setup, so there is no need to shim the system just to get it back.
func (b *backendPluginClient) System() logical.SystemView {
	return b.system
}

// Logger returns vault's logger. The backend client stores the logger during
// Setup, so there is no need to shim the logger just to get it back.
func (b *backendPluginClient) Logger() log.Logger {
	return b.logger
}

func (b *backendPluginClient) HandleExistenceCheck(req *logical.Request) (bool, bool, error) {
	args := &HandleExistenceCheckArgs{
		Request: req,
	}
	var reply HandleExistenceCheckReply

	err := b.client.Call("Plugin.HandleExistenceCheck", args, &reply)
	if err != nil {
		return false, false, err
	}
	if reply.Error != nil {
		// THINKING: Should be be a switch on all error types?
		if reply.Error.Error() == logical.ErrUnsupportedPath.Error() {
			return false, false, logical.ErrUnsupportedPath
		}
		return false, false, reply.Error
	}

	return reply.CheckFound, reply.Exists, nil
}

func (b *backendPluginClient) Cleanup() {
	b.client.Call("Plugin.Cleanup", new(interface{}), &struct{}{})
}

func (b *backendPluginClient) Initialize() error {
	err := b.client.Call("Plugin.Initialize", new(interface{}), &struct{}{})
	return err
}

func (b *backendPluginClient) InvalidateKey(key string) {
	b.client.Call("Plugin.InvalidateKey", key, &struct{}{})
}

func (b *backendPluginClient) Setup(config *logical.BackendConfig) error {
	// Shim logical.Storage
	storageID := b.broker.NextId()
	go b.broker.AcceptAndServe(storageID, &StorageServer{
		impl: config.StorageView,
	})

	// Shim log.Logger
	loggerID := b.broker.NextId()
	go b.broker.AcceptAndServe(loggerID, &LoggerServer{
		logger: config.Logger,
	})

	// Shim logical.SystemView
	sysViewID := b.broker.NextId()
	go b.broker.AcceptAndServe(sysViewID, &SystemViewServer{
		impl: config.System,
	})

	args := &SetupArgs{
		StorageID: storageID,
		LoggerID:  loggerID,
		SysViewID: sysViewID,
		Config:    config.Config,
	}
	var reply SetupReply

	err := b.client.Call("Plugin.Setup", args, &reply)
	if err != nil {
		return err
	}
	if reply.Error != nil {
		return reply.Error
	}

	// Set system and logger for getter methods
	b.system = config.System
	b.logger = config.Logger

	return nil
}

func (b *backendPluginClient) Type() logical.BackendType {
	var reply TypeReply
	err := b.client.Call("Plugin.Type", new(interface{}), &reply)
	if err != nil {
		return logical.TypeUnknown
	}

	return logical.BackendType(reply.Type)
}

func (b *backendPluginClient) RegisterLicense(license interface{}) error {
	var reply RegisterLicenseReply
	args := RegisterLicenseArgs{
		License: license,
	}
	err := b.client.Call("Plugin.RegisterLicense", args, &reply)
	if err != nil {
		return err
	}
	if reply.Error != nil {
		return reply.Error
	}

	return nil
}
<commit_msg>Do not send storage on HandleRequest and HandleExistenceCheck on plugins<commit_after>package plugin

import (
	"net/rpc"

	"github.com/hashicorp/go-plugin"
	"github.com/hashicorp/vault/logical"
	log "github.com/mgutz/logxi/v1"
)

// backendPluginClient implements logical.Backend and is the
// go-plugin client.
type backendPluginClient struct {
	broker       *plugin.MuxBroker
	client       *rpc.Client
	pluginClient *plugin.Client

	system logical.SystemView
	logger log.Logger
}

// HandleRequestArgs is the args for HandleRequest method.
type HandleRequestArgs struct {
	StorageID uint32
	Request   *logical.Request
}

// HandleRequestReply is the reply for HandleRequest method.
type HandleRequestReply struct {
	Response *logical.Response
	Error    *plugin.BasicError
}

// SpecialPathsReply is the reply for SpecialPaths method.
type SpecialPathsReply struct {
	Paths *logical.Paths
}

// SystemReply is the reply for System method.
type SystemReply struct {
	SystemView logical.SystemView
	Error      *plugin.BasicError
}

// HandleExistenceCheckArgs is the args for HandleExistenceCheck method.
type HandleExistenceCheckArgs struct {
	StorageID uint32
	Request   *logical.Request
}

// HandleExistenceCheckReply is the reply for HandleExistenceCheck method.
type HandleExistenceCheckReply struct {
	CheckFound bool
	Exists     bool
	Error      *plugin.BasicError
}

// SetupArgs is the args for Setup method.
type SetupArgs struct {
	StorageID uint32
	LoggerID  uint32
	SysViewID uint32
	Config    map[string]string
}

// SetupReply is the reply for Setup method.
type SetupReply struct {
	Error *plugin.BasicError
}

// TypeReply is the reply for the Type method.
type TypeReply struct {
	Type logical.BackendType
}

// RegisterLicenseArgs is the args for the RegisterLicense method.
type RegisterLicenseArgs struct {
	License interface{}
}

// RegisterLicenseReply is the reply for the RegisterLicense method.
type RegisterLicenseReply struct {
	Error *plugin.BasicError
}

func (b *backendPluginClient) HandleRequest(req *logical.Request) (*logical.Response, error) {
	// Do not send the storage, since go-plugin cannot serialize
	// interfaces. The server will pick up the storage from the shim.
	req.Storage = nil
	args := &HandleRequestArgs{
		Request: req,
	}
	var reply HandleRequestReply

	err := b.client.Call("Plugin.HandleRequest", args, &reply)
	if err != nil {
		return nil, err
	}
	if reply.Error != nil {
		if reply.Error.Error() == logical.ErrUnsupportedOperation.Error() {
			return nil, logical.ErrUnsupportedOperation
		}
		return nil, reply.Error
	}

	return reply.Response, nil
}

func (b *backendPluginClient) SpecialPaths() *logical.Paths {
	var reply SpecialPathsReply
	err := b.client.Call("Plugin.SpecialPaths", new(interface{}), &reply)
	if err != nil {
		return nil
	}

	return reply.Paths
}

// System returns vault's system view. The backend client stores the view during
// Setup, so there is no need to shim the system just to get it back.
func (b *backendPluginClient) System() logical.SystemView {
	return b.system
}

// Logger returns vault's logger. The backend client stores the logger during
// Setup, so there is no need to shim the logger just to get it back.
func (b *backendPluginClient) Logger() log.Logger {
	return b.logger
}

func (b *backendPluginClient) HandleExistenceCheck(req *logical.Request) (bool, bool, error) {
	// Do not send the storage, since go-plugin cannot serialize
	// interfaces. The server will pick up the storage from the shim.
	req.Storage = nil
	args := &HandleExistenceCheckArgs{
		Request: req,
	}
	var reply HandleExistenceCheckReply

	err := b.client.Call("Plugin.HandleExistenceCheck", args, &reply)
	if err != nil {
		return false, false, err
	}
	if reply.Error != nil {
		// THINKING: Should be be a switch on all error types?
		if reply.Error.Error() == logical.ErrUnsupportedPath.Error() {
			return false, false, logical.ErrUnsupportedPath
		}
		return false, false, reply.Error
	}

	return reply.CheckFound, reply.Exists, nil
}

func (b *backendPluginClient) Cleanup() {
	b.client.Call("Plugin.Cleanup", new(interface{}), &struct{}{})
}

func (b *backendPluginClient) Initialize() error {
	err := b.client.Call("Plugin.Initialize", new(interface{}), &struct{}{})
	return err
}

func (b *backendPluginClient) InvalidateKey(key string) {
	b.client.Call("Plugin.InvalidateKey", key, &struct{}{})
}

func (b *backendPluginClient) Setup(config *logical.BackendConfig) error {
	// Shim logical.Storage
	storageID := b.broker.NextId()
	go b.broker.AcceptAndServe(storageID, &StorageServer{
		impl: config.StorageView,
	})

	// Shim log.Logger
	loggerID := b.broker.NextId()
	go b.broker.AcceptAndServe(loggerID, &LoggerServer{
		logger: config.Logger,
	})

	// Shim logical.SystemView
	sysViewID := b.broker.NextId()
	go b.broker.AcceptAndServe(sysViewID, &SystemViewServer{
		impl: config.System,
	})

	args := &SetupArgs{
		StorageID: storageID,
		LoggerID:  loggerID,
		SysViewID: sysViewID,
		Config:    config.Config,
	}
	var reply SetupReply

	err := b.client.Call("Plugin.Setup", args, &reply)
	if err != nil {
		return err
	}
	if reply.Error != nil {
		return reply.Error
	}

	// Set system and logger for getter methods
	b.system = config.System
	b.logger = config.Logger

	return nil
}

func (b *backendPluginClient) Type() logical.BackendType {
	var reply TypeReply
	err := b.client.Call("Plugin.Type", new(interface{}), &reply)
	if err != nil {
		return logical.TypeUnknown
	}

	return logical.BackendType(reply.Type)
}

func (b *backendPluginClient) RegisterLicense(license interface{}) error {
	var reply RegisterLicenseReply
	args := RegisterLicenseArgs{
		License: license,
	}
	err := b.client.Call("Plugin.RegisterLicense", args, &reply)
	if err != nil {
		return err
	}
	if reply.Error != nil {
		return reply.Error
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"strings"

	"github.com/nlopes/slack"
	"github.com/shkh/lastfm-go/lastfm"

	"torpedobot/multibot"
)

var (
	lastfm_key    = flag.String("lastfm_key", "", "Last.FM API Key")
	lastfm_secret = flag.String("lastfm_secret", "", "Last.FM API Secret")
)

func lastfmArtist(artist string) (summary, artist_url, artist_corrected, image_url string) {
	var tags string
	lastfm_api := lastfm.New(*lastfm_key, *lastfm_secret)
	r, err := lastfm_api.Artist.GetInfo(lastfm.P{"artist": artist})
	summary = "An error occured while processing your request"
	if err == nil {
		for idx, tag := range r.Tags {
			if idx == 0 {
				tags = tag.Name
			} else {
				tags += fmt.Sprintf(", %s", tag.Name)
			}
		}

		for _, img := range r.Images {
			if img.Size == "large" {
				image_url = img.Url
				break
			}
		}

		summary = fmt.Sprintf("%s\n\nTags: %s\n", r.Bio.Summary, tags)
		artist_url = r.Url
		r, err := lastfm_api.Artist.GetCorrection(lastfm.P{"artist": artist})
		artist_corrected = artist
		if err == nil {
			artist_corrected = r.Correction.Artist.Name
		}
	}
	return
}

func lastfmTag(tag string) (result string) {
	var artists string
	lastfm_api := lastfm.New(*lastfm_key, *lastfm_secret)
	r, err := lastfm_api.Tag.GetTopArtists(lastfm.P{"tag": tag})
	result = "An error occured while processing your request"
	if err == nil {
		for idx, artist := range r.Artists {
			if idx == 0 {
				artists = artist.Name
			} else {
				artists += fmt.Sprintf(", %s", artist.Name)
			}
		}
		if artists != "" {
			result = fmt.Sprintf("Artists: %s\n", artists)
		}
	}
	return
}

func LastFmProcessMessage(api *multibot.TorpedoBotAPI, channel interface{}, incoming_message string) {
	var message string
	var params slack.PostMessageParameters
	help := "Usage: !lastfm command\nAvailable commands: artist, tag"
	command := strings.Split(strings.TrimSpace(strings.TrimLeft(incoming_message, fmt.Sprintf("%slastfm", api.CommandPrefix))), " ")[0]

	switch command {
	case "artist":
		artist := strings.TrimSpace(strings.TrimPrefix(incoming_message, fmt.Sprintf("%slastfm %s", api.CommandPrefix, command)))
		if artist != "" {
			summary, artist_url, artist_corrected, image_url := lastfmArtist(artist)
			attachment := slack.Attachment{
				Color:     "#36a64f",
				Text:      summary,
				Title:     artist_corrected,
				TitleLink: artist_url,
				ImageURL:  image_url,
			}
			params.Attachments = []slack.Attachment{attachment}
		} else {
			message = "Please supply artist: !lastfm artist artist_name"
		}
	case "tag":
		tag := strings.TrimSpace(strings.TrimPrefix(incoming_message, fmt.Sprintf("!lastfm %s", command)))
		if tag != "" {
			message = lastfmTag(tag)
		} else {
			message = "Please supply tag: !lastfm tag tag_name"
		}
	default:
		message = help
	}

	api.Bot.PostMessage(channel, message, api, params)
}
<commit_msg>lastfm<commit_after>package main

import (
	"flag"
	"fmt"
	"strings"

	"github.com/nlopes/slack"
	"github.com/tb0hdan/lastfm-go/lastfm"

	"torpedobot/multibot"
)

var (
	lastfm_key    = flag.String("lastfm_key", "", "Last.FM API Key")
	lastfm_secret = flag.String("lastfm_secret", "", "Last.FM API Secret")
)

func lastfmArtist(artist string) (summary, artist_url, artist_corrected, image_url string) {
	var tags string
	lastfm_api := lastfm.New(*lastfm_key, *lastfm_secret)
	r, err := lastfm_api.Artist.GetInfo(lastfm.P{"artist": artist})
	summary = "An error occured while processing your request"
	if err == nil {
		for idx, tag := range r.Tags {
			if idx == 0 {
				tags = tag.Name
			} else {
				tags += fmt.Sprintf(", %s", tag.Name)
			}
		}

		for _, img := range r.Images {
			if img.Size == "large" {
				image_url = img.Url
				break
			}
		}

		summary = fmt.Sprintf("%s\n\nTags: %s\n", r.Bio.Summary, tags)
		artist_url = r.Url
		r, err := lastfm_api.Artist.GetCorrection(lastfm.P{"artist": artist})
		artist_corrected = artist
		if err == nil {
			artist_corrected = r.Correction.Artist.Name
		}
	}
	return
}

func lastfmTag(tag string) (result string) {
	var artists string
	lastfm_api := lastfm.New(*lastfm_key, *lastfm_secret)
	r, err := lastfm_api.Tag.GetTopArtists(lastfm.P{"tag": tag})
	result = "An error occured while processing your request"
	if err == nil {
		for idx, artist := range r.Artists {
			if idx == 0 {
				artists = artist.Name
			} else {
				artists += fmt.Sprintf(", %s", artist.Name)
			}
		}
		if artists != "" {
			result = fmt.Sprintf("Artists: %s\n", artists)
		}
	}
	return
}

func LastFmProcessMessage(api *multibot.TorpedoBotAPI, channel interface{}, incoming_message string) {
	var message string
	var params slack.PostMessageParameters
	help := fmt.Sprintf("Usage: %slastfm command\nAvailable commands: artist, tag", api.CommandPrefix)
	command := strings.Split(strings.TrimSpace(strings.TrimLeft(incoming_message, fmt.Sprintf("%slastfm", api.CommandPrefix))), " ")[0]

	switch command {
	case "artist":
		artist := strings.TrimSpace(strings.TrimPrefix(incoming_message, fmt.Sprintf("%slastfm %s", api.CommandPrefix, command)))
		if artist != "" {
			summary, artist_url, artist_corrected, image_url := lastfmArtist(artist)
			attachment := slack.Attachment{
				Color:     "#36a64f",
				Text:      summary,
				Title:     artist_corrected,
				TitleLink: artist_url,
				ImageURL:  image_url,
			}
			params.Attachments = []slack.Attachment{attachment}
		} else {
			message = fmt.Sprintf("Please supply artist: %slastfm artist artist_name", api.CommandPrefix)
		}
	case "tag":
		tag := strings.TrimSpace(strings.TrimPrefix(incoming_message, fmt.Sprintf("%slastfm %s", api.CommandPrefix, command)))
		if tag != "" {
			message = lastfmTag(tag)
		} else {
			message = fmt.Sprintf("Please supply tag: %slastfm tag tag_name", api.CommandPrefix)
		}
	default:
		message = help
	}

	api.Bot.PostMessage(channel, message, api, params)
}
<|endoftext|>


<commit_before>package main

import (
	// stdlib
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"path/filepath"
	"regexp"
	"text/template"

	// external
	"github.com/russross/blackfriday"
)

const (
	GOIKIVERSION = "0.0.1"
)

var (
	displayVersion bool
	config         Config
)

type Config struct {
	Port    int
	Host    string
	DataDir string
}

type Page struct {
	Title string
	Body  string
}

func init() {
	flag.IntVar(&config.Port, "port", 4567, "Bind port")
	flag.StringVar(&config.Host, "host", "0.0.0.0", "Hostname or IP address to listen on")
	flag.StringVar(&config.DataDir, "data-dir", "./data", "Directory for page data")
	flag.BoolVar(&displayVersion, "version", false, "Display version and exit")
}

func (p *Page) save() error {
	filename := buildFilename(p.Title)
	return ioutil.WriteFile(filename, []byte(p.Body), 0600)
}

func buildFilename(title string) string {
	return filepath.Join(config.DataDir, (title + ".txt"))
}

func loadPage(title string) (*Page, error) {
	filename := buildFilename(title)
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return &Page{Title: title, Body: string(body)}, nil
}

func processLinks(content []byte) []byte {
	re := regexp.MustCompile(`\[([^\]]+)]\(\)`)
	return re.ReplaceAllFunc(content, func(match []byte) []byte {
		return re.ReplaceAll(match, []byte("[$1]($1)"))
	})
}

func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
		return
	}

	content := []byte(p.Body)
	content = processLinks(content)
	content = blackfriday.MarkdownCommon(content)
	p.Body = string(content)

	renderTemplate(w, "view", p)
}

func editHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		p = &Page{Title: title}
	}
	renderTemplate(w, "edit", p)
}

func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
	body := r.FormValue("body")
	p := &Page{Title: title, Body: body}
	err := p.save()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/view/"+title, http.StatusFound)
}

var templates = template.Must(template.ParseFiles("templates/edit.html", "templates/view.html"))

func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
	err := templates.ExecuteTemplate(w, tmpl+".html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9/]+)$")

func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		path := r.URL.Path
		if path == "/" {
			path = "/view/FrontPage"
		}
		m := validPath.FindStringSubmatch(path)
		if m == nil {
			http.NotFound(w, r)
			return
		}
		fn(w, r, m[2])
	}
}

func main() {
	flag.Parse()

	// Display version and exit
	if displayVersion {
		fmt.Println("Goiki", GOIKIVERSION)
		return
	}

	http.Handle("/static/", http.FileServer(http.Dir("./")))
	http.HandleFunc("/", makeHandler(viewHandler))
	http.HandleFunc("/view/", makeHandler(viewHandler))
	http.HandleFunc("/edit/", makeHandler(editHandler))
	http.HandleFunc("/save/", makeHandler(saveHandler))

	l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.Host, config.Port))
	if err != nil {
		log.Fatal(err)
	}

	s := &http.Server{}
	s.Serve(l)
	return
}
<commit_msg>Reorganize variables<commit_after>package main

import (
	// stdlib
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"path/filepath"
	"regexp"
	"text/template"

	// external
	"github.com/russross/blackfriday"
)

const (
	GOIKIVERSION = "0.0.1"
)

var (
	displayVersion bool
	config         Config
	templates      *template.Template
	validPath      *regexp.Regexp
)

type Config struct {
	Port    int
	Host    string
	DataDir string
}

type Page struct {
	Title string
	Body  string
}

func init() {
	flag.IntVar(&config.Port, "port", 4567, "Bind port")
	flag.StringVar(&config.Host, "host", "0.0.0.0", "Hostname or IP address to listen on")
	flag.StringVar(&config.DataDir, "data-dir", "./data", "Directory for page data")
	flag.BoolVar(&displayVersion, "version", false, "Display version and exit")

	templates = template.Must(template.ParseFiles("templates/edit.html", "templates/view.html"))
	validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9/]+)$")
}

func (p *Page) save() error {
	filename := buildFilename(p.Title)
	return ioutil.WriteFile(filename, []byte(p.Body), 0600)
}

func buildFilename(title string) string {
	return filepath.Join(config.DataDir, (title + ".txt"))
}

func loadPage(title string) (*Page, error) {
	filename := buildFilename(title)
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return &Page{Title: title, Body: string(body)}, nil
}

func processLinks(content []byte) []byte {
	re := regexp.MustCompile(`\[([^\]]+)]\(\)`)
	return re.ReplaceAllFunc(content, func(match []byte) []byte {
		return re.ReplaceAll(match, []byte("[$1]($1)"))
	})
}

func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
		return
	}

	content := []byte(p.Body)
	content = processLinks(content)
	content = blackfriday.MarkdownCommon(content)
	p.Body = string(content)

	renderTemplate(w, "view", p)
}

func editHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		p = &Page{Title: title}
	}
	renderTemplate(w, "edit", p)
}

func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
	body := r.FormValue("body")
	p := &Page{Title: title, Body: body}
	err := p.save()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/view/"+title, http.StatusFound)
}

func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
	err := templates.ExecuteTemplate(w, tmpl+".html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		path := r.URL.Path
		if path == "/" {
			path = "/view/FrontPage"
		}
		fmt.Println(path)
		m := validPath.FindStringSubmatch(path)
		if m == nil {
			http.NotFound(w, r)
			return
		}
		fn(w, r, m[2])
	}
}

func main() {
	flag.Parse()

	// Display version and exit
	if displayVersion {
		fmt.Println("Goiki", GOIKIVERSION)
		return
	}

	http.Handle("/static/", http.FileServer(http.Dir("./")))
	http.HandleFunc("/", makeHandler(viewHandler))
	http.HandleFunc("/view/", makeHandler(viewHandler))
	http.HandleFunc("/edit/", makeHandler(editHandler))
	http.HandleFunc("/save/", makeHandler(saveHandler))

	l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.Host, config.Port))
	if err != nil {
		log.Fatal(err)
	}

	s := &http.Server{}
	s.Serve(l)
	return
}
<|endoftext|>


<commit_before>package main

//go:generate errorgen

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"syscall"

	"v2ray.com/core"
	"v2ray.com/core/common/cmdarg"
	"v2ray.com/core/common/platform"
	_ "v2ray.com/core/main/distro/all"
)

var (
	configFiles cmdarg.Arg // "Config file for V2Ray.", the option is customed type, parse in main
	configDir   string
	version     = flag.Bool("version", false, "Show current version of V2Ray.")
	test        = flag.Bool("test", false, "Test config file only, without launching V2Ray server.")
	format      = flag.String("format", "json", "Format of input file.")

	/*  We have to do this here because Golang's Test will also need to parse flag, before
		main func in this file is run.
	*/
	_ = func() error {

		flag.Var(&configFiles, "config", "Config file for V2Ray. Multiple assign is accepted (only json). Latter ones overrides the former ones.")
		flag.Var(&configFiles, "c", "Short alias of -config")
		flag.StringVar(&configDir, "confdir", "", "A dir with multiple json config")

		return nil
	}()
)

func fileExists(file string) bool {
	info, err := os.Stat(file)
	return err == nil && !info.IsDir()
}

func dirExists(file string) bool {
	info, err := os.Stat(file)
	return err == nil && info.IsDir()
}

func readConfDir(dirPath string) {
	confs, err := ioutil.ReadDir(dirPath)
	if err != nil {
		log.Fatalln(err)
	}
	for _, f := range confs {
		if strings.HasSuffix(f.Name(), ".json") {
			configFiles.Set(path.Join(dirPath, f.Name()))
		}
	}
}

func getConfigFilePath() (cmdarg.Arg, error) {
	if dirExists(configDir) {
		readConfDir(configDir)
	}
	if len(configFiles) > 0 {
		return configFiles, nil
	}

	if workingDir, err := os.Getwd(); err == nil {
		configFile := filepath.Join(workingDir, "config.json")
		if fileExists(configFile) {
			log.Println("Using default config: ", configFile)
			return cmdarg.Arg{configFile}, nil
		}
	}

	if configFile := platform.GetConfigurationPath(); fileExists(configFile) {
		log.Println("Using config from env: ", configFile)
		return cmdarg.Arg{configFile}, nil
	}

	if envConfDir := platform.GetConfDirPath(); dirExists(envConfDir) {
		log.Println("Using confdir from env: ", envConfDir)
		readConfDir(envConfDir)
		if len(configFiles) > 0 {
			return configFiles, nil
		}
	}

	log.Println("Using config from STDIN")
	return cmdarg.Arg{"stdin:"}, nil
}

func GetConfigFormat() string {
	switch strings.ToLower(*format) {
	case "pb", "protobuf":
		return "protobuf"
	default:
		return "json"
	}
}

func startV2Ray() (core.Server, error) {
	configFiles, err := getConfigFilePath()
	if err != nil {
		return nil, err
	}

	config, err := core.LoadConfig(GetConfigFormat(), configFiles[0], configFiles)
	if err != nil {
		return nil, newError("failed to read config files: [", configFiles.String(), "]").Base(err)
	}

	server, err := core.New(config)
	if err != nil {
		return nil, newError("failed to create server").Base(err)
	}

	return server, nil
}

func printVersion() {
	version := core.VersionStatement()
	for _, s := range version {
		fmt.Println(s)
	}
}

func main() {

	flag.Parse()

	printVersion()

	if *version {
		return
	}

	server, err := startV2Ray()
	if err != nil {
		fmt.Println(err)
		// Configuration error. Exit with a special value to prevent systemd from restarting.
		os.Exit(23)
	}

	if *test {
		fmt.Println("Configuration OK.")
		os.Exit(0)
	}

	if err := server.Start(); err != nil {
		fmt.Println("Failed to start", err)
		os.Exit(-1)
	}
	defer server.Close()

	// Explicitly triggering GC to remove garbage from config loading.
	runtime.GC()

	{
		osSignals := make(chan os.Signal, 1)
		signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM)
		<-osSignals
	}
}
<commit_msg>fix confdir env startup priority<commit_after>package main

//go:generate errorgen

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"syscall"

	"v2ray.com/core"
	"v2ray.com/core/common/cmdarg"
	"v2ray.com/core/common/platform"
	_ "v2ray.com/core/main/distro/all"
)

var (
	configFiles cmdarg.Arg // "Config file for V2Ray.", the option is customed type, parse in main
	configDir   string
	version     = flag.Bool("version", false, "Show current version of V2Ray.")
	test        = flag.Bool("test", false, "Test config file only, without launching V2Ray server.")
	format      = flag.String("format", "json", "Format of input file.")

	/*  We have to do this here because Golang's Test will also need to parse flag, before
		main func in this file is run.
	*/
	_ = func() error {

		flag.Var(&configFiles, "config", "Config file for V2Ray. Multiple assign is accepted (only json). Latter ones overrides the former ones.")
		flag.Var(&configFiles, "c", "Short alias of -config")
		flag.StringVar(&configDir, "confdir", "", "A dir with multiple json config")

		return nil
	}()
)

func fileExists(file string) bool {
	info, err := os.Stat(file)
	return err == nil && !info.IsDir()
}

func dirExists(file string) bool {
	if file == "" {
		return false
	}
	info, err := os.Stat(file)
	return err == nil && info.IsDir()
}

func readConfDir(dirPath string) {
	confs, err := ioutil.ReadDir(dirPath)
	if err != nil {
		log.Fatalln(err)
	}
	for _, f := range confs {
		if strings.HasSuffix(f.Name(), ".json") {
			configFiles.Set(path.Join(dirPath, f.Name()))
		}
	}
}

func getConfigFilePath() (cmdarg.Arg, error) {
	if dirExists(configDir) {
		log.Println("Using confdir from arg:", configDir)
		readConfDir(configDir)
	} else {
		if envConfDir := platform.GetConfDirPath(); dirExists(envConfDir) {
			log.Println("Using confdir from env:", envConfDir)
			readConfDir(envConfDir)
			if len(configFiles) > 0 {
				return configFiles, nil
			}
		}
	}

	if len(configFiles) > 0 {
		return configFiles, nil
	}

	if workingDir, err := os.Getwd(); err == nil {
		configFile := filepath.Join(workingDir, "config.json")
		if fileExists(configFile) {
			log.Println("Using default config: ", configFile)
			return cmdarg.Arg{configFile}, nil
		}
	}

	if configFile := platform.GetConfigurationPath(); fileExists(configFile) {
		log.Println("Using config from env: ", configFile)
		return cmdarg.Arg{configFile}, nil
	}

	log.Println("Using config from STDIN")
	return cmdarg.Arg{"stdin:"}, nil
}

func GetConfigFormat() string {
	switch strings.ToLower(*format) {
	case "pb", "protobuf":
		return "protobuf"
	default:
		return "json"
	}
}

func startV2Ray() (core.Server, error) {
	configFiles, err := getConfigFilePath()
	if err != nil {
		return nil, err
	}

	config, err := core.LoadConfig(GetConfigFormat(), configFiles[0], configFiles)
	if err != nil {
		return nil, newError("failed to read config files: [", configFiles.String(), "]").Base(err)
	}

	server, err := core.New(config)
	if err != nil {
		return nil, newError("failed to create server").Base(err)
	}

	return server, nil
}

func printVersion() {
	version := core.VersionStatement()
	for _, s := range version {
		fmt.Println(s)
	}
}

func main() {

	flag.Parse()

	printVersion()

	if *version {
		return
	}

	server, err := startV2Ray()
	if err != nil {
		fmt.Println(err)
		// Configuration error. Exit with a special value to prevent systemd from restarting.
		os.Exit(23)
	}

	if *test {
		fmt.Println("Configuration OK.")
		os.Exit(0)
	}

	if err := server.Start(); err != nil {
		fmt.Println("Failed to start", err)
		os.Exit(-1)
	}
	defer server.Close()

	// Explicitly triggering GC to remove garbage from config loading.
	runtime.GC()

	{
		osSignals := make(chan os.Signal, 1)
		signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM)
		<-osSignals
	}
}
<|endoftext|>


<commit_before>// This file was generated by counterfeiter
package cryptofakes

import (
	"os"
	"sync"

	"github.com/cloudfoundry/bosh-cli/vendor/github.com/cloudfoundry/bosh-utils/crypto"
	"github.com/cloudfoundry/bosh-utils/system"
)

type FakeArchiveDigestFilePathReader struct {
	OpenFileStub        func(path string, flag int, perm os.FileMode) (system.File, error)
	openFileMutex       sync.RWMutex
	openFileArgsForCall []struct {
		path string
		flag int
		perm os.FileMode
	}
	openFileReturns struct {
		result1 system.File
		result2 error
	}
	invocations      map[string][][]interface{}
	invocationsMutex sync.RWMutex
}

func (fake *FakeArchiveDigestFilePathReader) OpenFile(path string, flag int, perm os.FileMode) (system.File, error) {
	fake.openFileMutex.Lock()
	fake.openFileArgsForCall = append(fake.openFileArgsForCall, struct {
		path string
		flag int
		perm os.FileMode
	}{path, flag, perm})
	fake.recordInvocation("OpenFile", []interface{}{path, flag, perm})
	fake.openFileMutex.Unlock()
	if fake.OpenFileStub != nil {
		return fake.OpenFileStub(path, flag, perm)
	} else {
		return fake.openFileReturns.result1, fake.openFileReturns.result2
	}
}

func (fake *FakeArchiveDigestFilePathReader) OpenFileCallCount() int {
	fake.openFileMutex.RLock()
	defer fake.openFileMutex.RUnlock()
	return len(fake.openFileArgsForCall)
}

func (fake *FakeArchiveDigestFilePathReader) OpenFileArgsForCall(i int) (string, int, os.FileMode) {
	fake.openFileMutex.RLock()
	defer fake.openFileMutex.RUnlock()
	return fake.openFileArgsForCall[i].path, fake.openFileArgsForCall[i].flag, fake.openFileArgsForCall[i].perm
}

func (fake *FakeArchiveDigestFilePathReader) OpenFileReturns(result1 system.File, result2 error) {
	fake.OpenFileStub = nil
	fake.openFileReturns = struct {
		result1 system.File
		result2 error
	}{result1, result2}
}

func (fake *FakeArchiveDigestFilePathReader) Invocations() map[string][][]interface{} {
	fake.invocationsMutex.RLock()
	defer fake.invocationsMutex.RUnlock()
	fake.openFileMutex.RLock()
	defer fake.openFileMutex.RUnlock()
	return fake.invocations
}

func (fake *FakeArchiveDigestFilePathReader) recordInvocation(key string, args []interface{}) {
	fake.invocationsMutex.Lock()
	defer fake.invocationsMutex.Unlock()
	if fake.invocations == nil {
		fake.invocations = map[string][][]interface{}{}
	}
	if fake.invocations[key] == nil {
		fake.invocations[key] = [][]interface{}{}
	}
	fake.invocations[key] = append(fake.invocations[key], args)
}

var _ crypto.ArchiveDigestFilePathReader = new(FakeArchiveDigestFilePathReader)
<commit_msg>Fix import path in counterfeiter fake<commit_after>// This file was generated by counterfeiter
package cryptofakes

import (
	"os"
	"sync"

	"github.com/cloudfoundry/bosh-utils/crypto"
	"github.com/cloudfoundry/bosh-utils/system"
)

type FakeArchiveDigestFilePathReader struct {
	OpenFileStub        func(path string, flag int, perm os.FileMode) (system.File, error)
	openFileMutex       sync.RWMutex
	openFileArgsForCall []struct {
		path string
		flag int
		perm os.FileMode
	}
	openFileReturns struct {
		result1 system.File
		result2 error
	}
	invocations      map[string][][]interface{}
	invocationsMutex sync.RWMutex
}

func (fake *FakeArchiveDigestFilePathReader) OpenFile(path string, flag int, perm os.FileMode) (system.File, error) {
	fake.openFileMutex.Lock()
	fake.openFileArgsForCall = append(fake.openFileArgsForCall, struct {
		path string
		flag int
		perm os.FileMode
	}{path, flag, perm})
	fake.recordInvocation("OpenFile", []interface{}{path, flag, perm})
	fake.openFileMutex.Unlock()
	if fake.OpenFileStub != nil {
		return fake.OpenFileStub(path, flag, perm)
	} else {
		return fake.openFileReturns.result1, fake.openFileReturns.result2
	}
}

func (fake *FakeArchiveDigestFilePathReader) OpenFileCallCount() int {
	fake.openFileMutex.RLock()
	defer fake.openFileMutex.RUnlock()
	return len(fake.openFileArgsForCall)
}

func (fake *FakeArchiveDigestFilePathReader) OpenFileArgsForCall(i int) (string, int, os.FileMode) {
	fake.openFileMutex.RLock()
	defer fake.openFileMutex.RUnlock()
	return fake.openFileArgsForCall[i].path, fake.openFileArgsForCall[i].flag, fake.openFileArgsForCall[i].perm
}

func (fake *FakeArchiveDigestFilePathReader) OpenFileReturns(result1 system.File, result2 error) {
	fake.OpenFileStub = nil
	fake.openFileReturns = struct {
		result1 system.File
		result2 error
	}{result1, result2}
}

func (fake *FakeArchiveDigestFilePathReader) Invocations() map[string][][]interface{} {
	fake.invocationsMutex.RLock()
	defer fake.invocationsMutex.RUnlock()
	fake.openFileMutex.RLock()
	defer fake.openFileMutex.RUnlock()
	return fake.invocations
}

func (fake *FakeArchiveDigestFilePathReader) recordInvocation(key string, args []interface{}) {
	fake.invocationsMutex.Lock()
	defer fake.invocationsMutex.Unlock()
	if fake.invocations == nil {
		fake.invocations = map[string][][]interface{}{}
	}
	if fake.invocations[key] == nil {
		fake.invocations[key] = [][]interface{}{}
	}
	fake.invocations[key] = append(fake.invocations[key], args)
}

var _ crypto.ArchiveDigestFilePathReader = new(FakeArchiveDigestFilePathReader)
<|endoftext|>


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

// Package ghistogram provides a simple histogram of uint64's that
// avoids heap allocations (garbage creation) during data processing.
package ghistogram

import (
	"bytes"
	"fmt"
	"math"
	"strconv"
	"sync"
)

// Histogram is a simple uint64 histogram implementation that avoids
// heap allocations during its processing of incoming data points.
//
// It was motivated for tracking simple performance timings.
//
// The histogram bins are split across the two arrays of Ranges and
// Counts, where len(Ranges) == len(Counts).  These arrays are public
// in case users wish to use reflection or JSON marhsaling.
//
// An optional growth factor for bin sizes is supported - see
// NewHistogram() binGrowthFactor parameter.
//
// The histogram is concurrent safe.
type Histogram struct {
	// Ranges holds the lower domain bounds of bins, so bin i has data
	// point domain of "[Ranges[i], Ranges[i+1])".  Related,
	// Ranges[0] == 0 and Ranges[1] == binFirst.
	Ranges []uint64

	// Counts holds the event counts for bins.
	Counts []uint64

	MinDataPoint uint64
	MaxDataPoint uint64

	m sync.Mutex
}

// NewHistogram creates a new, ready to use Histogram.  The numBins
// must be >= 2.  The binFirst is the width of the first bin.  The
// binGrowthFactor must be > 1.0 or 0.0.
//
// A special case of binGrowthFactor of 0.0 means the the allocated
// bins will have constant, non-growing size or "width".
func NewHistogram(
	numBins int,
	binFirst uint64,
	binGrowthFactor float64) *Histogram {
	gh := &Histogram{
		Ranges: make([]uint64, numBins),
		Counts: make([]uint64, numBins),

		MinDataPoint: math.MaxUint64,
		MaxDataPoint: 0,
	}

	gh.Ranges[0] = 0
	gh.Ranges[1] = binFirst

	for i := 2; i < len(gh.Ranges); i++ {
		if binGrowthFactor == 0.0 {
			gh.Ranges[i] = gh.Ranges[i-1] + binFirst
		} else {
			gh.Ranges[i] =
				uint64(math.Ceil(binGrowthFactor * float64(gh.Ranges[i-1])))
		}
	}

	return gh
}

// Add increases the count in the bin for the given dataPoint.
func (gh *Histogram) Add(dataPoint uint64, count uint64) {
	gh.m.Lock()

	idx := search(gh.Ranges, dataPoint)
	if idx >= 0 {
		gh.Counts[idx] += count
	}
	if gh.MinDataPoint > count {
		gh.MinDataPoint = count
	}
	if gh.MaxDataPoint < count {
		gh.MaxDataPoint = count
	}

	gh.m.Unlock()
}

// Finds the last arr index where the arr entry <= dataPoint.
func search(arr []uint64, dataPoint uint64) int {
	i, j := 0, len(arr)

	for i < j {
		h := i + (j-i)/2 // Avoids h overflow, where i <= h < j.
		if dataPoint >= arr[h] {
			i = h + 1
		} else {
			j = h
		}
	}

	return i - 1
}

// AddAll adds all the Counts from the src histogram into this
// histogram.  The src and this histogram must either have the same
// exact creation parameters.
func (gh *Histogram) AddAll(src *Histogram) {
	src.m.Lock()
	gh.m.Lock()

	for i := 0; i < len(src.Counts); i++ {
		gh.Counts[i] += src.Counts[i]
	}
	if gh.MinDataPoint > src.MinDataPoint {
		gh.MinDataPoint = src.MinDataPoint
	}
	if gh.MaxDataPoint < src.MaxDataPoint {
		gh.MaxDataPoint = src.MaxDataPoint
	}

	gh.m.Unlock()
	src.m.Unlock()
}

// Graph emits an ascii graph to the optional out buffer, allocating a
// out buffer if none was supplied.  Returns the out buffer.  Each
// line emitted may have an optional prefix.
//
// For example:
//       0+  10=2 10.00% ********
//      10+  10=1 10.00% ****
//      20+  10=3 10.00% ************
func (gh *Histogram) EmitGraph(prefix []byte,
	out *bytes.Buffer) *bytes.Buffer {
	gh.m.Lock()

	ranges := gh.Ranges
	rangesN := len(ranges)
	counts := gh.Counts
	countsN := len(counts)

	if out == nil {
		out = bytes.NewBuffer(make([]byte, 0, 80*countsN))
	}

	var totCount uint64
	var maxCount uint64
	for _, c := range counts {
		totCount += c
		if maxCount < c {
			maxCount = c
		}
	}
	totCountF := float64(totCount)
	maxCountF := float64(maxCount)

	widthRange := len(strconv.Itoa(int(ranges[rangesN-1])))
	widthWidth := len(strconv.Itoa(int(ranges[rangesN-1] - ranges[rangesN-2])))
	widthCount := len(strconv.Itoa(int(maxCount)))

	// Each line looks like: "[prefix]START+WIDTH=COUNT PCT% BAR\n"
	f := fmt.Sprintf("%%%dd+%%%dd=%%%dd%% 7.2f%%%%",
		widthRange, widthWidth, widthCount)

	var runCount uint64 // Running total while emitting lines.

	barLen := float64(len(bar))

	for i, c := range counts {
		if prefix != nil {
			out.Write(prefix)
		}

		var width uint64
		if i < countsN-1 {
			width = uint64(ranges[i+1] - ranges[i])
		}

		runCount += c
		fmt.Fprintf(out, f, ranges[i], width, c,
			100.0*(float64(runCount)/totCountF))

		if c > 0 {
			out.Write([]byte(" "))
			barWant := int(math.Floor(barLen * (float64(c) / maxCountF)))
			out.Write(bar[0:barWant])
		}

		out.Write([]byte("\n"))
	}

	gh.m.Unlock()

	return out
}

var bar = []byte("******************************")
<commit_msg>track TotCount<commit_after>//  Copyright (c) 2015 Couchbase, Inc.
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the
//  License. You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//  Unless required by applicable law or agreed to in writing,
//  software distributed under the License is distributed on an "AS
//  IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
//  express or implied. See the License for the specific language
//  governing permissions and limitations under the License.

// Package ghistogram provides a simple histogram of uint64's that
// avoids heap allocations (garbage creation) during data processing.
package ghistogram

import (
	"bytes"
	"fmt"
	"math"
	"strconv"
	"sync"
)

// Histogram is a simple uint64 histogram implementation that avoids
// heap allocations during its processing of incoming data points.
//
// It was motivated for tracking simple performance timings.
//
// The histogram bins are split across the two arrays of Ranges and
// Counts, where len(Ranges) == len(Counts).  These arrays are public
// in case users wish to use reflection or JSON marhsaling.
//
// An optional growth factor for bin sizes is supported - see
// NewHistogram() binGrowthFactor parameter.
//
// The histogram is concurrent safe.
type Histogram struct {
	// Ranges holds the lower domain bounds of bins, so bin i has data
	// point domain of "[Ranges[i], Ranges[i+1])".  Related,
	// Ranges[0] == 0 and Ranges[1] == binFirst.
	Ranges []uint64

	// Counts holds the event counts for bins.
	Counts []uint64

	TotCount     uint64
	MinDataPoint uint64
	MaxDataPoint uint64

	m sync.Mutex
}

// NewHistogram creates a new, ready to use Histogram.  The numBins
// must be >= 2.  The binFirst is the width of the first bin.  The
// binGrowthFactor must be > 1.0 or 0.0.
//
// A special case of binGrowthFactor of 0.0 means the the allocated
// bins will have constant, non-growing size or "width".
func NewHistogram(
	numBins int,
	binFirst uint64,
	binGrowthFactor float64) *Histogram {
	gh := &Histogram{
		Ranges:       make([]uint64, numBins),
		Counts:       make([]uint64, numBins),
		TotCount:     0,
		MinDataPoint: math.MaxUint64,
		MaxDataPoint: 0,
	}

	gh.Ranges[0] = 0
	gh.Ranges[1] = binFirst

	for i := 2; i < len(gh.Ranges); i++ {
		if binGrowthFactor == 0.0 {
			gh.Ranges[i] = gh.Ranges[i-1] + binFirst
		} else {
			gh.Ranges[i] =
				uint64(math.Ceil(binGrowthFactor * float64(gh.Ranges[i-1])))
		}
	}

	return gh
}

// Add increases the count in the bin for the given dataPoint.
func (gh *Histogram) Add(dataPoint uint64, count uint64) {
	gh.m.Lock()

	idx := search(gh.Ranges, dataPoint)
	if idx >= 0 {
		gh.Counts[idx] += count

		gh.TotCount += count

		if gh.MinDataPoint > count {
			gh.MinDataPoint = count
		}

		if gh.MaxDataPoint < count {
			gh.MaxDataPoint = count
		}
	}

	gh.m.Unlock()
}

// Finds the last arr index where the arr entry <= dataPoint.
func search(arr []uint64, dataPoint uint64) int {
	i, j := 0, len(arr)

	for i < j {
		h := i + (j-i)/2 // Avoids h overflow, where i <= h < j.
		if dataPoint >= arr[h] {
			i = h + 1
		} else {
			j = h
		}
	}

	return i - 1
}

// AddAll adds all the Counts from the src histogram into this
// histogram.  The src and this histogram must either have the same
// exact creation parameters.
func (gh *Histogram) AddAll(src *Histogram) {
	src.m.Lock()
	gh.m.Lock()

	for i := 0; i < len(src.Counts); i++ {
		gh.Counts[i] += src.Counts[i]
	}

	gh.TotCount += src.TotCount

	if gh.MinDataPoint > src.MinDataPoint {
		gh.MinDataPoint = src.MinDataPoint
	}

	if gh.MaxDataPoint < src.MaxDataPoint {
		gh.MaxDataPoint = src.MaxDataPoint
	}

	gh.m.Unlock()
	src.m.Unlock()
}

// Graph emits an ascii graph to the optional out buffer, allocating a
// out buffer if none was supplied.  Returns the out buffer.  Each
// line emitted may have an optional prefix.
//
// For example:
//       0+  10=2 10.00% ********
//      10+  10=1 10.00% ****
//      20+  10=3 10.00% ************
func (gh *Histogram) EmitGraph(prefix []byte,
	out *bytes.Buffer) *bytes.Buffer {
	gh.m.Lock()

	ranges := gh.Ranges
	rangesN := len(ranges)
	counts := gh.Counts
	countsN := len(counts)

	if out == nil {
		out = bytes.NewBuffer(make([]byte, 0, 80*countsN))
	}

	var maxCount uint64
	for _, c := range counts {
		if maxCount < c {
			maxCount = c
		}
	}
	maxCountF := float64(maxCount)
	totCountF := float64(gh.TotCount)

	widthRange := len(strconv.Itoa(int(ranges[rangesN-1])))
	widthWidth := len(strconv.Itoa(int(ranges[rangesN-1] - ranges[rangesN-2])))
	widthCount := len(strconv.Itoa(int(maxCount)))

	// Each line looks like: "[prefix]START+WIDTH=COUNT PCT% BAR\n"
	f := fmt.Sprintf("%%%dd+%%%dd=%%%dd%% 7.2f%%%%",
		widthRange, widthWidth, widthCount)

	var runCount uint64 // Running total while emitting lines.

	barLen := float64(len(bar))

	for i, c := range counts {
		if prefix != nil {
			out.Write(prefix)
		}

		var width uint64
		if i < countsN-1 {
			width = uint64(ranges[i+1] - ranges[i])
		}

		runCount += c
		fmt.Fprintf(out, f, ranges[i], width, c,
			100.0*(float64(runCount)/totCountF))

		if c > 0 {
			out.Write([]byte(" "))
			barWant := int(math.Floor(barLen * (float64(c) / maxCountF)))
			out.Write(bar[0:barWant])
		}

		out.Write([]byte("\n"))
	}

	gh.m.Unlock()

	return out
}

var bar = []byte("******************************")
<|endoftext|>


<commit_before>package json_test

import (
	"bytes"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"

	"github.com/apex/log"
	"github.com/apex/log/handlers/json"
)

func init() {
	log.Now = func() time.Time {
		return time.Unix(0, 0)
	}
}

func Test(t *testing.T) {
	var buf bytes.Buffer

	log.SetHandler(json.New(&buf))
	log.WithField("user", "tj").WithField("id", "123").Info("hello")
	log.Info("world")
	log.Error("boom")

	expected := `{"fields":{"id":"123","user":"tj"},"level":"info","timestamp":"1969-12-31T16:00:00-08:00","message":"hello"}
{"fields":{},"level":"info","timestamp":"1969-12-31T16:00:00-08:00","message":"world"}
{"fields":{},"level":"error","timestamp":"1969-12-31T16:00:00-08:00","message":"boom"}
`

	assert.Equal(t, expected, buf.String())
}
<commit_msg>fix json tests in CI<commit_after>package json_test

import (
	"bytes"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"

	"github.com/apex/log"
	"github.com/apex/log/handlers/json"
)

func init() {
	log.Now = func() time.Time {
		return time.Unix(0, 0).UTC()
	}
}

func Test(t *testing.T) {
	var buf bytes.Buffer

	log.SetHandler(json.New(&buf))
	log.WithField("user", "tj").WithField("id", "123").Info("hello")
	log.Info("world")
	log.Error("boom")

	expected := `{"fields":{"id":"123","user":"tj"},"level":"info","timestamp":"1970-01-01T00:00:00Z","message":"hello"}
{"fields":{},"level":"info","timestamp":"1970-01-01T00:00:00Z","message":"world"}
{"fields":{},"level":"error","timestamp":"1970-01-01T00:00:00Z","message":"boom"}
`

	assert.Equal(t, expected, buf.String())
}
<|endoftext|>