<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"math/big"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"
)

func init() {
	flag.Parse()
}

var (
	pt   = fmt.Printf
	sp   = fmt.Sprintf
	fp   = fmt.Fprintf
	zero = new(big.Rat)
)

func main() {
	args := flag.Args()
	if len(args) < 1 {
		pt("usage: %s [file]\n", os.Args[0])
		return
	}

	type Entry struct {
		Account  string
		Currency string
		Amount   *big.Rat
	}
	type Transaction struct {
		When    time.Time
		What    string
		Entries []Entry
	}

	// parse
	location, err := time.LoadLocation("Asia/Hong_Kong")
	ce(err, "load location")
	transactions := []Transaction{}
	bs, err := ioutil.ReadFile(args[0])
	ce(err, "read file")
	entries := strings.Split(string(bs), "\n\n")
	for _, bs := range entries {
		bs = strings.TrimSpace(bs)
		lines := Strs(strings.Split(bs, "\n"))
		lines = lines.Filter(func(s string) bool {
			return !strings.HasPrefix(s, "#")
		})
		if len(lines) == 0 {
			continue
		}
		when, what := spaceSplit(strings.TrimSpace(lines[0]))
		if len(when) == 0 {
			continue
		}
		parts := strings.Split(when, "-")
		year, err := strconv.Atoi(parts[0])
		ce(err, "parse year")
		if year < 100 {
			year += 2000
		}
		month, err := strconv.Atoi(parts[1])
		ce(err, "parse month")
		day, err := strconv.Atoi(parts[2])
		ce(err, "parse day")
		transaction := Transaction{
			When: time.Date(year, time.Month(month), day, 0, 0, 0, 0, location),
			What: what,
		}
		for _, line := range lines[1:] {
			line = strings.TrimSpace(line)
			if len(line) == 0 {
				continue
			}
			account, res := spaceSplit(line)
			entry := Entry{
				Account: account,
			}
			if len(res) == 0 {
				log.Fatalf("invalid entry %s", line)
			}
			runes := []rune(res)
			currency := string(runes[0])
			entry.Currency = currency
			amount := new(big.Rat)
			_, err := fmt.Sscan(string(runes[1:]), amount)
			ce(err, sp("parse amount %v", string(runes[1:])))
			entry.Amount = amount
			transaction.Entries = append(transaction.Entries, entry)
		}
		transactions = append(transactions, transaction)
	}

	// calculate balance
	zero := new(big.Rat)
	for _, transaction := range transactions {
		balance := make(map[string]*big.Rat)
		for _, entry := range transaction.Entries {
			if _, ok := balance[entry.Currency]; !ok {
				balance[entry.Currency] = new(big.Rat)
			}
			balance[entry.Currency].Add(balance[entry.Currency], entry.Amount)
		}
		for _, n := range balance {
			if n.Cmp(zero) != 0 {
				log.Fatalf("not balance: %s", transaction.What)
			}
		}
	}

	// account summaries
	accounts := make(map[string]map[string]*big.Rat)
	sum := func(name, currency string, n *big.Rat) {
		var account map[string]*big.Rat
		var ok bool
		if account, ok = accounts[name]; !ok {
			account = make(map[string]*big.Rat)
			accounts[name] = account
		}
		var amount *big.Rat
		if amount, ok = account[currency]; !ok {
			amount = new(big.Rat)
		}
		amount.Add(amount, n)
		account[currency] = amount
	}
	for _, transaction := range transactions {
		for _, entry := range transaction.Entries {
			var name []rune
			for _, r := range entry.Account {
				if r == '：' {
					sum(string(name), entry.Currency, entry.Amount)
				}
				name = append(name, r)
			}
			sum(string(name), entry.Currency, entry.Amount)
		}
	}
	names := []string{}
	for name := range accounts {
		names = append(names, name)
	}
	sort.Strings(names)
	for _, name := range names {
		account := accounts[name]
		n := []rune{}
		level := 0
		for _, r := range name {
			if r == '：' {
				n = n[0:0]
				level++
			} else {
				n = append(n, r)
			}
		}
		buf := new(bytes.Buffer)
		fp(buf, "%s%s", strings.Repeat("\t", level), string(n))
		nonZero := false
		for currency, amount := range account {
			if amount.Cmp(zero) != 0 {
				nonZero = true
				fp(buf, " %s%s", currency, amount.FloatString(2))
			}
		}
		fp(buf, "\n")
		if nonZero {
			pt("%s", buf.Bytes())
		}
	}

}

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

func spaceSplit(s string) (string, string) {
	ss := spaceSplitPattern.Split(s, 2)
	if len(ss) == 1 {
		return ss[0], ""
	}
	return ss[0], ss[1]
}
<commit_msg>show debit and credit of each account; make output align<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"math/big"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"

	"golang.org/x/text/width"
)

func init() {
	flag.Parse()
}

var (
	pt   = fmt.Printf
	sp   = fmt.Sprintf
	fp   = fmt.Fprintf
	zero = new(big.Rat)
)

func main() {
	args := flag.Args()
	if len(args) < 1 {
		pt("usage: %s [file]\n", os.Args[0])
		return
	}

	type Currency string
	type Entry struct {
		Account  string
		Currency Currency
		Amount   *big.Rat
	}
	type Transaction struct {
		When    time.Time
		What    string
		Entries []Entry
	}

	// parse
	location, err := time.LoadLocation("Asia/Hong_Kong")
	ce(err, "load location")
	transactions := []Transaction{}
	bs, err := ioutil.ReadFile(args[0])
	ce(err, "read file")
	entries := strings.Split(string(bs), "\n\n")
	for _, bs := range entries {
		bs = strings.TrimSpace(bs)
		lines := Strs(strings.Split(bs, "\n"))
		lines = lines.Filter(func(s string) bool {
			return !strings.HasPrefix(s, "#")
		})
		if len(lines) == 0 {
			continue
		}
		when, what := spaceSplit(strings.TrimSpace(lines[0]))
		if len(when) == 0 {
			continue
		}
		parts := strings.Split(when, "-")
		year, err := strconv.Atoi(parts[0])
		ce(err, "parse year")
		if year < 100 {
			year += 2000
		}
		month, err := strconv.Atoi(parts[1])
		ce(err, "parse month")
		day, err := strconv.Atoi(parts[2])
		ce(err, "parse day")
		transaction := Transaction{
			When: time.Date(year, time.Month(month), day, 0, 0, 0, 0, location),
			What: what,
		}
		for _, line := range lines[1:] {
			line = strings.TrimSpace(line)
			if len(line) == 0 {
				continue
			}
			account, res := spaceSplit(line)
			entry := Entry{
				Account: account,
			}
			if len(res) == 0 {
				log.Fatalf("invalid entry %s", line)
			}
			runes := []rune(res)
			currency := Currency(runes[0])
			entry.Currency = currency
			amount := new(big.Rat)
			_, err := fmt.Sscan(string(runes[1:]), amount)
			ce(err, sp("parse amount %v", string(runes[1:])))
			entry.Amount = amount
			transaction.Entries = append(transaction.Entries, entry)
		}
		transactions = append(transactions, transaction)
	}

	// calculate balance
	zero := new(big.Rat)
	for _, transaction := range transactions {
		balance := make(map[Currency]*big.Rat)
		for _, entry := range transaction.Entries {
			if _, ok := balance[entry.Currency]; !ok {
				balance[entry.Currency] = new(big.Rat)
			}
			balance[entry.Currency].Add(balance[entry.Currency], entry.Amount)
		}
		for _, n := range balance {
			if n.Cmp(zero) != 0 {
				log.Fatalf("not balance: %s", transaction.What)
			}
		}
	}

	type Amount struct {
		Debit  *big.Rat
		Credit *big.Rat
	}
	type Account map[Currency]*Amount

	// account summaries
	accounts := make(map[string]Account)
	sum := func(name string, currency Currency, n *big.Rat) {
		var account Account
		var ok bool
		if account, ok = accounts[name]; !ok {
			account = make(Account)
			accounts[name] = account
		}
		var amount *Amount
		if amount, ok = account[currency]; !ok {
			amount = &Amount{
				Debit:  new(big.Rat),
				Credit: new(big.Rat),
			}
		}
		if n.Sign() == -1 {
			amount.Credit.Add(amount.Credit, n)
		} else {
			amount.Debit.Add(amount.Debit, n)
		}
		account[currency] = amount
	}
	for _, transaction := range transactions {
		for _, entry := range transaction.Entries {
			var name []rune
			for _, r := range entry.Account {
				if r == '：' {
					sum(string(name), entry.Currency, entry.Amount)
				}
				name = append(name, r)
			}
			sum(string(name), entry.Currency, entry.Amount)
		}
	}
	names := []string{}
	maxNameLen := 0
	for name := range accounts {
		names = append(names, name)
		nameLen := 0
		level := 0
		for _, r := range name {
			if r == '：' {
				level++
				nameLen = level * 2
			} else if width.LookupRune(r).Kind() == width.EastAsianWide {
				nameLen += 2
			} else {
				nameLen += 1
			}
			if nameLen > maxNameLen {
				maxNameLen = nameLen
			}
		}
	}
	sort.Strings(names)
	for _, name := range names {
		account := accounts[name]
		n := []rune{}
		level := 0
		for _, r := range name {
			if r == '：' {
				n = n[0:0]
				level++
			} else {
				n = append(n, r)
			}
		}
		buf := new(bytes.Buffer)
		buf.WriteString(pad(strings.Repeat("  ", level)+string(n), maxNameLen))
		nonZero := false
		for currency, amount := range account {
			balance := new(big.Rat)
			balance.Set(amount.Credit)
			balance.Add(balance, amount.Debit)
			if balance.Sign() != 0 {
				nonZero = true
				credit := new(big.Rat)
				credit.Set(amount.Credit)
				credit.Abs(credit)
				fp(buf, " %s%s %s - %s", currency,
					pad(balance.FloatString(2), 10),
					pad(amount.Debit.FloatString(2), 10),
					pad(credit.FloatString(2), 10),
				)
			}
		}
		fp(buf, "\n")
		if nonZero {
			pt("%s", buf.Bytes())
		}
	}

}

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

func spaceSplit(s string) (string, string) {
	ss := spaceSplitPattern.Split(s, 2)
	if len(ss) == 1 {
		return ss[0], ""
	}
	return ss[0], ss[1]
}

func pad(s string, l int) string {
	n := 0
	for _, r := range s {
		if width.LookupRune(r).Kind() == width.EastAsianWide {
			n += 2
		} else {
			n += 1
		}
	}
	if res := l - n; res > 0 {
		return s + strings.Repeat(" ", res)
	}
	return s
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"code.google.com/p/go.tools/go/exact"
	"code.google.com/p/go.tools/go/types"
	"errors"
	"flag"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

var (
	// allImports is a map of already-imported import paths to packages
	allImports map[string]*types.Package

	// ErrCheckErrors is returned by the checkFiles function if any errors were
	// encountered during checking.
	ErrCheckErrors = errors.New("found errors in checked files")
)

// Err prints an error to Stderr
func Err(s string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "error: "+s+"\n", args...)
}

// Fatal calls Err followed by os.Exit(2)
func Fatal(s string, args ...interface{}) {
	Err(s, args...)
	os.Exit(2)
}

// regexpFlag is a type that can be used with flag.Var for regular expression flags
type regexpFlag struct {
	re *regexp.Regexp
}

func (r regexpFlag) String() string {
	if r.re == nil {
		return ""
	}
	return r.re.String()
}

func (r *regexpFlag) Set(s string) error {
	if s == "" {
		r.re = nil
		return nil
	}

	re, err := regexp.Compile(s)
	if err != nil {
		return err
	}
	r.re = re
	return nil
}

// stringsFlag is a type that can be used with flag.Var for lists that are turned to a set
type stringsFlag struct {
	items map[string]bool
}

func (f stringsFlag) String() string {
	items := make([]string, 0, len(f.items))
	for k := range f.items {
		items = append(items, k)
	}
	return strings.Join(items, ",")
}

func (f *stringsFlag) Set(s string) error {
	f.items = make(map[string]bool)
	for _, item := range strings.Split(s, ",") {
		f.items[item] = true
	}
	return nil
}

func main() {
	allImports = make(map[string]*types.Package)

	var ignore regexpFlag
	flag.Var(&ignore, "ignore", "regular expression of function names to ignore")
	ignorePkg := &stringsFlag{}
	ignorePkg.Set("fmt")
	flag.Var(ignorePkg, "ignorepkg", "comma-separated list of package paths to ignore")
	flag.Parse()

	pkgName := flag.Arg(0)
	if pkgName == "" {
		flag.Usage()
		Fatal("you must specify a package")
	}
	pkg, err := findPackage(pkgName)
	if err != nil {
		Fatal("%s", err)
	}
	files := getFiles(pkg)

	if err := checkFiles(files, ignore.re, ignorePkg.items); err != nil {
		if err == ErrCheckErrors {
			os.Exit(1)
		}
		Fatal("failed to check package: %s", err)
	}
}

// findPackage finds a package.
// path is first tried as an import path and if the package is not found, as a filesystem path.
func findPackage(path string) (*build.Package, error) {
	var (
		err1, err2 error
		pkg        *build.Package
	)

	ctx := build.Default
	ctx.CgoEnabled = false

	// First try to treat path as import path...
	pkg, err1 = ctx.Import(path, ".", 0)
	if err1 != nil {
		// ... then attempt as file path
		pkg, err2 = ctx.ImportDir(path, 0)
	}

	if err2 != nil {
		// Print both errors so the user can see in what ways the
		// package lookup failed.
		return nil, fmt.Errorf("could not import %s: %s\n%s", path, err1, err2)
	}

	return pkg, nil
}

// getFiles returns all the Go files found in a package
func getFiles(pkg *build.Package) []string {
	files := make([]string, len(pkg.GoFiles))
	for i, fileName := range pkg.GoFiles {
		files[i] = filepath.Join(pkg.Dir, fileName)
	}
	return files
}

type file struct {
	fset  *token.FileSet
	name  string
	ast   *ast.File
	lines [][]byte
}

func parseFile(fset *token.FileSet, fileName string) (f file, err error) {
	rd, err := os.Open(fileName)
	if err != nil {
		return f, err
	}
	defer rd.Close()

	data, err := ioutil.ReadAll(rd)
	if err != nil {
		return f, err
	}

	astFile, err := parser.ParseFile(fset, fileName, bytes.NewReader(data), parser.ParseComments)
	if err != nil {
		return f, fmt.Errorf("could not parse: %s", err)
	}

	lines := bytes.Split(data, []byte("\n"))
	f = file{fset: fset, name: fileName, ast: astFile, lines: lines}
	return f, nil
}

func typeCheck(fset *token.FileSet, astFiles []*ast.File) (map[*ast.CallExpr]types.Type, map[*ast.Ident]types.Object, error) {
	callTypes := make(map[*ast.CallExpr]types.Type)
	identObjs := make(map[*ast.Ident]types.Object)

	exprFn := func(x ast.Expr, typ types.Type, val exact.Value) {
		call, ok := x.(*ast.CallExpr)
		if !ok {
			return
		}
		callTypes[call] = typ
	}
	identFn := func(id *ast.Ident, obj types.Object) {
		identObjs[id] = obj
	}
	context := types.Context{
		Expr:   exprFn,
		Ident:  identFn,
		Import: importer,
	}
	_, err := context.Check(fset, astFiles)
	return callTypes, identObjs, err
}

type checker struct {
	fset      *token.FileSet
	files     map[string]file
	callTypes map[*ast.CallExpr]types.Type
	identObjs map[*ast.Ident]types.Object
	ignore    *regexp.Regexp
	ignorePkg map[string]bool

	errors []error
}

type uncheckedErr struct {
	pos  token.Position
	line []byte
}

func (e uncheckedErr) Error() string {
	return fmt.Sprintf("%s %s", e.pos, e.line)
}

func (c *checker) Visit(node ast.Node) ast.Visitor {
	n, ok := node.(*ast.ExprStmt)
	if !ok {
		return c
	}

	// Check for a call expression
	call, ok := n.X.(*ast.CallExpr)
	if !ok {
		return c
	}

	// Try to get an identifier.
	// Currently only supports simple expressions:
	//     1. f()
	//     2. x.y.f()
	var id *ast.Ident
	switch exp := call.Fun.(type) {
	case (*ast.Ident):
		id = exp
	case (*ast.SelectorExpr):
		id = exp.Sel
	default:
		// eg: *ast.SliceExpr, *ast.IndexExpr
	}

	// If we got an identifier for the function, see if it is ignored
	if id != nil {
		// Ignore if in an ignored package
		if obj := c.identObjs[id]; obj != nil {
			if pkg := obj.GetPkg(); pkg != nil && c.ignorePkg[pkg.Path] {
				return c
			}
		}
		// Ignore if the name matches the regexp
		if c.ignore != nil && c.ignore.MatchString(id.Name) {
			return c
		}
	}

	unchecked := false
	switch t := c.callTypes[call].(type) {
	case *types.NamedType:
		// Single return
		if isErrorType(t.Obj) {
			unchecked = true
		}
	case *types.Result:
		// Multiple returns
		for _, v := range t.Values {
			nt, ok := v.Type.(*types.NamedType)
			if !ok {
				continue
			}
			if isErrorType(nt.Obj) {
				unchecked = true
				break
			}
		}
	}

	if unchecked {
		pos := c.fset.Position(call.Lparen)
		line := bytes.TrimSpace(c.files[pos.Filename].lines[pos.Line-1])
		line = append([]byte{'\t'}, line...)
		c.errors = append(c.errors, uncheckedErr{pos, line})
	}
	return c
}

func checkFiles(fileNames []string, ignore *regexp.Regexp, ignorePkg map[string]bool) error {
	fset := token.NewFileSet()
	astFiles := make([]*ast.File, len(fileNames))
	files := make(map[string]file, len(fileNames))

	for i, fileName := range fileNames {
		f, err := parseFile(fset, fileName)
		if err != nil {
			return fmt.Errorf("could not parse %s: %s", fileName, err)
		}
		files[fileName] = f
		astFiles[i] = f.ast
	}

	callTypes, identObjs, err := typeCheck(fset, astFiles)
	if err != nil {
		return fmt.Errorf("could not type check: %s", err)
	}

	visitor := &checker{fset, files, callTypes, identObjs, ignore, ignorePkg, []error{}}
	for _, astFile := range astFiles {
		ast.Walk(visitor, astFile)
	}

	for _, e := range visitor.errors {
		fmt.Println(e)
	}

	if len(visitor.errors) > 0 {
		return ErrCheckErrors
	}
	return nil
}

type obj interface {
	GetPkg() *types.Package
	GetName() string
}

func isErrorType(v obj) bool {
	return v.GetPkg() == nil && v.GetName() == "error"
}

func importer(imports map[string]*types.Package, path string) (pkg *types.Package, err error) {
	// types.Importer does not seem to be designed for recursive
	// parsing like we're doing here. Specifically, each nested import
	// will maintain its own imports map. This will lead to duplicate
	// imports and in turn packages, which will lead to funny errors
	// such as "cannot pass argument ip (variable of type net.IP) to
	// variable of type net.IP"
	//
	// To work around this, we keep a global imports map, allImports,
	// to which we add all nested imports, and which we use as the
	// cache, instead of imports.
	//
	// Since all nested imports will also use this importer, there
	// should be no way to end up with duplicate imports.

	// We first try to use GcImport directly. This has the downside of
	// using possibly out-of-date packages, but it has the upside of
	// not having to parse most of the Go standard library.

	buildPkg, buildErr := build.Import(path, ".", 0)

	// If we found no build dir, assume we're dealing with installed
	// but no source. If we found a build dir, only use GcImport if
	// it's in GOROOT. This way we always use up-to-date code for
	// normal packages but avoid parsing the standard library.
	if (buildErr == nil && buildPkg.Goroot) || buildErr != nil {
		pkg, err = types.GcImport(allImports, path)
		if err == nil {
			// We don't use imports, but per API we have to add the package.
			imports[pkg.Path] = pkg
			allImports[pkg.Path] = pkg
			return pkg, nil
		}
	}

	// See if we already imported this package
	if pkg = allImports[path]; pkg != nil && pkg.Complete {
		return pkg, nil
	}

	// allImports failed, try to use go/build
	if buildErr != nil {
		return nil, buildErr
	}

	fileSet := token.NewFileSet()

	isGoFile := func(d os.FileInfo) bool {
		allFiles := make([]string, 0, len(buildPkg.GoFiles)+len(buildPkg.CgoFiles))
		allFiles = append(allFiles, buildPkg.GoFiles...)
		allFiles = append(allFiles, buildPkg.CgoFiles...)

		for _, file := range allFiles {
			if file == d.Name() {
				return true
			}
		}
		return false
	}
	pkgs, err := parser.ParseDir(fileSet, buildPkg.Dir, isGoFile, 0)
	if err != nil {
		return nil, err
	}

	delete(pkgs, "documentation")
	var astPkg *ast.Package
	var name string
	for name, astPkg = range pkgs {
		// Use the first non-main package, or the only package we
		// found.
		//
		// NOTE(dh) I can't think of a reason why there should be
		// multiple packages in a single directory, but ParseDir
		// accommodates for that possibility.
		if len(pkgs) == 1 || name != "main" {
			break
		}
	}

	if astPkg == nil {
		return nil, fmt.Errorf("can't find import: %s", name)
	}

	var ff []*ast.File
	for _, f := range astPkg.Files {
		ff = append(ff, f)
	}

	context := types.Context{
		Import: importer,
	}

	pkg, err = context.Check(fileSet, ff)
	if err != nil {
		return pkg, err
	}

	// We don't use imports, but per API we have to add the package.
	imports[path] = pkg
	allImports[path] = pkg
	pkg.Complete = true
	return pkg, nil
}
<commit_msg>updated for new go/types API<commit_after>package main

import (
	"bytes"
	"code.google.com/p/go.tools/go/exact"
	"code.google.com/p/go.tools/go/types"
	"errors"
	"flag"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

var (
	// allImports is a map of already-imported import paths to packages
	allImports map[string]*types.Package

	// ErrCheckErrors is returned by the checkFiles function if any errors were
	// encountered during checking.
	ErrCheckErrors = errors.New("found errors in checked files")
)

// Err prints an error to Stderr
func Err(s string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "error: "+s+"\n", args...)
}

// Fatal calls Err followed by os.Exit(2)
func Fatal(s string, args ...interface{}) {
	Err(s, args...)
	os.Exit(2)
}

// regexpFlag is a type that can be used with flag.Var for regular expression flags
type regexpFlag struct {
	re *regexp.Regexp
}

func (r regexpFlag) String() string {
	if r.re == nil {
		return ""
	}
	return r.re.String()
}

func (r *regexpFlag) Set(s string) error {
	if s == "" {
		r.re = nil
		return nil
	}

	re, err := regexp.Compile(s)
	if err != nil {
		return err
	}
	r.re = re
	return nil
}

// stringsFlag is a type that can be used with flag.Var for lists that are turned to a set
type stringsFlag struct {
	items map[string]bool
}

func (f stringsFlag) String() string {
	items := make([]string, 0, len(f.items))
	for k := range f.items {
		items = append(items, k)
	}
	return strings.Join(items, ",")
}

func (f *stringsFlag) Set(s string) error {
	f.items = make(map[string]bool)
	for _, item := range strings.Split(s, ",") {
		f.items[item] = true
	}
	return nil
}

func main() {
	allImports = make(map[string]*types.Package)

	var ignore regexpFlag
	flag.Var(&ignore, "ignore", "regular expression of function names to ignore")
	ignorePkg := &stringsFlag{}
	ignorePkg.Set("fmt")
	flag.Var(ignorePkg, "ignorepkg", "comma-separated list of package paths to ignore")
	flag.Parse()

	pkgName := flag.Arg(0)
	if pkgName == "" {
		flag.Usage()
		Fatal("you must specify a package")
	}
	pkg, err := findPackage(pkgName)
	if err != nil {
		Fatal("%s", err)
	}
	files := getFiles(pkg)

	if err := checkFiles(files, ignore.re, ignorePkg.items); err != nil {
		if err == ErrCheckErrors {
			os.Exit(1)
		}
		Fatal("failed to check package: %s", err)
	}
}

// findPackage finds a package.
// path is first tried as an import path and if the package is not found, as a filesystem path.
func findPackage(path string) (*build.Package, error) {
	var (
		err1, err2 error
		pkg        *build.Package
	)

	ctx := build.Default
	ctx.CgoEnabled = false

	// First try to treat path as import path...
	pkg, err1 = ctx.Import(path, ".", 0)
	if err1 != nil {
		// ... then attempt as file path
		pkg, err2 = ctx.ImportDir(path, 0)
	}

	if err2 != nil {
		// Print both errors so the user can see in what ways the
		// package lookup failed.
		return nil, fmt.Errorf("could not import %s: %s\n%s", path, err1, err2)
	}

	return pkg, nil
}

// getFiles returns all the Go files found in a package
func getFiles(pkg *build.Package) []string {
	files := make([]string, len(pkg.GoFiles))
	for i, fileName := range pkg.GoFiles {
		files[i] = filepath.Join(pkg.Dir, fileName)
	}
	return files
}

type file struct {
	fset  *token.FileSet
	name  string
	ast   *ast.File
	lines [][]byte
}

func parseFile(fset *token.FileSet, fileName string) (f file, err error) {
	rd, err := os.Open(fileName)
	if err != nil {
		return f, err
	}
	defer rd.Close()

	data, err := ioutil.ReadAll(rd)
	if err != nil {
		return f, err
	}

	astFile, err := parser.ParseFile(fset, fileName, bytes.NewReader(data), parser.ParseComments)
	if err != nil {
		return f, fmt.Errorf("could not parse: %s", err)
	}

	lines := bytes.Split(data, []byte("\n"))
	f = file{fset: fset, name: fileName, ast: astFile, lines: lines}
	return f, nil
}

func typeCheck(fset *token.FileSet, astFiles []*ast.File) (map[*ast.CallExpr]types.Type, map[*ast.Ident]types.Object, error) {
	callTypes := make(map[*ast.CallExpr]types.Type)
	identObjs := make(map[*ast.Ident]types.Object)

	exprFn := func(x ast.Expr, typ types.Type, val exact.Value) {
		call, ok := x.(*ast.CallExpr)
		if !ok {
			return
		}
		callTypes[call] = typ
	}
	identFn := func(id *ast.Ident, obj types.Object) {
		identObjs[id] = obj
	}
	context := types.Context{
		Expr:   exprFn,
		Ident:  identFn,
		Import: importer,
	}
	_, err := context.Check("FIX LINE 201", fset, astFiles...) // FIXME Not sure what to put as new 1st arg to Context.Check
	return callTypes, identObjs, err
}

type checker struct {
	fset      *token.FileSet
	files     map[string]file
	callTypes map[*ast.CallExpr]types.Type
	identObjs map[*ast.Ident]types.Object
	ignore    *regexp.Regexp
	ignorePkg map[string]bool

	errors []error
}

type uncheckedErr struct {
	pos  token.Position
	line []byte
}

func (e uncheckedErr) Error() string {
	return fmt.Sprintf("%s %s", e.pos, e.line)
}

func (c *checker) Visit(node ast.Node) ast.Visitor {
	n, ok := node.(*ast.ExprStmt)
	if !ok {
		return c
	}

	// Check for a call expression
	call, ok := n.X.(*ast.CallExpr)
	if !ok {
		return c
	}

	// Try to get an identifier.
	// Currently only supports simple expressions:
	//     1. f()
	//     2. x.y.f()
	var id *ast.Ident
	switch exp := call.Fun.(type) {
	case (*ast.Ident):
		id = exp
	case (*ast.SelectorExpr):
		id = exp.Sel
	default:
		// eg: *ast.SliceExpr, *ast.IndexExpr
	}

	// If we got an identifier for the function, see if it is ignored
	if id != nil {
		// Ignore if in an ignored package
		if obj := c.identObjs[id]; obj != nil {
			if pkg := obj.Pkg(); pkg != nil && c.ignorePkg[pkg.Path()] {
				return c
			}
		}
		// Ignore if the name matches the regexp
		if c.ignore != nil && c.ignore.MatchString(id.Name) {
			return c
		}
	}

	unchecked := false
	switch t := c.callTypes[call].(type) {
	case *types.Named:
		// Single return
		if isErrorType(t.Obj()) {
			unchecked = true
		}
	case *types.Tuple:
		// Multiple returns
		for i := 0; i < t.Len(); i++ {
			nt, ok := t.At(i).Type().(*types.Named)
			if !ok {
				continue
			}
			if isErrorType(nt.Obj()) {
				unchecked = true
				break
			}
		}
	}

	if unchecked {
		pos := c.fset.Position(call.Lparen)
		line := bytes.TrimSpace(c.files[pos.Filename].lines[pos.Line-1])
		line = append([]byte{'\t'}, line...)
		c.errors = append(c.errors, uncheckedErr{pos, line})
	}
	return c
}

func checkFiles(fileNames []string, ignore *regexp.Regexp, ignorePkg map[string]bool) error {
	fset := token.NewFileSet()
	astFiles := make([]*ast.File, len(fileNames))
	files := make(map[string]file, len(fileNames))

	for i, fileName := range fileNames {
		f, err := parseFile(fset, fileName)
		if err != nil {
			return fmt.Errorf("could not parse %s: %s", fileName, err)
		}
		files[fileName] = f
		astFiles[i] = f.ast
	}

	callTypes, identObjs, err := typeCheck(fset, astFiles)
	if err != nil {
		return fmt.Errorf("could not type check: %s", err)
	}

	visitor := &checker{fset, files, callTypes, identObjs, ignore, ignorePkg, []error{}}
	for _, astFile := range astFiles {
		ast.Walk(visitor, astFile)
	}

	for _, e := range visitor.errors {
		fmt.Println(e)
	}

	if len(visitor.errors) > 0 {
		return ErrCheckErrors
	}
	return nil
}

type obj interface {
	Pkg() *types.Package
	Name() string
}

func isErrorType(v obj) bool {
	return v.Pkg() == nil && v.Name() == "error"
}

func importer(imports map[string]*types.Package, path string) (pkg *types.Package, err error) {
	// types.Importer does not seem to be designed for recursive
	// parsing like we're doing here. Specifically, each nested import
	// will maintain its own imports map. This will lead to duplicate
	// imports and in turn packages, which will lead to funny errors
	// such as "cannot pass argument ip (variable of type net.IP) to
	// variable of type net.IP"
	//
	// To work around this, we keep a global imports map, allImports,
	// to which we add all nested imports, and which we use as the
	// cache, instead of imports.
	//
	// Since all nested imports will also use this importer, there
	// should be no way to end up with duplicate imports.

	// We first try to use GcImport directly. This has the downside of
	// using possibly out-of-date packages, but it has the upside of
	// not having to parse most of the Go standard library.

	buildPkg, buildErr := build.Import(path, ".", 0)

	// If we found no build dir, assume we're dealing with installed
	// but no source. If we found a build dir, only use GcImport if
	// it's in GOROOT. This way we always use up-to-date code for
	// normal packages but avoid parsing the standard library.
	if (buildErr == nil && buildPkg.Goroot) || buildErr != nil {
		pkg, err = types.GcImport(allImports, path)
		if err == nil {
			// We don't use imports, but per API we have to add the package.
			imports[pkg.Path()] = pkg
			allImports[pkg.Path()] = pkg
			return pkg, nil
		}
	}

	// See if we already imported this package
	if pkg = allImports[path]; pkg != nil && pkg.Complete() {
		return pkg, nil
	}

	// allImports failed, try to use go/build
	if buildErr != nil {
		return nil, buildErr
	}

	fileSet := token.NewFileSet()

	isGoFile := func(d os.FileInfo) bool {
		allFiles := make([]string, 0, len(buildPkg.GoFiles)+len(buildPkg.CgoFiles))
		allFiles = append(allFiles, buildPkg.GoFiles...)
		allFiles = append(allFiles, buildPkg.CgoFiles...)

		for _, file := range allFiles {
			if file == d.Name() {
				return true
			}
		}
		return false
	}
	pkgs, err := parser.ParseDir(fileSet, buildPkg.Dir, isGoFile, 0)
	if err != nil {
		return nil, err
	}

	delete(pkgs, "documentation")
	var astPkg *ast.Package
	var name string
	for name, astPkg = range pkgs {
		// Use the first non-main package, or the only package we
		// found.
		//
		// NOTE(dh) I can't think of a reason why there should be
		// multiple packages in a single directory, but ParseDir
		// accommodates for that possibility.
		if len(pkgs) == 1 || name != "main" {
			break
		}
	}

	if astPkg == nil {
		return nil, fmt.Errorf("can't find import: %s", name)
	}

	var ff []*ast.File
	for _, f := range astPkg.Files {
		ff = append(ff, f)
	}

	context := types.Context{
		Import: importer,
	}

	pkg, err = context.Check("FIX LINE 430", fileSet, ff...) // FIXME Not sure what to put as new 1st arg to Context.Check
	if err != nil {
		return pkg, err
	}

	// We don't use imports, but per API we have to add the package.
	imports[path] = pkg
	allImports[path] = pkg
	// pkg.Complete = true // FIXME Can't assign pkg.Complete in new API
	return pkg, nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/mitchellh/go-homedir"
)

var homePath string

func init() {
	h, err := homedir.Dir()
	if err != nil {
		panic(err)
	}
	homePath = h
}

func usage() {
	os.Stderr.WriteString(`
Usage: mcm [OPTION]... RECIPE

Options:
	--help       show this help message
	--version    print the version
`[1:])
}

func version() {
	os.Stderr.WriteString(`
mcm: v0.1.0
`[1:])
}

func isExist(path string) bool {
	_, err := os.Stat(path)
	return !os.IsNotExist(err)
}

type Mod struct {
	Name string `toml:"name"`
	URL  string `toml:"url"`
}

type Manager struct {
	log  *log.Logger
	Root string `toml:"root"`
	Mods []Mod  `toml:"mod"`
}

func NewManager(confPath string, logWriter io.Writer) (*Manager, error) {
	m := &Manager{
		log:  log.New(logWriter, "", log.LstdFlags),
		Root: filepath.Join(homePath, ".minecraft"),
	}

	_, err := toml.DecodeFile(confPath, &m)
	if err != nil {
		return nil, err
	}
	m.Root = filepath.Clean(m.Root)
	return m, nil
}

func (m *Manager) Download() error {
	var errors []string

	m.log.Println("INFO:", "Start mcm")
	for _, mod := range m.Mods {
		modPath := filepath.Join(m.Root, "mods", mod.Name)
		if isExist(modPath) {
			m.log.Println("INFO:", "Already installed:", mod.Name)
			continue
		}

		m.log.Println("INFO:", "Start install:", mod.Name)
		modFile, err := os.Create(modPath)
		if err != nil {
			m.log.Println("ERRO:", "Failed create file:", modPath)
			errors = append(errors, err.Error())
			continue
		}

		m.log.Println("INFO:", "Download from:", mod.URL)
		remoteFile, err := http.Get(mod.URL)
		if err != nil {
			m.log.Println("ERRO:", "Failed Download:", mod.Name)
			errors = append(errors, err.Error())
			continue
		}
		defer remoteFile.Body.Close()

		_, err = io.Copy(modFile, remoteFile.Body)
		if err != nil {
			m.log.Println("ERRO:", "Failed Write to:", modPath)
			errors = append(errors, err.Error())
			continue
		}
		m.log.Println("INFO:", "Complete install:", mod.Name)
	}
	m.log.Println("INFO:", "Finish mcm")

	if len(errors) > 0 {
		return fmt.Errorf("%d errors occurred:\n%s",
			len(errors), strings.Join(errors, "\n"))
	}

	return nil
}

func main() {
	isHelp := flag.Bool("help", false, "")
	isVersion := flag.Bool("version", false, "")
	flag.Usage = usage
	flag.Parse()

	if *isHelp {
		usage()
		os.Exit(2)
	}
	if *isVersion {
		version()
		os.Exit(2)
	}
	if flag.NArg() < 1 {
		fmt.Fprintln(os.Stderr, "mcm:", "no input file")
		usage()
		os.Exit(1)
	}

	m, err := NewManager(flag.Arg(0), os.Stdout)
	if err != nil {
		fmt.Fprintln(os.Stderr, "mcm:", err)
		os.Exit(1)
	}
	if err = m.Download(); err != nil {
		fmt.Fprintln(os.Stderr, "mcm:", err)
		os.Exit(1)
	}
}
<commit_msg>Add declare minecraft path<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/mitchellh/go-homedir"
)

var minecraftPath string

func init() {
	homePath, err := homedir.Dir()
	if err != nil {
		panic(err)
	}
	minecraftPath = filepath.Join(homePath, ".minecraft")
}

func usage() {
	os.Stderr.WriteString(`
Usage: mcm [OPTION]... RECIPE

Options:
	--help       show this help message
	--version    print the version
`[1:])
}

func version() {
	os.Stderr.WriteString(`
mcm: v0.1.0
`[1:])
}

func isExist(path string) bool {
	_, err := os.Stat(path)
	return !os.IsNotExist(err)
}

type Mod struct {
	Name string `toml:"name"`
	URL  string `toml:"url"`
}

type Manager struct {
	log  *log.Logger
	Root string `toml:"root"`
	Mods []Mod  `toml:"mod"`
}

func NewManager(confPath string, logWriter io.Writer) (*Manager, error) {
	m := &Manager{
		log:  log.New(logWriter, "", log.LstdFlags),
		Root: minecraftPath,
	}

	_, err := toml.DecodeFile(confPath, &m)
	if err != nil {
		return nil, err
	}
	m.Root = filepath.Clean(m.Root)
	return m, nil
}

func (m *Manager) Download() error {
	var errors []string

	m.log.Println("INFO:", "Start mcm")
	for _, mod := range m.Mods {
		modPath := filepath.Join(m.Root, "mods", mod.Name)
		if isExist(modPath) {
			m.log.Println("INFO:", "Already installed:", mod.Name)
			continue
		}

		m.log.Println("INFO:", "Start install:", mod.Name)
		modFile, err := os.Create(modPath)
		if err != nil {
			m.log.Println("ERRO:", "Failed create file:", modPath)
			errors = append(errors, err.Error())
			continue
		}

		m.log.Println("INFO:", "Download from:", mod.URL)
		remoteFile, err := http.Get(mod.URL)
		if err != nil {
			m.log.Println("ERRO:", "Failed Download:", mod.Name)
			errors = append(errors, err.Error())
			continue
		}
		defer remoteFile.Body.Close()

		_, err = io.Copy(modFile, remoteFile.Body)
		if err != nil {
			m.log.Println("ERRO:", "Failed Write to:", modPath)
			errors = append(errors, err.Error())
			continue
		}
		m.log.Println("INFO:", "Complete install:", mod.Name)
	}
	m.log.Println("INFO:", "Finish mcm")

	if len(errors) > 0 {
		return fmt.Errorf("%d errors occurred:\n%s",
			len(errors), strings.Join(errors, "\n"))
	}

	return nil
}

func main() {
	isHelp := flag.Bool("help", false, "")
	isVersion := flag.Bool("version", false, "")
	flag.Usage = usage
	flag.Parse()

	if *isHelp {
		usage()
		os.Exit(2)
	}
	if *isVersion {
		version()
		os.Exit(2)
	}
	if flag.NArg() < 1 {
		fmt.Fprintln(os.Stderr, "mcm:", "no input file")
		usage()
		os.Exit(1)
	}

	m, err := NewManager(flag.Arg(0), os.Stdout)
	if err != nil {
		fmt.Fprintln(os.Stderr, "mcm:", err)
		os.Exit(1)
	}
	if err = m.Download(); err != nil {
		fmt.Fprintln(os.Stderr, "mcm:", err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"net/http"
	"runtime"
)

var pubAddr = flag.String("pubAddr", ":8080", "Address on which to serve public requests")
var apiAddr = flag.String("apiAddr", ":8081", "Address on which to receive reload requests")
var mongoUrl = flag.String("mongoUrl", "localhost", "Address of mongo cluster (e.g. 'mongo1,mongo2,mongo3')")
var mongoDbName = flag.String("mongoDbName", "router", "Name of mongo database to use")

var quit = make(chan int)

func main() {
	// Use all available cores
	runtime.GOMAXPROCS(runtime.NumCPU())

	flag.Parse()

	rout := NewRouter(*mongoUrl, *mongoDbName)
	rout.ReloadRoutes()

	log.Println("router: listening for requests on " + *pubAddr)
	log.Println("router: listening for refresh on " + *apiAddr)

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "POST" {
			http.NotFound(w, r)
			return
		}

		rout.ReloadRoutes()
	})

	go http.ListenAndServe(*pubAddr, rout)
	go http.ListenAndServe(*apiAddr, nil)

	<-quit
}
<commit_msg>Reorder logging and binding in main()<commit_after>package main

import (
	"flag"
	"log"
	"net/http"
	"runtime"
)

var pubAddr = flag.String("pubAddr", ":8080", "Address on which to serve public requests")
var apiAddr = flag.String("apiAddr", ":8081", "Address on which to receive reload requests")
var mongoUrl = flag.String("mongoUrl", "localhost", "Address of mongo cluster (e.g. 'mongo1,mongo2,mongo3')")
var mongoDbName = flag.String("mongoDbName", "router", "Name of mongo database to use")

var quit = make(chan int)

func main() {
	// Use all available cores
	runtime.GOMAXPROCS(runtime.NumCPU())

	flag.Parse()

	rout := NewRouter(*mongoUrl, *mongoDbName)
	rout.ReloadRoutes()

	go http.ListenAndServe(*pubAddr, rout)
	log.Println("router: listening for requests on " + *pubAddr)

	// This applies to DefaultServeMux, below.
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "POST" {
			http.NotFound(w, r)
			return
		}

		rout.ReloadRoutes()
	})
	go http.ListenAndServe(*apiAddr, nil)
	log.Println("router: listening for refresh on " + *apiAddr)

	<-quit
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/base64"
	"log"
	"net/http"
	"os"
	"os/exec"
	"runtime"
	"time"

	"github.com/garyburd/redigo/redis"
	"github.com/soveran/redisurl"
)

var (
	jobs = make(chan string, 100)
	pool redis.Pool
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	pool = redis.Pool{
		MaxIdle:     3,
		MaxActive:   10,
		IdleTimeout: 240 * time.Second,
		Dial: func() (conn redis.Conn, err error) {
			if len(os.Getenv("REDISCLOUD_URL")) > 0 {
				conn, err = redisurl.ConnectToURL(os.Getenv("REDISCLOUD_URL"))
			} else {
				conn, err = redis.Dial("tcp", ":6379")
			}
			return conn, err
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
	}

	conn := pool.Get()
	_, err := conn.Do("FLUSHALL")
	if err != nil {
		panic(err)
	}
	conn.Close()
}

func main() {
	for w := 1; w <= 3; w++ {
		go phantom(jobs)
	}

	http.HandleFunc("/", screenshot)
	log.Println("listening...")
	err := http.ListenAndServe(":"+os.Getenv("PORT"), nil)
	if err != nil {
		panic(err)
	}
}

func phantom(jobs <-chan string) {
	for job := range jobs {
		cmd := exec.Command("phantomjs", "rasterize.js", job, "300px*300px", "0.25")
		cmd.Stderr = os.Stderr
		out, err := cmd.Output()
		conn := pool.Get()
		if err != nil {
			log.Println("Error rasterizing: ", err)
		} else {
			conn.Do("HSET", "screenshot", job, string(out))
		}
		conn.Close()
	}
}

func screenshot(res http.ResponseWriter, req *http.Request) {
	defer req.Body.Close()
	req.ParseForm()
	if len(req.Form.Get("url")) > 0 {
		conn := pool.Get()
		defer conn.Close()

		url := req.Form.Get("url")
		log.Println(url)

		exists, err := redis.Bool(conn.Do("HEXISTS", "screenshot", url))
		if err != nil || !exists {
			jobs <- url
		}
		for err != nil || !exists {
			if err != nil {
				log.Println(err)
				return
			}
			time.Sleep(500 * time.Millisecond)
			exists, err = redis.Bool(conn.Do("HEXISTS", "screenshot", url))
		}
		screenshot, err := redis.String(conn.Do("HGET", "screenshot", url))
		if err != nil {
			log.Println(err)
			return
		}
		res.Header().Set("Content-Type", "image/png")
		decode, _ := base64.StdEncoding.DecodeString(screenshot)
		res.Write(decode)
	}
}
<commit_msg>Use the top level hash<commit_after>package main

import (
	"encoding/base64"
	"log"
	"net/http"
	"os"
	"os/exec"
	"runtime"
	"time"

	"github.com/garyburd/redigo/redis"
	"github.com/soveran/redisurl"
)

var (
	jobs = make(chan string, 100)
	pool redis.Pool
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	pool = redis.Pool{
		MaxIdle:     3,
		MaxActive:   10,
		IdleTimeout: 240 * time.Second,
		Dial: func() (conn redis.Conn, err error) {
			if len(os.Getenv("REDISCLOUD_URL")) > 0 {
				conn, err = redisurl.ConnectToURL(os.Getenv("REDISCLOUD_URL"))
			} else {
				conn, err = redis.Dial("tcp", ":6379")
			}
			return conn, err
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
	}

	conn := pool.Get()
	_, err := conn.Do("FLUSHALL")
	if err != nil {
		panic(err)
	}
	conn.Close()
}

func main() {
	for w := 1; w <= 3; w++ {
		go phantom(jobs)
	}

	http.HandleFunc("/", screenshot)
	log.Println("listening...")
	err := http.ListenAndServe(":"+os.Getenv("PORT"), nil)
	if err != nil {
		panic(err)
	}
}

func phantom(jobs <-chan string) {
	for job := range jobs {
		cmd := exec.Command("phantomjs", "rasterize.js", job, "300px*300px", "0.25")
		cmd.Stderr = os.Stderr
		out, err := cmd.Output()
		conn := pool.Get()
		if err != nil {
			log.Println("Error rasterizing: ", err)
		} else {
			conn.Do("SETEX", job, 21600, string(out))
		}
		conn.Close()
	}
}

func screenshot(res http.ResponseWriter, req *http.Request) {
	defer req.Body.Close()
	req.ParseForm()
	if len(req.Form.Get("url")) > 0 {
		conn := pool.Get()
		defer conn.Close()

		url := req.Form.Get("url")
		log.Println(url)

		exists, err := redis.Bool(conn.Do("EXISTS", url))
		if err != nil || !exists {
			jobs <- url
		}
		for err != nil || !exists {
			if err != nil {
				log.Println(err)
				return
			}
			time.Sleep(500 * time.Millisecond)
			exists, err = redis.Bool(conn.Do("EXISTS", url))
		}
		screenshot, err := redis.String(conn.Do("GET", url))
		if err != nil {
			log.Println(err)
			return
		}
		res.Header().Set("Content-Type", "image/png")
		decode, _ := base64.StdEncoding.DecodeString(screenshot)
		res.Write(decode)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"time"

	"github.com/go-vgo/robotgo"
)

func main() {
	modePtr := flag.String("mode", "random", "Mode to use.")
	flag.Parse()

	var strategy IStrategy

	switch *modePtr {
	case "random":
		fmt.Printf("Unimplemented mode: %s\n", *modePtr)
	case "schizo":
		fmt.Printf("Unimplemented mode: %s\n", *modePtr)
	case "momentum":
		// Cole's original algo
		fmt.Println("Running in mode Momentum")
		strategy = NewMomentumStrategy(10)
	}

	runStrategy(strategy, 10)

}

func runStrategy(s IStrategy, interval int) {
	t := time.NewTicker(time.Millisecond * time.Duration(interval))
	for {
		s.Run()
		<-t.C
	}
}

type IStrategy interface {
	Run()
}

type Pair struct {
	x, y int
}

type MomentumStrategy struct {
	previous Pair
	momentum Pair
	damping  int
}

func (s *MomentumStrategy) Run() {
	x, y := robotgo.GetMousePos()

	dif := Pair{
		s.previous.x - x,
		s.previous.y - y,
	}

	s.momentum = Pair{
		s.momentum.x - (dif.x / s.damping),
		s.momentum.y - (dif.y / s.damping),
	}

	robotgo.MoveMouse(x+s.momentum.x, y+s.momentum.y)
	s.previous = Pair{x, y}
}

func NewMomentumStrategy(damping int) *MomentumStrategy {
	x, y := robotgo.GetMousePos()
	return &MomentumStrategy{Pair{x, y}, Pair{0, 0}, damping}
}
<commit_msg>code clean up<commit_after>package main

import (
	"flag"
	"fmt"
	"time"

	"github.com/go-vgo/robotgo"
)

func main() {
	modePtr := flag.String("mode", "momentum", "Mode to use.")
	flag.Parse()

	var strategy IStrategy

	switch *modePtr {
	case "random":
		// TODO
	case "schizo":
		// TODO
	case "momentum":
		// Cole's original algo
		strategy = NewMomentumStrategy(15)
	}

	if strategy != nil {
		fmt.Printf("Running in mode: %s\n", *modePtr)
		runStrategy(strategy, 10)
	} else {
		fmt.Printf("Unimplemented mode: %s\n", *modePtr)
	}

}

func runStrategy(s IStrategy, interval int) {
	t := time.NewTicker(time.Millisecond * time.Duration(interval))
	for {
		s.Run()
		<-t.C
	}
}

type IStrategy interface {
	Run()
}

type Pair struct {
	x, y int
}

type MomentumStrategy struct {
	previous Pair
	momentum Pair
	damping  int
}

func NewMomentumStrategy(damping int) *MomentumStrategy {
	x, y := robotgo.GetMousePos()
	return &MomentumStrategy{Pair{x, y}, Pair{0, 0}, damping}
}

func (s *MomentumStrategy) Run() {
	x, y := robotgo.GetMousePos()

	dif := Pair{
		s.previous.x - x,
		s.previous.y - y,
	}

	s.momentum = Pair{
		s.momentum.x - (dif.x / s.damping),
		s.momentum.y - (dif.y / s.damping),
	}

	robotgo.MoveMouse(x+s.momentum.x, y+s.momentum.y)
	s.previous = Pair{x, y}
}
<|endoftext|>


<commit_before>// Copyright 2015 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"os"
)

var (
	server string
	wallet string
)

const Version = 1003

func main() {
	cfg := ReadConfig().Main
	server = cfg.Server
	wallet = cfg.Wallet

	// command line flags overwirte conf file
	var (
		hflag = flag.Bool("h", false, "help")
		sflag = flag.String("s", "", "address of api server")
		wflag = flag.String("w", "", "wallet address")
	)
	flag.Parse()
	args := flag.Args()
	if *sflag != "" {
		server = *sflag
	}
	if *wflag != "" {
		wallet = *wflag
	}
	if *hflag {
		args = []string{"help"}
	}
	if len(args) == 0 {
		args = append(args, "help")
	}

	switch args[0] {

	case "get":
		get(args)
	case "help":
		help(args)
	case "mkchain":
		mkchain(args)
	case "put":
		put(args)
	// two commands for the same thing
	case "newaddress":
		generateaddress(args)
	case "generateaddress":
		generateaddress(args)
	// two commands for the same thing
	case "balances":
		getaddresses(args)
	case "getaddresses":
		getaddresses(args)
	case "transactions":
		gettransactions(args)
	case "balance":
		balance(args)
	case "newtransaction":
		fctnewtrans(args)
	case "deletetransaction":
		fctdeletetrans(args)
	case "addinput":
		fctaddinput(args)
	case "addoutput":
		fctaddoutput(args)
	case "addecoutput":
		fctaddecoutput(args)
	case "sign":
		fctsign(args)
	case "submit":
		fctsubmit(args)
	case "getfee":
		fctgetfee(args)
	case "addfee":
		fctaddfee(args)
	case "properties":
		fctproperties(args)
	case "list":
		getlist(args)
	case "listj":
		getlistj(args)
	default:
		fmt.Println("Command not found")
		man("default")
	}
}

func errorln(a ...interface{}) (n int, err error) {
	return fmt.Fprintln(os.Stderr, a...)
}
<commit_msg>bump version<commit_after>// Copyright 2015 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"os"
)

var (
	server string
	wallet string
)

const Version = 1004

func main() {
	cfg := ReadConfig().Main
	server = cfg.Server
	wallet = cfg.Wallet

	// command line flags overwirte conf file
	var (
		hflag = flag.Bool("h", false, "help")
		sflag = flag.String("s", "", "address of api server")
		wflag = flag.String("w", "", "wallet address")
	)
	flag.Parse()
	args := flag.Args()
	if *sflag != "" {
		server = *sflag
	}
	if *wflag != "" {
		wallet = *wflag
	}
	if *hflag {
		args = []string{"help"}
	}
	if len(args) == 0 {
		args = append(args, "help")
	}

	switch args[0] {

	case "get":
		get(args)
	case "help":
		help(args)
	case "mkchain":
		mkchain(args)
	case "put":
		put(args)
	// two commands for the same thing
	case "newaddress":
		generateaddress(args)
	case "generateaddress":
		generateaddress(args)
	// two commands for the same thing
	case "balances":
		getaddresses(args)
	case "getaddresses":
		getaddresses(args)
	case "transactions":
		gettransactions(args)
	case "balance":
		balance(args)
	case "newtransaction":
		fctnewtrans(args)
	case "deletetransaction":
		fctdeletetrans(args)
	case "addinput":
		fctaddinput(args)
	case "addoutput":
		fctaddoutput(args)
	case "addecoutput":
		fctaddecoutput(args)
	case "sign":
		fctsign(args)
	case "submit":
		fctsubmit(args)
	case "getfee":
		fctgetfee(args)
	case "addfee":
		fctaddfee(args)
	case "properties":
		fctproperties(args)
	case "list":
		getlist(args)
	case "listj":
		getlistj(args)
	default:
		fmt.Println("Command not found")
		man("default")
	}
}

func errorln(a ...interface{}) (n int, err error) {
	return fmt.Fprintln(os.Stderr, a...)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"flag"
	"fmt"
	"os"
)

var (
	errNotFound = errors.New("Not found")

	dbDir         = os.Getenv("HOME") + "/.bookmarkable"
	defaultConfig = dbDir + "/config.json"

	versionFlag = flag.Bool("v", false, "Print version and exit")
	configFile  = flag.String(
		"config",
		defaultConfig,
		"Config file. See config/example.json.dist")
	url  = flag.String("url", "", "URL to bookmark")
	tags = flag.String("tags", "", "\"foo bar\" adds tag \"foo\" and \"bar\"")
)

func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Version : %s\n", version)
		fmt.Fprintf(os.Stderr, "Commmit : %s\n", commit)
		fmt.Fprintf(os.Stderr, "Built   : %s\n\n", buildDate)

		flag.PrintDefaults()

		fmt.Fprintln(os.Stderr, "\nUsage:")
		fmt.Fprintln(os.Stderr, "    bookmarkable command -config conf.json")
	}
}

const (
	errorUnparsableConfig = 1
	errorDBCreate         = 2
	errorDBGet            = 4
	errorPageGet          = 8
	errorBookmarkAdd      = 16
	cmdAdd                = "add"
	cmdList               = "list"
	cmdSearch             = "search"
)

func main() {
	// remove the command so that the flags are parsable
	args := os.Args[0:1]
	cmd := os.Args[1]

	// fmt.Printf("cmd = %v\n", cmd)

	for _, s := range os.Args[2:] {
		args = append(args, s)
	}

	// command removed, put the args back
	os.Args = args

	flag.Parse()

	if *versionFlag { // }|| *url == "" {
		flag.Usage()
		os.Exit(0)
	}

	config, err := parseConfig(*configFile)

	if err != nil {
		fmt.Printf("%v", err)
		os.Exit(errorUnparsableConfig)
	}

	db := New(config)

	if err != nil {
		fmt.Printf("%v", err)
		os.Exit(errorDBCreate)
	}

	if cmd == "sync" {
		if err := db.sync(); err != nil {
			fmt.Printf("%v\n", err)
			os.Exit(32)
		}
	} else if cmd == "search" {
		results := db.search(os.Args[1])
		printBookmarks(results)
	} else if cmd == "list" {
		results, _ := db.getBookmarks()
		printBookmarks(results)
	} else if cmd == "add" {
		url := os.Args[1]
		tags := os.Args[2:]
		if err := db.add(url, tags); err != nil {
			fmt.Printf("%v\n", err)
			os.Exit(64)
		}
	}
}

func printBookmarks(bookmarks []*Bookmark) {
	for _, b := range bookmarks {
		fmt.Printf("%v\n  %v\n  %v\n  %v\n\n",
			b.Title,
			b.URL,
			b.Tags,
			b.CreatedAt)
	}
}
<commit_msg>Tidy up main<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
)

var (
	dbDir         = os.Getenv("HOME") + "/.bookmarkable"
	defaultConfig = dbDir + "/config.json"

	versionFlag = flag.Bool("v", false, "Print version and exit")
)

func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Version : %s\n", version)
		fmt.Fprintf(os.Stderr, "Commmit : %s\n", commit)
		fmt.Fprintf(os.Stderr, "Built   : %s\n\n", buildDate)

		flag.PrintDefaults()

		fmt.Fprintln(os.Stderr, "\nUsage:")
		fmt.Fprintln(os.Stderr, "    bookmarkable command -config conf.json")
	}
}

const (
	cmdSync   = "sync"
	cmdAdd    = "add"
	cmdList   = "list"
	cmdSearch = "search"
)

func main() {
	// remove the command so that the flags are parsable
	args := os.Args[0:1]
	cmd := os.Args[1]

	for _, s := range os.Args[2:] {
		args = append(args, s)
	}

	// command removed, put the args back
	os.Args = args

	flag.Parse()

	if *versionFlag {
		flag.Usage()
		os.Exit(0)
	}

	configFile := &defaultConfig
	db, err := New(configFile)

	if err != nil {
		fmt.Printf("%v", err)
		os.Exit(1)
	}

	if cmd == cmdSync {
		if err := db.sync(); err != nil {
			fmt.Printf("%v\n", err)
			os.Exit(2)
		}
	} else if cmd == cmdSearch {
		results := db.search(os.Args[1])
		printBookmarks(results)
	} else if cmd == cmdList {
		results, _ := db.getBookmarks()
		printBookmarks(results)
	} else if cmd == cmdList {
		url := os.Args[1]
		tags := os.Args[2:]
		if err := db.add(url, tags); err != nil {
			fmt.Printf("%v\n", err)
			os.Exit(4)
		}
	}
}

func printBookmarks(bookmarks []*Bookmark) {
	for _, b := range bookmarks {
		fmt.Printf("%v\n  %v\n  %v\n  %v\n\n",
			b.Title,
			b.URL,
			b.Tags,
			b.CreatedAt)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/mantishK/deadend"
)

func main() {
	args := os.Args
	sourceURL := args[1]

	brokenLinkChan := make(chan deadend.BrokenLinkMap, 100)
	deadend := deadend.NewDeadend(sourceURL)
	go deadend.Check(sourceURL, brokenLinkChan)
	fmt.Println("Fetching the broken links for " + sourceURL)
	for {
		select {
		case brokenLinkMap := <-brokenLinkChan:
			fmt.Println("Source: " + brokenLinkMap.Source)
			fmt.Println("Broken Link: " + brokenLinkMap.BrokenURL)
			fmt.Println("Status: ", brokenLinkMap.StatusCode)
			fmt.Println()
		}
	}
}
<commit_msg>removed unncessary main file from the library<commit_after><|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
	"runtime"

	"github.com/m-lab/go/prometheusx"

	"github.com/m-lab/annotation-service/handler"
	"github.com/m-lab/annotation-service/manager"
)

// Status provides a simple status page, to help understand the current running version.
// TODO(gfr) Add either a black list or a white list for the environment
// variables, so we can hide sensitive vars. https://github.com/m-lab/etl/issues/384
func Status(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "\n")
	fmt.Fprintf(w, "
NOTE: This is just one of potentially many instances.
\n")
	commit := os.Getenv("COMMIT_HASH")
	if len(commit) >= 8 {
		fmt.Fprintf(w, "Release: %s
  Commit: %s
\n",
			os.Getenv("RELEASE_TAG"), os.Getenv("COMMIT_HASH"), os.Getenv("COMMIT_HASH")[0:7])
	} else {
		fmt.Fprintf(w, "Release: %s   Commit: unknown\n", os.Getenv("RELEASE_TAG"))
	}

	//	fmt.Fprintf(w, "
Workers: %d / %d
\n", atomic.LoadInt32(&inFlight), maxInFlight)
	env := os.Environ()
	for i := range env {
		fmt.Fprintf(w, "%s
\n", env[i])
	}
	fmt.Fprintf(w, "\n")
}

// Update the list of maxmind datasets daily
func updateMaxmindDatasets(w http.ResponseWriter, r *http.Request) {
	manager.MustUpdateDirectory()
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("OK"))
}

func init() {
	// Always prepend the filename and line number.
	log.SetFlags(log.LstdFlags | log.Lshortfile)
}

func main() {
	runtime.SetBlockProfileRate(1000000) // 1 sample/msec
	runtime.SetMutexProfileFraction(1000)

	log.Print("Beginning Setup\n")
	http.HandleFunc("/cron/update_maxmind_datasets", updateMaxmindDatasets)
	http.HandleFunc("/status", Status)

	handler.InitHandler()
	prometheusx.MustStartPrometheus(":9090")
	log.Print("Listening on port 8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}
<commit_msg>use gocron<commit_after>package main

import (
	"fmt"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
	"runtime"

	"github.com/m-lab/go/prometheusx"

	"github.com/m-lab/annotation-service/gocron"
	"github.com/m-lab/annotation-service/handler"
	"github.com/m-lab/annotation-service/manager"
)

// Status provides a simple status page, to help understand the current running version.
// TODO(gfr) Add either a black list or a white list for the environment
// variables, so we can hide sensitive vars. https://github.com/m-lab/etl/issues/384
func Status(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "\n")
	fmt.Fprintf(w, "
NOTE: This is just one of potentially many instances.
\n")
	commit := os.Getenv("COMMIT_HASH")
	if len(commit) >= 8 {
		fmt.Fprintf(w, "Release: %s
  Commit: %s
\n",
			os.Getenv("RELEASE_TAG"), os.Getenv("COMMIT_HASH"), os.Getenv("COMMIT_HASH")[0:7])
	} else {
		fmt.Fprintf(w, "Release: %s   Commit: unknown\n", os.Getenv("RELEASE_TAG"))
	}

	//	fmt.Fprintf(w, "
Workers: %d / %d
\n", atomic.LoadInt32(&inFlight), maxInFlight)
	env := os.Environ()
	for i := range env {
		fmt.Fprintf(w, "%s
\n", env[i])
	}
	fmt.Fprintf(w, "\n")
}

// Update the list of maxmind datasets daily
func updateMaxmindDatasets(w http.ResponseWriter, r *http.Request) {
	manager.MustUpdateDirectory()
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("OK"))
}

func init() {
	// Always prepend the filename and line number.
	log.SetFlags(log.LstdFlags | log.Lshortfile)
}

func main() {
	runtime.SetBlockProfileRate(1000000) // 1 sample/msec
	runtime.SetMutexProfileFraction(1000)

	log.Print("Beginning Setup\n")
	s := gocron.NewScheduler()
	s.Every(1).Day().Do(updateMaxmindDatasets)
	<-s.Start()

	http.HandleFunc("/status", Status)

	handler.InitHandler()
	prometheusx.MustStartPrometheus(":9090")
	log.Print("Listening on port 8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"time"
	"reflect"
	"encoding/json"

	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/pkg/api"
	"k8s.io/apimachinery/pkg/fields"
	"k8s.io/client-go/pkg/api/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/pkg/apis/extensions/v1beta1"
	"strings"
	"k8s.io/client-go/rest"
)

type LogMessage struct {
	ObjectType string
	ObjectName string
	EventType string
	AssignedNode string
	Replicas int32
	Timestamp time.Time
}

func main() {
	clientset := createClientSet()

	createWatcher(clientset.CoreV1().RESTClient(), &v1.Pod{}, "pods")
	createWatcher(clientset.CoreV1().RESTClient(), &v1.Service{}, "services")
	createWatcher(clientset.CoreV1().RESTClient(), &v1.Secret{}, "secrets")
	createWatcher(clientset.CoreV1().RESTClient(), &v1.ConfigMap{}, "configmaps")
	createWatcher(clientset.CoreV1().RESTClient(), &v1.Namespace{}, "namespaces")
	createWatcher(clientset.CoreV1().RESTClient(), &v1.ReplicationController{}, "replicationcontrollers")
	createWatcher(clientset.ExtensionsV1beta1().RESTClient(), &v1beta1.ReplicaSet{}, "replicasets")
	createWatcher(clientset.ExtensionsV1beta1().RESTClient(), &v1beta1.Ingress{}, "ingresses")
	createWatcher(clientset.ExtensionsV1beta1().RESTClient(), &v1beta1.Deployment{}, "deployments")

	for{
		time.Sleep(time.Second)
	}
}

func createWatcher(c cache.Getter, obj runtime.Object, resource string) cache.Controller {
	watchlist := cache.NewListWatchFromClient(c, resource, api.NamespaceAll, fields.Everything())
	resyncPeriod := 30 * time.Minute

	_, controller := cache.NewInformer(
		watchlist,
		obj,
		resyncPeriod,
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				toJson(obj, "Created")
			},
			DeleteFunc: func(obj interface{}) {
				toJson(obj, "Deleted")
			},
			UpdateFunc: func(oldObj, newObj interface{}) {
				toJson(newObj, "Updated")
			},
		},
	)

	go controller.Run(wait.NeverStop)
	return controller
}

func toJson(obj interface{}, eventType string) string {
	objType := reflect.TypeOf(obj)

	logMessage := &LogMessage{ObjectType: strings.TrimLeft(objType.String(), "*"), ObjectName: getName(obj), EventType: eventType, Timestamp: time.Now()}

	//Add additional information to log message
	switch t := obj.(type) {
	case *v1.Pod:
		logMessage.AssignedNode = t.Spec.NodeName
	case *v1beta1.Deployment:
		logMessage.Replicas = *t.Spec.Replicas
	case *v1beta1.ReplicaSet:
		logMessage.Replicas = *t.Spec.Replicas
	}

	b, err := json.Marshal(logMessage)
	if err != nil {
		fmt.Println(err)
		return ""
	}

	jsonString := string(b)
	fmt.Println(jsonString)
	return string(jsonString)
}

func getName(obj interface{}) string {
	switch t := obj.(type) {
	default:
		return "Unknown Name"
	case *v1.Namespace:
		return t.ObjectMeta.Name
	case *v1.Pod:
		return t.ObjectMeta.Name
	case *v1beta1.Deployment:
		return t.ObjectMeta.Name
	case *v1beta1.DaemonSet:
		return t.ObjectMeta.Name
	case *v1beta1.ReplicaSet:
		return t.ObjectMeta.Name
	case *v1.Secret:
		return t.ObjectMeta.Name
	case *v1.ConfigMap:
		return t.ObjectMeta.Name
	case *v1beta1.Ingress:
		return t.ObjectMeta.Name
	case *v1.Service:
		return t.ObjectMeta.Name
	}

	return "Unknown Name"
}

func createClientSet() *kubernetes.Clientset {
	var kubeconfig *string
	if home := homeDir(); home != "" {
		kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
	} else {
		kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
	}
	flag.Parse()

	//Default to using kubeconfig or commandline arg
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
	if err != nil {
		// kubeconfig failed attempt in cluster config
		// creates the in-cluster config
		fmt.Println("Creating in cluster configuration...")
		config, err = rest.InClusterConfig()
		if err != nil {
			panic(err.Error())
		}
	}

	return buildClientSet(config)
}

func buildClientSet(config *rest.Config) *kubernetes.Clientset {
	// create the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err.Error())
	}

	return clientset
}

func homeDir() string {
	if h := os.Getenv("HOME"); h != "" {
		return h
	}
	return os.Getenv("USERPROFILE") // windows
}<commit_msg>Timestamp tweaks<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"time"
	"reflect"
	"encoding/json"

	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/pkg/api"
	"k8s.io/apimachinery/pkg/fields"
	"k8s.io/client-go/pkg/api/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/pkg/apis/extensions/v1beta1"
	"strings"
	"k8s.io/client-go/rest"
)

type LogMessage struct {
	ObjectType string
	ObjectName string
	EventType string
	AssignedNode string `json:"omitempty"`
	Replicas int32 `json:"omitempty"`
	Timestamp time.Time `json:"time"`
}

func main() {
	clientset := createClientSet()

	createWatcher(clientset.CoreV1().RESTClient(), &v1.Pod{}, "pods")
	createWatcher(clientset.CoreV1().RESTClient(), &v1.Service{}, "services")
	createWatcher(clientset.CoreV1().RESTClient(), &v1.Secret{}, "secrets")
	createWatcher(clientset.CoreV1().RESTClient(), &v1.ConfigMap{}, "configmaps")
	createWatcher(clientset.CoreV1().RESTClient(), &v1.Namespace{}, "namespaces")
	createWatcher(clientset.CoreV1().RESTClient(), &v1.ReplicationController{}, "replicationcontrollers")
	createWatcher(clientset.ExtensionsV1beta1().RESTClient(), &v1beta1.ReplicaSet{}, "replicasets")
	createWatcher(clientset.ExtensionsV1beta1().RESTClient(), &v1beta1.Ingress{}, "ingresses")
	createWatcher(clientset.ExtensionsV1beta1().RESTClient(), &v1beta1.Deployment{}, "deployments")

	for{
		time.Sleep(time.Second)
	}
}

func createWatcher(c cache.Getter, obj runtime.Object, resource string) cache.Controller {
	watchlist := cache.NewListWatchFromClient(c, resource, api.NamespaceAll, fields.Everything())
	resyncPeriod := 30 * time.Minute

	_, controller := cache.NewInformer(
		watchlist,
		obj,
		resyncPeriod,
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				toJson(obj, "Created")
			},
			DeleteFunc: func(obj interface{}) {
				toJson(obj, "Deleted")
			},
			UpdateFunc: func(oldObj, newObj interface{}) {
				toJson(newObj, "Updated")
			},
		},
	)

	go controller.Run(wait.NeverStop)
	return controller
}

func toJson(obj interface{}, eventType string) string {
	objType := reflect.TypeOf(obj)

	logMessage := &LogMessage{ObjectType: strings.TrimLeft(objType.String(), "*"), ObjectName: getName(obj), EventType: eventType, Timestamp: time.Now().UTC()}

	//Add additional information to log message
	switch t := obj.(type) {
	case *v1.Pod:
		logMessage.AssignedNode = t.Spec.NodeName
	case *v1beta1.Deployment:
		logMessage.Replicas = *t.Spec.Replicas
	case *v1beta1.ReplicaSet:
		logMessage.Replicas = *t.Spec.Replicas
	}

	b, err := json.Marshal(logMessage)
	if err != nil {
		fmt.Println(err)
		return ""
	}

	jsonString := string(b)
	fmt.Println(jsonString)
	return string(jsonString)
}

func getName(obj interface{}) string {
	switch t := obj.(type) {
	default:
		return "Unknown Name"
	case *v1.Namespace:
		return t.ObjectMeta.Name
	case *v1.Pod:
		return t.ObjectMeta.Name
	case *v1beta1.Deployment:
		return t.ObjectMeta.Name
	case *v1beta1.DaemonSet:
		return t.ObjectMeta.Name
	case *v1beta1.ReplicaSet:
		return t.ObjectMeta.Name
	case *v1.Secret:
		return t.ObjectMeta.Name
	case *v1.ConfigMap:
		return t.ObjectMeta.Name
	case *v1beta1.Ingress:
		return t.ObjectMeta.Name
	case *v1.Service:
		return t.ObjectMeta.Name
	}

	return "Unknown Name"
}

func createClientSet() *kubernetes.Clientset {
	var kubeconfig *string
	if home := homeDir(); home != "" {
		kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
	} else {
		kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
	}
	flag.Parse()

	//Default to using kubeconfig or commandline arg
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
	if err != nil {
		// kubeconfig failed attempt in cluster config
		// creates the in-cluster config
		fmt.Println("Creating in cluster configuration...")
		config, err = rest.InClusterConfig()
		if err != nil {
			panic(err.Error())
		}
	}

	return buildClientSet(config)
}

func buildClientSet(config *rest.Config) *kubernetes.Clientset {
	// create the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err.Error())
	}

	return clientset
}

func homeDir() string {
	if h := os.Getenv("HOME"); h != "" {
		return h
	}
	return os.Getenv("USERPROFILE") // windows
}<|endoftext|>


<commit_before>package main

import "fmt"

func main() {

	fmt.Printf("Hello, world!\n")
}
<commit_msg>some json<commit_after>package main

import (
	"encoding/json"
	"net/http"

	"github.com/codegangsta/martini"
)

func main() {
	m := martini.Classic()

	t := thing{
		Name: "Brian",
		Age:  39,
	}

	m.Get("/", func(w http.ResponseWriter) string {
		w.Header().Set("Content-Type", "application/json")
		return must(json.Marshal(t))
	})
	m.Run()
}

func must(data []byte, err error) string {
	if err != nil {
		panic(err)
	}
	return string(data)
}

type thing struct {
	Name string `json:"name"`
	Age  int `json:"age"`
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"crypto/tls"
	"flag"
	"fmt"
	"github.com/jbogarin/go-cisco-spark/ciscospark"
	"log"
	"net/http"
	"os"
	"strings"
)

func main() {
	// START: figure out flag sets
	// helpOpt := flag.Bool("h", false, "print help message and exit")
	// flag.Parse()

	// if *helpOpt {
	//		flag.PrintDefaults()
	//		os.Exit(0)
	//}

	msgCommand := flag.NewFlagSet("msg", flag.ExitOnError)

	msgPersonOpt := msgCommand.String("p", "", "send message to a person")

	// verify that a sub command has been provided
	if len(os.Args) < 2 {
		fmt.Println("msg command is required")
		os.Exit(1)
	}

	// parse CLI options for each subcommand
	switch os.Args[1] {
	case "msg":
		msgCommand.Parse(os.Args[2:])
	default:
		flag.PrintDefaults()
		os.Exit(1)
	}

	if msgCommand.Parsed() {
		// TODO: sort out required and optional options
		fmt.Printf("msgPersonOpt: %s\n", *msgPersonOpt)
	}

	os.Exit(0)

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	sparkClient := ciscospark.NewClient(client)

	reader := bufio.NewReader(os.Stdin)
	fmt.Print("Enter Auth Token: ")
	token, _ := reader.ReadString('\n')
	token = strings.TrimSuffix(token, "\n")
	sparkClient.Authorization = "Bearer " + token

	myPersonID := "722bb271-d7ca-4bce-a9e3-471e4412fa77"

	// POST messages - Text Message
	message := &ciscospark.MessageRequest{
		Text:       "This is a text message",
		ToPersonID: myPersonID,
	}
	newTextMessage, _, err := sparkClient.Messages.Post(message)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("POST:", newTextMessage.ID, newTextMessage.Text, newTextMessage.Created)
}
<commit_msg>Add link to tutorial article<commit_after>package main

import (
	"bufio"
	"crypto/tls"
	"flag"
	"fmt"
	"github.com/jbogarin/go-cisco-spark/ciscospark"
	"log"
	"net/http"
	"os"
	"strings"
)

func main() {
	// START: figure out flag sets
	// helpOpt := flag.Bool("h", false, "print help message and exit")
	// flag.Parse()

	// if *helpOpt {
	//		flag.PrintDefaults()
	//		os.Exit(0)
	//}

	//
	// https://blog.komand.com/build-a-simple-cli-tool-with-golang
	//

	msgCommand := flag.NewFlagSet("msg", flag.ExitOnError)

	msgPersonOpt := msgCommand.String("p", "", "send message to a person")

	// verify that a sub command has been provided
	if len(os.Args) < 2 {
		fmt.Println("msg command is required")
		os.Exit(1)
	}

	// parse CLI options for each subcommand
	switch os.Args[1] {
	case "msg":
		msgCommand.Parse(os.Args[2:])
	default:
		flag.PrintDefaults()
		os.Exit(1)
	}

	if msgCommand.Parsed() {
		// TODO: sort out required and optional options
		fmt.Printf("msgPersonOpt: %s\n", *msgPersonOpt)
	}

	os.Exit(0)

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	sparkClient := ciscospark.NewClient(client)

	reader := bufio.NewReader(os.Stdin)
	fmt.Print("Enter Auth Token: ")
	token, _ := reader.ReadString('\n')
	token = strings.TrimSuffix(token, "\n")
	sparkClient.Authorization = "Bearer " + token

	myPersonID := "722bb271-d7ca-4bce-a9e3-471e4412fa77"

	// POST messages - Text Message
	message := &ciscospark.MessageRequest{
		Text:       "This is a text message",
		ToPersonID: myPersonID,
	}
	newTextMessage, _, err := sparkClient.Messages.Post(message)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("POST:", newTextMessage.ID, newTextMessage.Text, newTextMessage.Created)
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * Copyright (c) 2014, K. S. Ernest "iFire" Lee */

package main

import (
	"github.com/fire/pgxc-ctl-go/exec"
)

func main() {
	var ai exec.Auth_info
	ai.Username = "admin"
	ai.Server = "192.168.1.81:22"
	var cmds []string
	cmds = append(cmds, "/usr/bin/env ls")
	cmds = append(cmds, "/usr/bin/env ifconfig")
	exec.Execute(ai, cmds)
}
<commit_msg>Use cli library.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * Copyright (c) 2014, K. S. Ernest "iFire" Lee */

package main

import (
	"os"
	"github.com/codegangsta/cli"
	"github.com/fire/pgxc-ctl-go/exec"
)

func main() {
	app := cli.NewApp()
	app.Name = "pgxc"
	app.Usage = "Controls a postgresqlxl cluster"
	app.Action = func(c *cli.Context) {
		var ai exec.Auth_info
		ai.Username = "admin"
		ai.Server = "192.168.1.81:22"
		var cmds []string
		cmds = append(cmds, "/usr/bin/env whoami")
		cmds = append(cmds, "/usr/bin/env ifconfig")
		exec.Execute(ai, cmds)
	}
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"runtime"

	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"

	stdlog "log"
)

var (
	version   string
	branch    string
	revision  string
	buildDate string
	goVersion = runtime.Version()
)

func main() {

	ciServer := getEstafetteEnv("ESTAFETTE_CI_SERVER")
	if ciServer == "gocd" {
		// pretty print for go.cd integration
		log.Logger = zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr}).With().
			Timestamp().
			Logger()
	} else {
		// log as severity for stackdriver logging to recognize the level
		zerolog.LevelFieldName = "severity"

		// set some default fields added to all logs
		log.Logger = zerolog.New(os.Stdout).With().
			Timestamp().
			Str("app", "estafette-ci-builder").
			Str("version", version).
			Logger()
	}

	stdlog.SetFlags(0)
	stdlog.SetOutput(log.Logger)

	// log startup message
	log.Info().
		Str("branch", branch).
		Str("revision", revision).
		Str("buildDate", buildDate).
		Str("goVersion", goVersion).
		Msg("Starting estafette-ci-builder...")

	if ciServer == "estafette" {

		err := startDockerDaemon()
		if err != nil {
			handleFatal(err, "Error starting docker daemon")
		}

		gitName := getEstafetteEnv("ESTAFETTE_GIT_NAME")
		gitURL := getEstafetteEnv("ESTAFETTE_GIT_URL")
		gitBranch := getEstafetteEnv("ESTAFETTE_GIT_BRANCH")
		gitRevision := getEstafetteEnv("ESTAFETTE_GIT_REVISION")

		// git clone to specific branch and revision
		err = gitCloneRevision(gitName, gitURL, gitBranch, gitRevision)
		if err != nil {
			handleFatal(err, fmt.Sprintf("Error cloning git repository %v to branch %v and revision %v...", gitName, gitBranch, gitRevision))
		}

		if !manifestExists(".estafette.yaml") {
			log.Info().Msg(".estafette.yaml file does not exist, exiting...")
			os.Exit(0)
		}

		// check if docker daemon is ready for usage
		waitForDockerDaemon()
	}

	// read yaml
	manifest, err := readManifest(".estafette.yaml")
	if err != nil {
		handleFatal(err, "Reading .estafette.yaml manifest failed")
	}

	// get current working directory
	dir, err := os.Getwd()
	if err != nil {
		handleFatal(err, "Getting current working directory failed")
	}

	log.Info().Msgf("Running %v pipelines", len(manifest.Pipelines))

	err = setEstafetteGlobalEnvvars()
	if err != nil {
		handleFatal(err, "Setting global environment variables failed")
	}

	envvars := collectEstafetteEnvvars(manifest)

	result := runPipelines(manifest, dir, envvars)

	if ciServer == "gocd" {
		renderStats(result)
	}

	if ciServer == "estafette" {
		// todo send result to ci-api
		log.Info().Msg("Finished running pipelines")
		sendBuildFinishedEvent()
		os.Exit(0)
	}

	handleExit(result)
}
<commit_msg>also clean up job if it has no manifest<commit_after>package main

import (
	"fmt"
	"os"
	"runtime"

	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"

	stdlog "log"
)

var (
	version   string
	branch    string
	revision  string
	buildDate string
	goVersion = runtime.Version()
)

func main() {

	ciServer := getEstafetteEnv("ESTAFETTE_CI_SERVER")
	if ciServer == "gocd" {
		// pretty print for go.cd integration
		log.Logger = zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr}).With().
			Timestamp().
			Logger()
	} else {
		// log as severity for stackdriver logging to recognize the level
		zerolog.LevelFieldName = "severity"

		// set some default fields added to all logs
		log.Logger = zerolog.New(os.Stdout).With().
			Timestamp().
			Str("app", "estafette-ci-builder").
			Str("version", version).
			Logger()
	}

	stdlog.SetFlags(0)
	stdlog.SetOutput(log.Logger)

	// log startup message
	log.Info().
		Str("branch", branch).
		Str("revision", revision).
		Str("buildDate", buildDate).
		Str("goVersion", goVersion).
		Msg("Starting estafette-ci-builder...")

	if ciServer == "estafette" {

		err := startDockerDaemon()
		if err != nil {
			handleFatal(err, "Error starting docker daemon")
		}

		gitName := getEstafetteEnv("ESTAFETTE_GIT_NAME")
		gitURL := getEstafetteEnv("ESTAFETTE_GIT_URL")
		gitBranch := getEstafetteEnv("ESTAFETTE_GIT_BRANCH")
		gitRevision := getEstafetteEnv("ESTAFETTE_GIT_REVISION")

		// git clone to specific branch and revision
		err = gitCloneRevision(gitName, gitURL, gitBranch, gitRevision)
		if err != nil {
			handleFatal(err, fmt.Sprintf("Error cloning git repository %v to branch %v and revision %v...", gitName, gitBranch, gitRevision))
		}

		if !manifestExists(".estafette.yaml") {
			log.Info().Msg(".estafette.yaml file does not exist, exiting...")
			sendBuildFinishedEvent()
			os.Exit(0)
		}

		// check if docker daemon is ready for usage
		waitForDockerDaemon()
	}

	// read yaml
	manifest, err := readManifest(".estafette.yaml")
	if err != nil {
		handleFatal(err, "Reading .estafette.yaml manifest failed")
	}

	// get current working directory
	dir, err := os.Getwd()
	if err != nil {
		handleFatal(err, "Getting current working directory failed")
	}

	log.Info().Msgf("Running %v pipelines", len(manifest.Pipelines))

	err = setEstafetteGlobalEnvvars()
	if err != nil {
		handleFatal(err, "Setting global environment variables failed")
	}

	envvars := collectEstafetteEnvvars(manifest)

	result := runPipelines(manifest, dir, envvars)

	if ciServer == "gocd" {
		renderStats(result)
	}

	if ciServer == "estafette" {
		// todo send result to ci-api
		log.Info().Msg("Finished running pipelines")
		sendBuildFinishedEvent()
		os.Exit(0)
	}

	handleExit(result)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"github.com/jbuchbinder/go-gmetric/gmetric"
	"log"
	"net"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"
)

const (
	TCP = "tcp"
	UDP = "udp"
)

type Packet struct {
	Bucket   string
	Value    string
	Modifier string
	Sampling float32
}

var (
	serviceAddress   = flag.String("address", ":8125", "UDP service address")
	graphiteAddress  = flag.String("graphite", "", "Graphite service address (example: 'localhost:2003')")
	gangliaAddress   = flag.String("ganglia", "localhost", "Ganglia gmond servers, comma separated")
	gangliaPort      = flag.Int("ganglia-port", 8649, "Ganglia gmond service port")
	gangliaSpoofHost = flag.String("ganglia-spoof-host", "", "Ganglia gmond spoof host string")
	flushInterval    = flag.Int64("flush-interval", 10, "Flush interval")
	percentThreshold = flag.Int("percent-threshold", 90, "Threshold percent")
	debug            = flag.Bool("debug", false, "Debug mode")
)

var (
	In       = make(chan Packet, 10000)
	counters = make(map[string]int)
	timers   = make(map[string][]int)
	gauges   = make(map[string]int)
)

func monitor() {
	var err error
	if err != nil {
		log.Println(err)
	}
	t := time.NewTicker(time.Duration(*flushInterval) * time.Second)
	for {
		select {
		case <-t.C:
			submit()
		case s := <-In:
			if s.Modifier == "ms" {
				_, ok := timers[s.Bucket]
				if !ok {
					var t []int
					timers[s.Bucket] = t
				}
				intValue, _ := strconv.Atoi(s.Value)
				timers[s.Bucket] = append(timers[s.Bucket], intValue)
			} else if s.Modifier == "g" {
				_, ok := gauges[s.Bucket]
				if !ok {
					gauges[s.Bucket] = 0
				}
				intValue, _ := strconv.Atoi(s.Value)
				gauges[s.Bucket] += intValue
			} else {
				_, ok := counters[s.Bucket]
				if !ok {
					counters[s.Bucket] = 0
				}
				floatValue, _ := strconv.ParseFloat(s.Value, 32)
				counters[s.Bucket] += int(float32(floatValue) * (1 / s.Sampling))
			}
		}
	}
}

func submit() {
	var clientGraphite net.Conn
	if clientGraphite != nil {
		log.Println(clientGraphite)
	}
	var err error
	if err != nil {
		log.Println(err)
	}
	if *graphiteAddress != "" {
		clientGraphite, err := net.Dial(TCP, *graphiteAddress)
		if clientGraphite != nil {
			// Run this when we're all done, only if clientGraphite was opened.
			defer clientGraphite.Close()
		}
		if err != nil {
			log.Printf(err.Error())
		}
	}
	var useGanglia bool
	var gm gmetric.Gmetric
	gmSubmit := func(name string, value uint32) {
		if useGanglia {
			if *debug {
				fmt.Printf("Ganglia send metric %s value %d\n", name, value)
			}
			m_value := fmt.Sprint(value)
			m_units := "count"
			m_type := uint32(gmetric.VALUE_UNSIGNED_INT)
			m_slope := uint32(gmetric.SLOPE_BOTH)
			m_grp := "statsd"
			m_ival := uint32(*flushInterval * int64(2))

			go gm.SendMetric(name, m_value, m_type, m_units, m_slope, m_ival, m_ival, m_grp)
		}
	}
	if *gangliaAddress != "" {
		gm = gmetric.Gmetric{
			Host:  *gangliaSpoofHost,
			Spoof: *gangliaSpoofHost,
		}
		gm.SetVerbose(false)

		if strings.Contains(*gangliaAddress, ",") {
			segs := strings.Split(*gangliaAddress, ",")
			for i := 0; i < len(segs); i++ {
				gIP, err := net.ResolveIPAddr("ip4", segs[i])
				if err != nil {
					panic(err.Error())
				}
				gm.AddServer(gmetric.GmetricServer{gIP.IP, *gangliaPort})
			}
		} else {
			gIP, err := net.ResolveIPAddr("ip4", *gangliaAddress)
			if err != nil {
				panic(err.Error())
			}
			gm.AddServer(gmetric.GmetricServer{gIP.IP, *gangliaPort})
		}
		useGanglia = true
	} else {
		useGanglia = false
	}
	numStats := 0
	now := time.Now()
	buffer := bytes.NewBufferString("")
	for s, c := range counters {
		value := int64(c) / ((*flushInterval * int64(time.Second)) / 1e3)
		fmt.Fprintf(buffer, "stats.%s %d %d\n", s, value, now)
		gmSubmit(fmt.Sprintf("stats_%s", s), uint32(value))
		fmt.Fprintf(buffer, "stats_counts.%s %d %d\n", s, c, now)
		gmSubmit(fmt.Sprintf("stats_counts_%s", s), uint32(c))
		counters[s] = 0
		numStats++
	}
	for i, g := range gauges {
		value := int64(g)
		fmt.Fprintf(buffer, "stats.%s %d %d\n", i, value, now)
		gmSubmit(fmt.Sprintf("stats_%s", i), uint32(value))
		numStats++
	}
	for u, t := range timers {
		if len(t) > 0 {
			sort.Ints(t)
			min := t[0]
			max := t[len(t)-1]
			mean := min
			maxAtThreshold := max
			count := len(t)
			if len(t) > 1 {
				var thresholdIndex int
				thresholdIndex = ((100 - *percentThreshold) / 100) * count
				numInThreshold := count - thresholdIndex
				values := t[0:numInThreshold]

				sum := 0
				for i := 0; i < numInThreshold; i++ {
					sum += values[i]
				}
				mean = sum / numInThreshold
			}
			var z []int
			timers[u] = z

			fmt.Fprintf(buffer, "stats.timers.%s.mean %d %d\n", u, mean, now)
			gmSubmit(fmt.Sprintf("stats_timers_%s_mean", u), uint32(mean))
			fmt.Fprintf(buffer, "stats.timers.%s.upper %d %d\n", u, max, now)
			gmSubmit(fmt.Sprintf("stats_timers_%s_upper", u), uint32(max))
			fmt.Fprintf(buffer, "stats.timers.%s.upper_%d %d %d\n", u,
				*percentThreshold, maxAtThreshold, now)
			gmSubmit(fmt.Sprintf("stats_timers_%s_upper_%d", u, *percentThreshold), uint32(maxAtThreshold))
			fmt.Fprintf(buffer, "stats.timers.%s.lower %d %d\n", u, min, now)
			gmSubmit(fmt.Sprintf("stats_timers_%s_lower", u), uint32(min))
			fmt.Fprintf(buffer, "stats.timers.%s.count %d %d\n", u, count, now)
			gmSubmit(fmt.Sprintf("stats_timers_%s_count", u), uint32(count))
		}
		numStats++
	}
	fmt.Fprintf(buffer, "statsd.numStats %d %d\n", numStats, now)
	gmSubmit("statsd_numStats", uint32(numStats))
	if clientGraphite != nil {
		if *debug {
			fmt.Printf("Send to graphite: [[[%s]]]\n", string(buffer.Bytes()))
		}
		clientGraphite.Write(buffer.Bytes())
	}
}

func handleMessage(conn *net.UDPConn, remaddr net.Addr, buf *bytes.Buffer) {
	var packet Packet
	var value string
	var sanitizeRegexp = regexp.MustCompile("[^a-zA-Z0-9\\-_\\.:\\|@]")
	var packetRegexp = regexp.MustCompile("([a-zA-Z0-9_]+):([0-9\\.]+)\\|(c|ms)(\\|@([0-9\\.]+))?")
	s := sanitizeRegexp.ReplaceAllString(buf.String(), "")
	for _, item := range packetRegexp.FindAllStringSubmatch(s, -1) {
		value = item[2]
		_, err := strconv.Atoi(item[2])
		if err != nil {
			if item[3] == "ms" {
				value = "0"
			} else {
				value = "1"
			}
		}

		sampleRate, err := strconv.ParseFloat(item[5], 32)
		if err != nil {
			sampleRate = 1
		}

		packet.Bucket = item[1]
		packet.Value = value
		packet.Modifier = item[3]
		packet.Sampling = float32(sampleRate)

		if *debug {
			fmt.Printf("Packet: bucket = %s, value = %s, modifier = %s, sampling = %f\n", packet.Bucket, packet.Value, packet.Modifier, packet.Sampling)
		}

		In <- packet
	}
}

func udpListener() {
	address, _ := net.ResolveUDPAddr(UDP, *serviceAddress)
	listener, err := net.ListenUDP(UDP, address)
	defer listener.Close()
	if err != nil {
		log.Fatalf("ListenAndServe: %s", err.Error())
	}
	for {
		message := make([]byte, 512)
		n, remaddr, error := listener.ReadFrom(message)
		if error != nil {
			continue
		}
		buf := bytes.NewBuffer(message[0:n])
		if *debug {
			fmt.Printf("Packet received: " + string(message[0:n]) + "\n")
		}
		go handleMessage(listener, remaddr, buf)
	}
}

func main() {
	flag.Parse()
	go udpListener()
	monitor()
}
<commit_msg>Fix from Vlad, move timers to float64<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"github.com/jbuchbinder/go-gmetric/gmetric"
	"log"
	"net"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"
)

const (
	TCP = "tcp"
	UDP = "udp"
)

type Packet struct {
	Bucket   string
	Value    string
	Modifier string
	Sampling float32
}

var (
	serviceAddress   = flag.String("address", ":8125", "UDP service address")
	graphiteAddress  = flag.String("graphite", "", "Graphite service address (example: 'localhost:2003')")
	gangliaAddress   = flag.String("ganglia", "localhost", "Ganglia gmond servers, comma separated")
	gangliaPort      = flag.Int("ganglia-port", 8649, "Ganglia gmond service port")
	gangliaSpoofHost = flag.String("ganglia-spoof-host", "", "Ganglia gmond spoof host string")
	flushInterval    = flag.Int64("flush-interval", 10, "Flush interval")
	percentThreshold = flag.Int("percent-threshold", 90, "Threshold percent")
	debug            = flag.Bool("debug", false, "Debug mode")
)

var (
	In       = make(chan Packet, 10000)
	counters = make(map[string]int)
	timers   = make(map[string][]float64)
	gauges   = make(map[string]int)
)

func monitor() {
	var err error
	if err != nil {
		log.Println(err)
	}
	t := time.NewTicker(time.Duration(*flushInterval) * time.Second)
	for {
		select {
		case <-t.C:
			submit()
		case s := <-In:
			if s.Modifier == "ms" {
				_, ok := timers[s.Bucket]
				if !ok {
					var t []float64
					timers[s.Bucket] = t
				}
				//intValue, _ := strconv.Atoi(s.Value)
				floatValue, _ := strconv.ParseFloat(s.Value, 64)
				timers[s.Bucket] = append(timers[s.Bucket], floatValue)
			} else if s.Modifier == "g" {
				_, ok := gauges[s.Bucket]
				if !ok {
					gauges[s.Bucket] = 0
				}
				intValue, _ := strconv.Atoi(s.Value)
				gauges[s.Bucket] += intValue
			} else {
				_, ok := counters[s.Bucket]
				if !ok {
					counters[s.Bucket] = 0
				}
				floatValue, _ := strconv.ParseFloat(s.Value, 32)
				counters[s.Bucket] += int(float32(floatValue) * (1 / s.Sampling))
			}
		}
	}
}

func submit() {
	var clientGraphite net.Conn
	if clientGraphite != nil {
		log.Println(clientGraphite)
	}
	var err error
	if err != nil {
		log.Println(err)
	}
	if *graphiteAddress != "" {
		clientGraphite, err := net.Dial(TCP, *graphiteAddress)
		if clientGraphite != nil {
			// Run this when we're all done, only if clientGraphite was opened.
			defer clientGraphite.Close()
		}
		if err != nil {
			log.Printf(err.Error())
		}
	}
	var useGanglia bool
	var gm gmetric.Gmetric
	gmSubmit := func(name string, value uint32) {
		if useGanglia {
			if *debug {
				fmt.Printf("Ganglia send metric %s value %d\n", name, value)
			}
			m_value := fmt.Sprint(value)
			m_units := "count"
			m_type := uint32(gmetric.VALUE_UNSIGNED_INT)
			m_slope := uint32(gmetric.SLOPE_BOTH)
			m_grp := "statsd"
			m_ival := uint32(*flushInterval * int64(2))

			go gm.SendMetric(name, m_value, m_type, m_units, m_slope, m_ival, m_ival, m_grp)
		}
	}
	gmSubmitFloat := func(name string, value float64) {
		if useGanglia {
			if *debug {
				fmt.Printf("Ganglia send metric %s value %f\n", name, value)
			}
			m_value := fmt.Sprint(value)
			m_units := "count"
			m_type := uint32(gmetric.VALUE_DOUBLE)
			m_slope := uint32(gmetric.SLOPE_BOTH)
			m_grp := "statsd"
			m_ival := uint32(*flushInterval * int64(2))

			go gm.SendMetric(name, m_value, m_type, m_units, m_slope, m_ival, m_ival, m_grp)
		}
	}
	if *gangliaAddress != "" {
		gm = gmetric.Gmetric{
			Host:  *gangliaSpoofHost,
			Spoof: *gangliaSpoofHost,
		}
		gm.SetVerbose(false)

		if strings.Contains(*gangliaAddress, ",") {
			segs := strings.Split(*gangliaAddress, ",")
			for i := 0; i < len(segs); i++ {
				gIP, err := net.ResolveIPAddr("ip4", segs[i])
				if err != nil {
					panic(err.Error())
				}
				gm.AddServer(gmetric.GmetricServer{gIP.IP, *gangliaPort})
			}
		} else {
			gIP, err := net.ResolveIPAddr("ip4", *gangliaAddress)
			if err != nil {
				panic(err.Error())
			}
			gm.AddServer(gmetric.GmetricServer{gIP.IP, *gangliaPort})
		}
		useGanglia = true
	} else {
		useGanglia = false
	}
	numStats := 0
	now := time.Now()
	buffer := bytes.NewBufferString("")
	for s, c := range counters {
		value := float64(c) / float64((float64(*flushInterval)*float64(time.Second))/float64(1e3))
		fmt.Fprintf(buffer, "stats.%s %d %d\n", s, value, now)
		gmSubmitFloat(fmt.Sprintf("stats_%s", s), value)
		fmt.Fprintf(buffer, "stats_counts.%s %d %d\n", s, c, now)
		gmSubmit(fmt.Sprintf("stats_counts_%s", s), uint32(c))
		counters[s] = 0
		numStats++
	}
	for i, g := range gauges {
		value := int64(g)
		fmt.Fprintf(buffer, "stats.%s %d %d\n", i, value, now)
		gmSubmit(fmt.Sprintf("stats_%s", i), uint32(value))
		numStats++
	}
	for u, t := range timers {
		if len(t) > 0 {
			sort.Float64s(t)
			min := float64(t[0])
			max := float64(t[len(t)-1])
			mean := float64(min)
			maxAtThreshold := float64(max)
			count := len(t)
			if len(t) > 1 {
				var thresholdIndex int
				thresholdIndex = ((100 - *percentThreshold) / 100) * count
				numInThreshold := count - thresholdIndex
				values := t[0:numInThreshold]

				sum := float64(0)
				for i := 0; i < numInThreshold; i++ {
					sum += values[i]
				}
				mean = float64(sum) / float64(numInThreshold)
			}
			var z []float64
			timers[u] = z

			fmt.Fprintf(buffer, "stats.timers.%s.mean %f %d\n", u, mean, now)
			gmSubmitFloat(fmt.Sprintf("stats_timers_%s_mean", u), mean)
			fmt.Fprintf(buffer, "stats.timers.%s.upper %f %d\n", u, max, now)
			gmSubmitFloat(fmt.Sprintf("stats_timers_%s_upper", u), max)
			fmt.Fprintf(buffer, "stats.timers.%s.upper_%d %f %d\n", u,
				*percentThreshold, maxAtThreshold, now)
			gmSubmitFloat(fmt.Sprintf("stats_timers_%s_upper_%d", u, *percentThreshold), maxAtThreshold)
			fmt.Fprintf(buffer, "stats.timers.%s.lower %f %d\n", u, min, now)
			gmSubmitFloat(fmt.Sprintf("stats_timers_%s_lower", u), min)
			fmt.Fprintf(buffer, "stats.timers.%s.count %d %d\n", u, count, now)
			gmSubmit(fmt.Sprintf("stats_timers_%s_count", u), uint32(count))
		}
		numStats++
	}
	fmt.Fprintf(buffer, "statsd.numStats %d %d\n", numStats, now)
	gmSubmit("statsd_numStats", uint32(numStats))
	if clientGraphite != nil {
		if *debug {
			fmt.Printf("Send to graphite: [[[%s]]]\n", string(buffer.Bytes()))
		}
		clientGraphite.Write(buffer.Bytes())
	}
}

func handleMessage(conn *net.UDPConn, remaddr net.Addr, buf *bytes.Buffer) {
	var packet Packet
	var value string
	var sanitizeRegexp = regexp.MustCompile("[^a-zA-Z0-9\\-_\\.:\\|@]")
	var packetRegexp = regexp.MustCompile("([a-zA-Z0-9_]+):(\\-?[0-9\\.]+)\\|(c|ms)(\\|@([0-9\\.]+))?")
	s := sanitizeRegexp.ReplaceAllString(buf.String(), "")
	for _, item := range packetRegexp.FindAllStringSubmatch(s, -1) {
		value = item[2]
		if item[3] == "ms" {
			_, err := strconv.ParseFloat(item[2], 32)
			if err != nil {
				value = "0"
			} else {
				value = "1"
			}
		}

		sampleRate, err := strconv.ParseFloat(item[5], 32)
		if err != nil {
			sampleRate = 1
		}

		packet.Bucket = item[1]
		packet.Value = value
		packet.Modifier = item[3]
		packet.Sampling = float32(sampleRate)

		if *debug {
			fmt.Printf("Packet: bucket = %s, value = %s, modifier = %s, sampling = %f\n", packet.Bucket, packet.Value, packet.Modifier, packet.Sampling)
		}

		In <- packet
	}
}

func udpListener() {
	address, _ := net.ResolveUDPAddr(UDP, *serviceAddress)
	listener, err := net.ListenUDP(UDP, address)
	defer listener.Close()
	if err != nil {
		log.Fatalf("ListenAndServe: %s", err.Error())
	}
	for {
		message := make([]byte, 512)
		n, remaddr, error := listener.ReadFrom(message)
		if error != nil {
			continue
		}
		buf := bytes.NewBuffer(message[0:n])
		if *debug {
			fmt.Printf("Packet received: " + string(message[0:n]) + "\n")
		}
		go handleMessage(listener, remaddr, buf)
	}
}

func main() {
	flag.Parse()
	go udpListener()
	monitor()
}
<|endoftext|>


<commit_before>// Distributive is a tool for running distributed health checks in server clusters.
// It was designed with Consul in mind, but is platform agnostic.
// The idea is that the checks are run locally, but executed by a central server
// that records and logs their output. This model distributes responsibility to
// each node, instead of one central server, and allows for more types of checks.
package main

import (
	"os"

	"github.com/CiscoCloud/distributive/checklists"
	log "github.com/Sirupsen/logrus"
	"github.com/mitchellh/panicwrap"
)

var useCache bool // should remote checks be run from the cache when possible?

const Version = "v0.2.5"
const Name = "distributive"

// getChecklists returns a list of checklists based on the supplied sources
func getChecklists(file string, dir string, url string, stdin bool) (lsts []checklists.Checklist) {
	parseError := func(src string, err error) {
		if err != nil {
			log.WithFields(log.Fields{
				"origin": src,
				"error":  err,
			}).Fatal("Couldn't parse checklist.")
		}
	}
	msg := "Creating checklist(s)..."
	switch {
	// checklists from file are already tagged with their origin
	// this applies to FromFile, FromDirectory, FromURL
	case file != "":
		log.WithFields(log.Fields{
			"type": "file",
			"path": file,
		}).Info(msg)
		chklst, err := checklists.FromFile(file)
		parseError(file, err)
		lsts = append(lsts, chklst)
	case dir != "":
		log.WithFields(log.Fields{
			"type": "dir",
			"path": dir,
		}).Info(msg)
		chklsts, err := checklists.FromDirectory(dir)
		parseError(dir, err)
		lsts = append(lsts, chklsts...)
	case url != "":
		log.WithFields(log.Fields{
			"type": "url",
			"path": url,
		}).Info(msg)
		chklst, err := checklists.FromURL(url, useCache)
		parseError(url, err)
		lsts = append(lsts, chklst)
	case stdin == true:
		log.WithFields(log.Fields{
			"type": "url",
			"path": url,
		}).Info(msg)
		checklist, err := checklists.FromStdin()
		checklist.Origin = "stdin" // TODO put this in the method
		parseError("stdin", err)
		lsts = append(lsts, checklist)
	default:
		log.Fatal("Neither file, URL, directory, nor stdin specified. Try --help.")
	}
	return lsts
}

// main reads the command line flag -f, runs the Check specified in the YAML,
// and exits with the appropriate message and exit code.
func main() {
	// Set up global panic handling
	exitStatus, err := panicwrap.BasicWrap(panicHandler)
	if err != nil {
		reportURL := "https://github.com/mitchellh/panicwrap"
		log.WithFields(log.Fields{
			"err": err.Error(),
		}).Fatal("Please report this error to " + reportURL)
	}
	// If exitStatus >= 0, then we're the parent process and the panicwrap
	// re-executed ourselves and completed. Just exit with the proper status.
	if exitStatus >= 0 {
		os.Exit(exitStatus)
	}
	// Otherwise, exitStatus < 0 means we're the child. Continue executing as
	// normal...

	// Set up and parse flags
	log.Debug("Parsing flags")
	file, URL, directory, stdin := getFlags()
	log.Debug("Validating flags")
	validateFlags(file, URL, directory)
	// add workers to workers, parameterLength
	log.Debug("Running checklists")
	exitCode := 0
	for _, chklst := range getChecklists(file, directory, URL, stdin) {
		anyFailed, report := chklst.MakeReport()
		if anyFailed {
			exitCode = 1
		}
		log.WithFields(log.Fields{
			"checklist": chklst.Name,
			"report":    report,
		}).Info("Report from checklist")
	}
	os.Exit(exitCode)
}
<commit_msg>refactor: proper linkage of checks/<commit_after>// Distributive is a tool for running distributed health checks in server clusters.
// It was designed with Consul in mind, but is platform agnostic.
// The idea is that the checks are run locally, but executed by a central server
// that records and logs their output. This model distributes responsibility to
// each node, instead of one central server, and allows for more types of checks.
package main

import (
	"os"

	"github.com/CiscoCloud/distributive/checklists"
	log "github.com/Sirupsen/logrus"
	"github.com/mitchellh/panicwrap"
    _ "github.com/CiscoCloud/distributive/checks"
)

var useCache bool // should remote checks be run from the cache when possible?

const Version = "v0.2.5"
const Name = "distributive"

// getChecklists returns a list of checklists based on the supplied sources
func getChecklists(file string, dir string, url string, stdin bool) (lsts []checklists.Checklist) {
	parseError := func(src string, err error) {
		if err != nil {
			log.WithFields(log.Fields{
				"origin": src,
				"error":  err,
			}).Fatal("Couldn't parse checklist.")
		}
	}
	msg := "Creating checklist(s)..."
	switch {
	// checklists from file are already tagged with their origin
	// this applies to FromFile, FromDirectory, FromURL
	case file != "":
		log.WithFields(log.Fields{
			"type": "file",
			"path": file,
		}).Info(msg)
		chklst, err := checklists.FromFile(file)
		parseError(file, err)
		lsts = append(lsts, chklst)
	case dir != "":
		log.WithFields(log.Fields{
			"type": "dir",
			"path": dir,
		}).Info(msg)
		chklsts, err := checklists.FromDirectory(dir)
		parseError(dir, err)
		lsts = append(lsts, chklsts...)
	case url != "":
		log.WithFields(log.Fields{
			"type": "url",
			"path": url,
		}).Info(msg)
		chklst, err := checklists.FromURL(url, useCache)
		parseError(url, err)
		lsts = append(lsts, chklst)
	case stdin == true:
		log.WithFields(log.Fields{
			"type": "url",
			"path": url,
		}).Info(msg)
		checklist, err := checklists.FromStdin()
		checklist.Origin = "stdin" // TODO put this in the method
		parseError("stdin", err)
		lsts = append(lsts, checklist)
	default:
		log.Fatal("Neither file, URL, directory, nor stdin specified. Try --help.")
	}
	return lsts
}

// main reads the command line flag -f, runs the Check specified in the YAML,
// and exits with the appropriate message and exit code.
func main() {
	// Set up global panic handling
	exitStatus, err := panicwrap.BasicWrap(panicHandler)
	if err != nil {
		reportURL := "https://github.com/mitchellh/panicwrap"
		log.WithFields(log.Fields{
			"err": err.Error(),
		}).Fatal("Please report this error to " + reportURL)
	}
	// If exitStatus >= 0, then we're the parent process and the panicwrap
	// re-executed ourselves and completed. Just exit with the proper status.
	if exitStatus >= 0 {
		os.Exit(exitStatus)
	}
	// Otherwise, exitStatus < 0 means we're the child. Continue executing as
	// normal...

	// Set up and parse flags
	log.Debug("Parsing flags")
	file, URL, directory, stdin := getFlags()
	log.Debug("Validating flags")
	validateFlags(file, URL, directory)
	// add workers to workers, parameterLength
	log.Debug("Running checklists")
	exitCode := 0
	for _, chklst := range getChecklists(file, directory, URL, stdin) {
		anyFailed, report := chklst.MakeReport()
		if anyFailed {
			exitCode = 1
		}
		log.WithFields(log.Fields{
			"checklist": chklst.Name,
			"report":    report,
		}).Info("Report from checklist")
	}
	os.Exit(exitCode)
}
<|endoftext|>