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

package main

import (
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"syscall"

	"github.com/gorilla/mux"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"github.com/uber/jaeger-lib/metrics/go-kit"
	"github.com/uber/jaeger-lib/metrics/go-kit/expvar"
	"go.uber.org/zap"

	basicB "github.com/uber/jaeger/cmd/builder"
	"github.com/uber/jaeger/cmd/flags"
	casFlags "github.com/uber/jaeger/cmd/flags/cassandra"
	esFlags "github.com/uber/jaeger/cmd/flags/es"
	"github.com/uber/jaeger/cmd/query/app"
	"github.com/uber/jaeger/cmd/query/app/builder"
	"github.com/uber/jaeger/pkg/config"
	"github.com/uber/jaeger/pkg/healthcheck"
	"github.com/uber/jaeger/pkg/recoveryhandler"
)

func main() {
	var serverChannel = make(chan os.Signal, 0)
	signal.Notify(serverChannel, os.Interrupt, syscall.SIGTERM)

	logger, _ := zap.NewProduction()
	casOptions := casFlags.NewOptions("cassandra", "cassandra.archive")
	esOptions := esFlags.NewOptions("es", "es.archive")
	v := viper.New()

	var command = &cobra.Command{
		Use:   "jaeger-query",
		Short: "Jaeger query is a service to access tracing data",
		Long:  `Jaeger query is a service to access tracing data and host UI.`,
		Run: func(cmd *cobra.Command, args []string) {
			casOptions.InitFromViper(v)
			esOptions.InitFromViper(v)
			queryOpts := new(builder.QueryOptions).InitFromViper(v)
			sFlags := new(flags.SharedFlags).InitFromViper(v)

			hc, err := healthcheck.Serve(http.StatusServiceUnavailable, queryOpts.QueryHealthCheckHTTPPort, logger)
			if err != nil {
				logger.Fatal("Could not start the health check server.", zap.Error(err))
			}

			metricsFactory := xkit.Wrap("jaeger-query", expvar.NewFactory(10))

			storageBuild, err := builder.NewStorageBuilder(
				sFlags.SpanStorage.Type,
				sFlags.DependencyStorage.DataFrequency,
				basicB.Options.LoggerOption(logger),
				basicB.Options.MetricsFactoryOption(metricsFactory),
				basicB.Options.CassandraSessionOption(casOptions.GetPrimary()),
				basicB.Options.ElasticClientOption(esOptions.GetPrimary()),
			)
			if err != nil {
				logger.Fatal("Failed to init storage builder", zap.Error(err))
			}
			rHandler := app.NewAPIHandler(
				storageBuild.SpanReader,
				storageBuild.DependencyReader,
				app.HandlerOptions.Prefix(queryOpts.QueryPrefix),
				app.HandlerOptions.Logger(logger))
			sHandler := app.NewStaticAssetsHandler(queryOpts.QueryStaticAssets)
			r := mux.NewRouter()
			rHandler.RegisterRoutes(r)
			sHandler.RegisterRoutes(r)
			portStr := ":" + strconv.Itoa(queryOpts.QueryPort)
			recoveryHandler := recoveryhandler.NewRecoveryHandler(logger, true)

			go func() {
				logger.Info("Starting jaeger-query HTTP server", zap.Int("port", queryOpts.QueryPort))
				if err := http.ListenAndServe(portStr, recoveryHandler(r)); err != nil {
					logger.Fatal("Could not launch service", zap.Error(err))
				}
				hc.Set(http.StatusInternalServerError)
			}()

			hc.Ready()

			select {
			case <-serverChannel:
				logger.Info("Jaeger Query is finishing")
			}
		},
	}

	config.AddFlags(
		v,
		command,
		flags.AddFlags,
		casOptions.AddFlags,
		esOptions.AddFlags,
		builder.AddFlags,
	)

	if error := command.Execute(); error != nil {
		logger.Fatal(error.Error())
	}
}
<commit_msg>Add tracing to the query server (#454)<commit_after>// Copyright (c) 2017 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"syscall"

	"github.com/gorilla/mux"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	jaegerClientConfig "github.com/uber/jaeger-client-go/config"
	"github.com/uber/jaeger-lib/metrics/go-kit"
	"github.com/uber/jaeger-lib/metrics/go-kit/expvar"
	"go.uber.org/zap"

	basicB "github.com/uber/jaeger/cmd/builder"
	"github.com/uber/jaeger/cmd/flags"
	casFlags "github.com/uber/jaeger/cmd/flags/cassandra"
	esFlags "github.com/uber/jaeger/cmd/flags/es"
	"github.com/uber/jaeger/cmd/query/app"
	"github.com/uber/jaeger/cmd/query/app/builder"
	"github.com/uber/jaeger/pkg/config"
	"github.com/uber/jaeger/pkg/healthcheck"
	"github.com/uber/jaeger/pkg/recoveryhandler"
)

func main() {
	var serverChannel = make(chan os.Signal, 0)
	signal.Notify(serverChannel, os.Interrupt, syscall.SIGTERM)

	logger, _ := zap.NewProduction()
	casOptions := casFlags.NewOptions("cassandra", "cassandra.archive")
	esOptions := esFlags.NewOptions("es", "es.archive")
	v := viper.New()

	var command = &cobra.Command{
		Use:   "jaeger-query",
		Short: "Jaeger query is a service to access tracing data",
		Long:  `Jaeger query is a service to access tracing data and host UI.`,
		Run: func(cmd *cobra.Command, args []string) {
			casOptions.InitFromViper(v)
			esOptions.InitFromViper(v)
			queryOpts := new(builder.QueryOptions).InitFromViper(v)
			sFlags := new(flags.SharedFlags).InitFromViper(v)

			hc, err := healthcheck.Serve(http.StatusServiceUnavailable, queryOpts.QueryHealthCheckHTTPPort, logger)
			if err != nil {
				logger.Fatal("Could not start the health check server.", zap.Error(err))
			}

			metricsFactory := xkit.Wrap("jaeger-query", expvar.NewFactory(10))

			tracer, closer, err := jaegerClientConfig.Configuration{
				Sampler: &jaegerClientConfig.SamplerConfig{
					Type:  "probabilistic",
					Param: 1.0,
				},
				RPCMetrics: true,
			}.New("jaeger-query", jaegerClientConfig.Metrics(metricsFactory))
			if err != nil {
				logger.Fatal("Failed to initialize tracer", zap.Error(err))
			}
			defer closer.Close()

			storageBuild, err := builder.NewStorageBuilder(
				sFlags.SpanStorage.Type,
				sFlags.DependencyStorage.DataFrequency,
				basicB.Options.LoggerOption(logger),
				basicB.Options.MetricsFactoryOption(metricsFactory),
				basicB.Options.CassandraSessionOption(casOptions.GetPrimary()),
				basicB.Options.ElasticClientOption(esOptions.GetPrimary()),
			)
			if err != nil {
				logger.Fatal("Failed to init storage builder", zap.Error(err))
			}

			rHandler := app.NewAPIHandler(
				storageBuild.SpanReader,
				storageBuild.DependencyReader,
				app.HandlerOptions.Prefix(queryOpts.QueryPrefix),
				app.HandlerOptions.Logger(logger),
				app.HandlerOptions.Tracer(tracer))
			sHandler := app.NewStaticAssetsHandler(queryOpts.QueryStaticAssets)
			r := mux.NewRouter()
			rHandler.RegisterRoutes(r)
			sHandler.RegisterRoutes(r)
			portStr := ":" + strconv.Itoa(queryOpts.QueryPort)
			recoveryHandler := recoveryhandler.NewRecoveryHandler(logger, true)

			go func() {
				logger.Info("Starting jaeger-query HTTP server", zap.Int("port", queryOpts.QueryPort))
				if err := http.ListenAndServe(portStr, recoveryHandler(r)); err != nil {
					logger.Fatal("Could not launch service", zap.Error(err))
				}
				hc.Set(http.StatusInternalServerError)
			}()

			hc.Ready()

			select {
			case <-serverChannel:
				logger.Info("Jaeger Query is finishing")
			}
		},
	}

	config.AddFlags(
		v,
		command,
		flags.AddFlags,
		casOptions.AddFlags,
		esOptions.AddFlags,
		builder.AddFlags,
	)

	if error := command.Execute(); error != nil {
		logger.Fatal(error.Error())
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2016, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"runtime/pprof"
	"strings"

	"github.com/mvdan/sh/syntax"
)

var (
	write      = flag.Bool("w", false, "write result to file instead of stdout")
	list       = flag.Bool("l", false, "list files whose formatting differs from shfmt's")
	indent     = flag.Int("i", 0, "indent: 0 for tabs (default), >0 for number of spaces")
	posix      = flag.Bool("p", false, "parse POSIX shell code instead of bash")
	cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

	parseMode         syntax.ParseMode
	printConfig       syntax.PrintConfig
	readBuf, writeBuf bytes.Buffer

	copyBuf = make([]byte, 32*1024)

	out io.Writer
)

func main() {
	flag.Parse()
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	out = os.Stdout
	printConfig.Spaces = *indent
	parseMode |= syntax.ParseComments
	if *posix {
		parseMode |= syntax.PosixConformant
	}
	if flag.NArg() == 0 {
		if err := formatStdin(); err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		return
	}
	anyErr := false
	onError := func(err error) {
		anyErr = true
		fmt.Fprintln(os.Stderr, err)
	}
	for _, path := range flag.Args() {
		walk(path, onError)
	}
	if anyErr {
		os.Exit(1)
	}
}

func formatStdin() error {
	if *write || *list {
		return fmt.Errorf("-w and -l can only be used on files")
	}
	readBuf.Reset()
	if _, err := io.CopyBuffer(&readBuf, os.Stdin, copyBuf); err != nil {
		return err
	}
	src := readBuf.Bytes()
	prog, err := syntax.Parse(src, "", parseMode)
	if err != nil {
		return err
	}
	return printConfig.Fprint(out, prog)
}

var (
	shellFile    = regexp.MustCompile(`\.(sh|bash)$`)
	validShebang = regexp.MustCompile(`^#!\s?/(usr/)?bin/(env *)?(sh|bash)`)
	vcsDir       = regexp.MustCompile(`^\.(git|svn|hg)$`)
)

type shellConfidence int

const (
	notShellFile shellConfidence = iota
	ifValidShebang
	isShellFile
)

func getConfidence(info os.FileInfo) shellConfidence {
	name := info.Name()
	switch {
	case info.IsDir(), name[0] == '.', !info.Mode().IsRegular():
		return notShellFile
	case shellFile.MatchString(name):
		return isShellFile
	case strings.Contains(name, "."):
		return notShellFile // different extension
	case info.Size() < 8:
		return notShellFile // cannot possibly hold valid shebang
	default:
		return ifValidShebang
	}
}

func walk(path string, onError func(error)) {
	info, err := os.Stat(path)
	if err != nil {
		onError(err)
		return
	}
	if !info.IsDir() {
		if err := formatPath(path, false); err != nil {
			onError(err)
		}
		return
	}
	filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() && vcsDir.MatchString(info.Name()) {
			return filepath.SkipDir
		}
		if err != nil {
			onError(err)
			return nil
		}
		conf := getConfidence(info)
		if conf == notShellFile {
			return nil
		}
		err = formatPath(path, conf == ifValidShebang)
		if err != nil && !os.IsNotExist(err) {
			onError(err)
		}
		return nil
	})
}

func empty(f *os.File) error {
	if err := f.Truncate(0); err != nil {
		return err
	}
	_, err := f.Seek(0, 0)
	return err
}

func formatPath(path string, checkShebang bool) error {
	openMode := os.O_RDONLY
	if *write {
		openMode = os.O_RDWR
	}
	f, err := os.OpenFile(path, openMode, 0)
	if err != nil {
		return err
	}
	defer f.Close()
	readBuf.Reset()
	if checkShebang {
		n, err := f.Read(copyBuf[:32])
		if err != nil {
			return err
		}
		if !validShebang.Match(copyBuf[:n]) {
			return nil
		}
		readBuf.Write(copyBuf[:n])
	}
	if _, err := io.CopyBuffer(&readBuf, f, copyBuf); err != nil {
		return err
	}
	src := readBuf.Bytes()
	prog, err := syntax.Parse(src, path, parseMode)
	if err != nil {
		return err
	}
	writeBuf.Reset()
	printConfig.Fprint(&writeBuf, prog)
	res := writeBuf.Bytes()
	if !bytes.Equal(src, res) {
		if *list {
			fmt.Fprintln(out, path)
		}
		if *write {
			if err := empty(f); err != nil {
				return err
			}
			if _, err := f.Write(res); err != nil {
				return err
			}
		}
	}
	if !*list && !*write {
		if _, err := out.Write(res); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>cmd/shfmt: remove optional pprof<commit_after>// Copyright (c) 2016, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/mvdan/sh/syntax"
)

var (
	write      = flag.Bool("w", false, "write result to file instead of stdout")
	list       = flag.Bool("l", false, "list files whose formatting differs from shfmt's")
	indent     = flag.Int("i", 0, "indent: 0 for tabs (default), >0 for number of spaces")
	posix      = flag.Bool("p", false, "parse POSIX shell code instead of bash")
	cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

	parseMode         syntax.ParseMode
	printConfig       syntax.PrintConfig
	readBuf, writeBuf bytes.Buffer

	copyBuf = make([]byte, 32*1024)

	out io.Writer
)

func main() {
	flag.Parse()

	out = os.Stdout
	printConfig.Spaces = *indent
	parseMode |= syntax.ParseComments
	if *posix {
		parseMode |= syntax.PosixConformant
	}
	if flag.NArg() == 0 {
		if err := formatStdin(); err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		return
	}
	anyErr := false
	onError := func(err error) {
		anyErr = true
		fmt.Fprintln(os.Stderr, err)
	}
	for _, path := range flag.Args() {
		walk(path, onError)
	}
	if anyErr {
		os.Exit(1)
	}
}

func formatStdin() error {
	if *write || *list {
		return fmt.Errorf("-w and -l can only be used on files")
	}
	readBuf.Reset()
	if _, err := io.CopyBuffer(&readBuf, os.Stdin, copyBuf); err != nil {
		return err
	}
	src := readBuf.Bytes()
	prog, err := syntax.Parse(src, "", parseMode)
	if err != nil {
		return err
	}
	return printConfig.Fprint(out, prog)
}

var (
	shellFile    = regexp.MustCompile(`\.(sh|bash)$`)
	validShebang = regexp.MustCompile(`^#!\s?/(usr/)?bin/(env *)?(sh|bash)`)
	vcsDir       = regexp.MustCompile(`^\.(git|svn|hg)$`)
)

type shellConfidence int

const (
	notShellFile shellConfidence = iota
	ifValidShebang
	isShellFile
)

func getConfidence(info os.FileInfo) shellConfidence {
	name := info.Name()
	switch {
	case info.IsDir(), name[0] == '.', !info.Mode().IsRegular():
		return notShellFile
	case shellFile.MatchString(name):
		return isShellFile
	case strings.Contains(name, "."):
		return notShellFile // different extension
	case info.Size() < 8:
		return notShellFile // cannot possibly hold valid shebang
	default:
		return ifValidShebang
	}
}

func walk(path string, onError func(error)) {
	info, err := os.Stat(path)
	if err != nil {
		onError(err)
		return
	}
	if !info.IsDir() {
		if err := formatPath(path, false); err != nil {
			onError(err)
		}
		return
	}
	filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() && vcsDir.MatchString(info.Name()) {
			return filepath.SkipDir
		}
		if err != nil {
			onError(err)
			return nil
		}
		conf := getConfidence(info)
		if conf == notShellFile {
			return nil
		}
		err = formatPath(path, conf == ifValidShebang)
		if err != nil && !os.IsNotExist(err) {
			onError(err)
		}
		return nil
	})
}

func empty(f *os.File) error {
	if err := f.Truncate(0); err != nil {
		return err
	}
	_, err := f.Seek(0, 0)
	return err
}

func formatPath(path string, checkShebang bool) error {
	openMode := os.O_RDONLY
	if *write {
		openMode = os.O_RDWR
	}
	f, err := os.OpenFile(path, openMode, 0)
	if err != nil {
		return err
	}
	defer f.Close()
	readBuf.Reset()
	if checkShebang {
		n, err := f.Read(copyBuf[:32])
		if err != nil {
			return err
		}
		if !validShebang.Match(copyBuf[:n]) {
			return nil
		}
		readBuf.Write(copyBuf[:n])
	}
	if _, err := io.CopyBuffer(&readBuf, f, copyBuf); err != nil {
		return err
	}
	src := readBuf.Bytes()
	prog, err := syntax.Parse(src, path, parseMode)
	if err != nil {
		return err
	}
	writeBuf.Reset()
	printConfig.Fprint(&writeBuf, prog)
	res := writeBuf.Bytes()
	if !bytes.Equal(src, res) {
		if *list {
			fmt.Fprintln(out, path)
		}
		if *write {
			if err := empty(f); err != nil {
				return err
			}
			if _, err := f.Write(res); err != nil {
				return err
			}
		}
	}
	if !*list && !*write {
		if _, err := out.Write(res); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


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

// This file contains the code to check canonical methods.

package main

import (
	"fmt"
	"go/ast"
	"go/printer"
	"strings"
)

type MethodSig struct {
	args    []string
	results []string
}

// canonicalMethods lists the input and output types for Go methods
// that are checked using dynamic interface checks.  Because the
// checks are dynamic, such methods would not cause a compile error
// if they have the wrong signature: instead the dynamic check would
// fail, sometimes mysteriously.  If a method is found with a name listed
// here but not the input/output types listed here, vet complains.
//
// A few of the canonical methods have very common names.
// For example, a type might implement a Scan method that
// has nothing to do with fmt.Scanner, but we still want to check
// the methods that are intended to implement fmt.Scanner.
// To do that, the arguments that have a = prefix are treated as
// signals that the canonical meaning is intended: if a Scan
// method doesn't have a fmt.ScanState as its first argument,
// we let it go.  But if it does have a fmt.ScanState, then the
// rest has to match.
var canonicalMethods = map[string]MethodSig{
	// "Flush": {{}, {"error"}}, // http.Flusher and jpeg.writer conflict
	"Format":        {[]string{"=fmt.State", "rune"}, []string{}},            // fmt.Formatter
	"GobDecode":     {[]string{"[]byte"}, []string{"error"}},                 // gob.GobDecoder
	"GobEncode":     {[]string{}, []string{"[]byte", "error"}},               // gob.GobEncoder
	"MarshalJSON":   {[]string{}, []string{"[]byte", "error"}},               // json.Marshaler
	"MarshalXML":    {[]string{}, []string{"[]byte", "error"}},               // xml.Marshaler
	"Peek":          {[]string{"=int"}, []string{"[]byte", "error"}},         // image.reader (matching bufio.Reader)
	"ReadByte":      {[]string{}, []string{"byte", "error"}},                 // io.ByteReader
	"ReadFrom":      {[]string{"=io.Reader"}, []string{"int64", "error"}},    // io.ReaderFrom
	"ReadRune":      {[]string{}, []string{"rune", "int", "error"}},          // io.RuneReader
	"Scan":          {[]string{"=fmt.ScanState", "rune"}, []string{"error"}}, // fmt.Scanner
	"Seek":          {[]string{"=int64", "int"}, []string{"int64", "error"}}, // io.Seeker
	"UnmarshalJSON": {[]string{"[]byte"}, []string{"error"}},                 // json.Unmarshaler
	"UnreadByte":    {[]string{}, []string{"error"}},
	"UnreadRune":    {[]string{}, []string{"error"}},
	"WriteByte":     {[]string{"byte"}, []string{"error"}},                // jpeg.writer (matching bufio.Writer)
	"WriteTo":       {[]string{"=io.Writer"}, []string{"int64", "error"}}, // io.WriterTo
}

func (f *File) checkCanonicalMethod(id *ast.Ident, t *ast.FuncType) {
	if !vet("methods") {
		return
	}
	// Expected input/output.
	expect, ok := canonicalMethods[id.Name]
	if !ok {
		return
	}

	// Actual input/output
	args := typeFlatten(t.Params.List)
	var results []ast.Expr
	if t.Results != nil {
		results = typeFlatten(t.Results.List)
	}

	// Do the =s (if any) all match?
	if !f.matchParams(expect.args, args, "=") || !f.matchParams(expect.results, results, "=") {
		return
	}

	// Everything must match.
	if !f.matchParams(expect.args, args, "") || !f.matchParams(expect.results, results, "") {
		expectFmt := id.Name + "(" + argjoin(expect.args) + ")"
		if len(expect.results) == 1 {
			expectFmt += " " + argjoin(expect.results)
		} else if len(expect.results) > 1 {
			expectFmt += " (" + argjoin(expect.results) + ")"
		}

		f.b.Reset()
		if err := printer.Fprint(&f.b, f.fset, t); err != nil {
			fmt.Fprintf(&f.b, "<%s>", err)
		}
		actual := f.b.String()
		actual = strings.TrimPrefix(actual, "func")
		actual = id.Name + actual

		f.Badf(id.Pos(), "method %s should have signature %s", actual, expectFmt)
	}
}

func argjoin(x []string) string {
	y := make([]string, len(x))
	for i, s := range x {
		if s[0] == '=' {
			s = s[1:]
		}
		y[i] = s
	}
	return strings.Join(y, ", ")
}

// Turn parameter list into slice of types
// (in the ast, types are Exprs).
// Have to handle f(int, bool) and f(x, y, z int)
// so not a simple 1-to-1 conversion.
func typeFlatten(l []*ast.Field) []ast.Expr {
	var t []ast.Expr
	for _, f := range l {
		if len(f.Names) == 0 {
			t = append(t, f.Type)
			continue
		}
		for _ = range f.Names {
			t = append(t, f.Type)
		}
	}
	return t
}

// Does each type in expect with the given prefix match the corresponding type in actual?
func (f *File) matchParams(expect []string, actual []ast.Expr, prefix string) bool {
	for i, x := range expect {
		if !strings.HasPrefix(x, prefix) {
			continue
		}
		if i >= len(actual) {
			return false
		}
		if !f.matchParamType(x, actual[i]) {
			return false
		}
	}
	if prefix == "" && len(actual) > len(expect) {
		return false
	}
	return true
}

// Does this one type match?
func (f *File) matchParamType(expect string, actual ast.Expr) bool {
	if strings.HasPrefix(expect, "=") {
		expect = expect[1:]
	}
	// Strip package name if we're in that package.
	if n := len(f.file.Name.Name); len(expect) > n && expect[:n] == f.file.Name.Name && expect[n] == '.' {
		expect = expect[n+1:]
	}

	// Overkill but easy.
	f.b.Reset()
	printer.Fprint(&f.b, f.fset, actual)
	return f.b.String() == expect
}
<commit_msg>go.tools/cmd/vet: Update canonical method check for new xml.Marshaler/Unmarshaler interfaces<commit_after>// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains the code to check canonical methods.

package main

import (
	"fmt"
	"go/ast"
	"go/printer"
	"strings"
)

type MethodSig struct {
	args    []string
	results []string
}

// canonicalMethods lists the input and output types for Go methods
// that are checked using dynamic interface checks.  Because the
// checks are dynamic, such methods would not cause a compile error
// if they have the wrong signature: instead the dynamic check would
// fail, sometimes mysteriously.  If a method is found with a name listed
// here but not the input/output types listed here, vet complains.
//
// A few of the canonical methods have very common names.
// For example, a type might implement a Scan method that
// has nothing to do with fmt.Scanner, but we still want to check
// the methods that are intended to implement fmt.Scanner.
// To do that, the arguments that have a = prefix are treated as
// signals that the canonical meaning is intended: if a Scan
// method doesn't have a fmt.ScanState as its first argument,
// we let it go.  But if it does have a fmt.ScanState, then the
// rest has to match.
var canonicalMethods = map[string]MethodSig{
	// "Flush": {{}, {"error"}}, // http.Flusher and jpeg.writer conflict
	"Format":        {[]string{"=fmt.State", "rune"}, []string{}},                      // fmt.Formatter
	"GobDecode":     {[]string{"[]byte"}, []string{"error"}},                           // gob.GobDecoder
	"GobEncode":     {[]string{}, []string{"[]byte", "error"}},                         // gob.GobEncoder
	"MarshalJSON":   {[]string{}, []string{"[]byte", "error"}},                         // json.Marshaler
	"MarshalXML":    {[]string{"*xml.Encoder", "xml.StartElement"}, []string{"error"}}, // xml.Marshaler
	"Peek":          {[]string{"=int"}, []string{"[]byte", "error"}},                   // image.reader (matching bufio.Reader)
	"ReadByte":      {[]string{}, []string{"byte", "error"}},                           // io.ByteReader
	"ReadFrom":      {[]string{"=io.Reader"}, []string{"int64", "error"}},              // io.ReaderFrom
	"ReadRune":      {[]string{}, []string{"rune", "int", "error"}},                    // io.RuneReader
	"Scan":          {[]string{"=fmt.ScanState", "rune"}, []string{"error"}},           // fmt.Scanner
	"Seek":          {[]string{"=int64", "int"}, []string{"int64", "error"}},           // io.Seeker
	"UnmarshalJSON": {[]string{"[]byte"}, []string{"error"}},                           // json.Unmarshaler
	"UnmarshalXML":  {[]string{"*xml.Decoder", "xml.StartElement"}, []string{"error"}}, // xml.Unmarshaler
	"UnreadByte":    {[]string{}, []string{"error"}},
	"UnreadRune":    {[]string{}, []string{"error"}},
	"WriteByte":     {[]string{"byte"}, []string{"error"}},                // jpeg.writer (matching bufio.Writer)
	"WriteTo":       {[]string{"=io.Writer"}, []string{"int64", "error"}}, // io.WriterTo
}

func (f *File) checkCanonicalMethod(id *ast.Ident, t *ast.FuncType) {
	if !vet("methods") {
		return
	}
	// Expected input/output.
	expect, ok := canonicalMethods[id.Name]
	if !ok {
		return
	}

	// Actual input/output
	args := typeFlatten(t.Params.List)
	var results []ast.Expr
	if t.Results != nil {
		results = typeFlatten(t.Results.List)
	}

	// Do the =s (if any) all match?
	if !f.matchParams(expect.args, args, "=") || !f.matchParams(expect.results, results, "=") {
		return
	}

	// Everything must match.
	if !f.matchParams(expect.args, args, "") || !f.matchParams(expect.results, results, "") {
		expectFmt := id.Name + "(" + argjoin(expect.args) + ")"
		if len(expect.results) == 1 {
			expectFmt += " " + argjoin(expect.results)
		} else if len(expect.results) > 1 {
			expectFmt += " (" + argjoin(expect.results) + ")"
		}

		f.b.Reset()
		if err := printer.Fprint(&f.b, f.fset, t); err != nil {
			fmt.Fprintf(&f.b, "<%s>", err)
		}
		actual := f.b.String()
		actual = strings.TrimPrefix(actual, "func")
		actual = id.Name + actual

		f.Badf(id.Pos(), "method %s should have signature %s", actual, expectFmt)
	}
}

func argjoin(x []string) string {
	y := make([]string, len(x))
	for i, s := range x {
		if s[0] == '=' {
			s = s[1:]
		}
		y[i] = s
	}
	return strings.Join(y, ", ")
}

// Turn parameter list into slice of types
// (in the ast, types are Exprs).
// Have to handle f(int, bool) and f(x, y, z int)
// so not a simple 1-to-1 conversion.
func typeFlatten(l []*ast.Field) []ast.Expr {
	var t []ast.Expr
	for _, f := range l {
		if len(f.Names) == 0 {
			t = append(t, f.Type)
			continue
		}
		for _ = range f.Names {
			t = append(t, f.Type)
		}
	}
	return t
}

// Does each type in expect with the given prefix match the corresponding type in actual?
func (f *File) matchParams(expect []string, actual []ast.Expr, prefix string) bool {
	for i, x := range expect {
		if !strings.HasPrefix(x, prefix) {
			continue
		}
		if i >= len(actual) {
			return false
		}
		if !f.matchParamType(x, actual[i]) {
			return false
		}
	}
	if prefix == "" && len(actual) > len(expect) {
		return false
	}
	return true
}

// Does this one type match?
func (f *File) matchParamType(expect string, actual ast.Expr) bool {
	if strings.HasPrefix(expect, "=") {
		expect = expect[1:]
	}
	// Strip package name if we're in that package.
	if n := len(f.file.Name.Name); len(expect) > n && expect[:n] == f.file.Name.Name && expect[n] == '.' {
		expect = expect[n+1:]
	}

	// Overkill but easy.
	f.b.Reset()
	printer.Fprint(&f.b, f.fset, actual)
	return f.b.String() == expect
}
<|endoftext|>


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

// This file contains the test for untagged struct literals.

package main

import (
	"flag"
	"go/ast"
	"strings"
)

var compositeWhiteList = flag.Bool("compositewhitelist", true, "use composite white list; for testing only")

// checkUntaggedLiteral checks if a composite literal is a struct literal with
// untagged fields.
func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) {
	if !vet("composites") {
		return
	}

	typ := c.Type
	for {
		if typ1, ok := c.Type.(*ast.ParenExpr); ok {
			typ = typ1
			continue
		}
		break
	}

	switch typ.(type) {
	case *ast.ArrayType:
		return
	case *ast.MapType:
		return
	case *ast.StructType:
		return // a literal struct type does not need to use tags
	case *ast.Ident:
		// A simple type name like t or T does not need tags either,
		// since it is almost certainly declared in the current package.
		// (The exception is names being used via import . "pkg", but
		// those are already breaking the Go 1 compatibility promise,
		// so not reporting potential additional breakage seems okay.)
		return
	}

	// Otherwise the type is a selector like pkg.Name.
	// We only care if pkg.Name is a struct, not if it's a map, array, or slice.
	isStruct, typeString := f.pkg.isStruct(c)
	if !isStruct {
		return
	}

	if typeString == "" { // isStruct doesn't know
		typeString = f.gofmt(typ)
	}

	// It's a struct, or we can't tell it's not a struct because we don't have types.

	// Check if the CompositeLit contains an untagged field.
	allKeyValue := true
	for _, e := range c.Elts {
		if _, ok := e.(*ast.KeyValueExpr); !ok {
			allKeyValue = false
			break
		}
	}
	if allKeyValue {
		return
	}

	// Check that the CompositeLit's type has the form pkg.Typ.
	s, ok := c.Type.(*ast.SelectorExpr)
	if !ok {
		return
	}
	pkg, ok := s.X.(*ast.Ident)
	if !ok {
		return
	}

	// Convert the package name to an import path, and compare to a whitelist.
	path := pkgPath(f, pkg.Name)
	if path == "" {
		f.Badf(c.Pos(), "unresolvable package for %s.%s literal", pkg.Name, s.Sel.Name)
		return
	}
	typeName := path + "." + s.Sel.Name
	if *compositeWhiteList && untaggedLiteralWhitelist[typeName] {
		return
	}

	f.Warn(c.Pos(), typeString+" composite literal uses untagged fields")
}

// pkgPath returns the import path "image/png" for the package name "png".
//
// This is based purely on syntax and convention, and not on the imported
// package's contents. It will be incorrect if a package name differs from the
// leaf element of the import path, or if the package was a dot import.
func pkgPath(f *File, pkgName string) (path string) {
	for _, x := range f.file.Imports {
		s := strings.Trim(x.Path.Value, `"`)
		if x.Name != nil {
			// Catch `import pkgName "foo/bar"`.
			if x.Name.Name == pkgName {
				return s
			}
		} else {
			// Catch `import "pkgName"` or `import "foo/bar/pkgName"`.
			if s == pkgName || strings.HasSuffix(s, "/"+pkgName) {
				return s
			}
		}
	}
	return ""
}

var untaggedLiteralWhitelist = map[string]bool{
	/*
		These types are actually slices. Syntactically, we cannot tell
		whether the Typ in pkg.Typ{1, 2, 3} is a slice or a struct, so we
		whitelist all the standard package library's exported slice types.

		find $GOROOT/src/pkg -type f | grep -v _test.go | xargs grep '^type.*\[\]' | \
			grep -v ' map\[' | sed 's,/[^/]*go.type,,' | sed 's,.*src/pkg/,,' | \
			sed 's, ,.,' |  sed 's, .*,,' | grep -v '\.[a-z]' | \
			sort | awk '{ print "\"" $0 "\": true," }'
	*/
	"crypto/x509/pkix.RDNSequence":                  true,
	"crypto/x509/pkix.RelativeDistinguishedNameSET": true,
	"database/sql.RawBytes":                         true,
	"debug/macho.LoadBytes":                         true,
	"encoding/asn1.ObjectIdentifier":                true,
	"encoding/asn1.RawContent":                      true,
	"encoding/json.RawMessage":                      true,
	"encoding/xml.CharData":                         true,
	"encoding/xml.Comment":                          true,
	"encoding/xml.Directive":                        true,
	"go/scanner.ErrorList":                          true,
	"image/color.Palette":                           true,
	"net.HardwareAddr":                              true,
	"net.IP":                                        true,
	"net.IPMask":                                    true,
	"sort.Float64Slice":                             true,
	"sort.IntSlice":                                 true,
	"sort.StringSlice":                              true,
	"unicode.SpecialCase":                           true,

	// These image and image/color struct types are frozen. We will never add fields to them.
	"image/color.Alpha16": true,
	"image/color.Alpha":   true,
	"image/color.Gray16":  true,
	"image/color.Gray":    true,
	"image/color.NRGBA64": true,
	"image/color.NRGBA":   true,
	"image/color.RGBA64":  true,
	"image/color.RGBA":    true,
	"image/color.YCbCr":   true,
	"image.Point":         true,
	"image.Rectangle":     true,
}
<commit_msg>go.tools/cmd/vet: add image.Uniform to untagged literal white list<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains the test for untagged struct literals.

package main

import (
	"flag"
	"go/ast"
	"strings"
)

var compositeWhiteList = flag.Bool("compositewhitelist", true, "use composite white list; for testing only")

// checkUntaggedLiteral checks if a composite literal is a struct literal with
// untagged fields.
func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) {
	if !vet("composites") {
		return
	}

	typ := c.Type
	for {
		if typ1, ok := c.Type.(*ast.ParenExpr); ok {
			typ = typ1
			continue
		}
		break
	}

	switch typ.(type) {
	case *ast.ArrayType:
		return
	case *ast.MapType:
		return
	case *ast.StructType:
		return // a literal struct type does not need to use tags
	case *ast.Ident:
		// A simple type name like t or T does not need tags either,
		// since it is almost certainly declared in the current package.
		// (The exception is names being used via import . "pkg", but
		// those are already breaking the Go 1 compatibility promise,
		// so not reporting potential additional breakage seems okay.)
		return
	}

	// Otherwise the type is a selector like pkg.Name.
	// We only care if pkg.Name is a struct, not if it's a map, array, or slice.
	isStruct, typeString := f.pkg.isStruct(c)
	if !isStruct {
		return
	}

	if typeString == "" { // isStruct doesn't know
		typeString = f.gofmt(typ)
	}

	// It's a struct, or we can't tell it's not a struct because we don't have types.

	// Check if the CompositeLit contains an untagged field.
	allKeyValue := true
	for _, e := range c.Elts {
		if _, ok := e.(*ast.KeyValueExpr); !ok {
			allKeyValue = false
			break
		}
	}
	if allKeyValue {
		return
	}

	// Check that the CompositeLit's type has the form pkg.Typ.
	s, ok := c.Type.(*ast.SelectorExpr)
	if !ok {
		return
	}
	pkg, ok := s.X.(*ast.Ident)
	if !ok {
		return
	}

	// Convert the package name to an import path, and compare to a whitelist.
	path := pkgPath(f, pkg.Name)
	if path == "" {
		f.Badf(c.Pos(), "unresolvable package for %s.%s literal", pkg.Name, s.Sel.Name)
		return
	}
	typeName := path + "." + s.Sel.Name
	if *compositeWhiteList && untaggedLiteralWhitelist[typeName] {
		return
	}

	f.Warn(c.Pos(), typeString+" composite literal uses untagged fields")
}

// pkgPath returns the import path "image/png" for the package name "png".
//
// This is based purely on syntax and convention, and not on the imported
// package's contents. It will be incorrect if a package name differs from the
// leaf element of the import path, or if the package was a dot import.
func pkgPath(f *File, pkgName string) (path string) {
	for _, x := range f.file.Imports {
		s := strings.Trim(x.Path.Value, `"`)
		if x.Name != nil {
			// Catch `import pkgName "foo/bar"`.
			if x.Name.Name == pkgName {
				return s
			}
		} else {
			// Catch `import "pkgName"` or `import "foo/bar/pkgName"`.
			if s == pkgName || strings.HasSuffix(s, "/"+pkgName) {
				return s
			}
		}
	}
	return ""
}

var untaggedLiteralWhitelist = map[string]bool{
	/*
		These types are actually slices. Syntactically, we cannot tell
		whether the Typ in pkg.Typ{1, 2, 3} is a slice or a struct, so we
		whitelist all the standard package library's exported slice types.

		find $GOROOT/src/pkg -type f | grep -v _test.go | xargs grep '^type.*\[\]' | \
			grep -v ' map\[' | sed 's,/[^/]*go.type,,' | sed 's,.*src/pkg/,,' | \
			sed 's, ,.,' |  sed 's, .*,,' | grep -v '\.[a-z]' | \
			sort | awk '{ print "\"" $0 "\": true," }'
	*/
	"crypto/x509/pkix.RDNSequence":                  true,
	"crypto/x509/pkix.RelativeDistinguishedNameSET": true,
	"database/sql.RawBytes":                         true,
	"debug/macho.LoadBytes":                         true,
	"encoding/asn1.ObjectIdentifier":                true,
	"encoding/asn1.RawContent":                      true,
	"encoding/json.RawMessage":                      true,
	"encoding/xml.CharData":                         true,
	"encoding/xml.Comment":                          true,
	"encoding/xml.Directive":                        true,
	"go/scanner.ErrorList":                          true,
	"image/color.Palette":                           true,
	"net.HardwareAddr":                              true,
	"net.IP":                                        true,
	"net.IPMask":                                    true,
	"sort.Float64Slice":                             true,
	"sort.IntSlice":                                 true,
	"sort.StringSlice":                              true,
	"unicode.SpecialCase":                           true,

	// These image and image/color struct types are frozen. We will never add fields to them.
	"image/color.Alpha16": true,
	"image/color.Alpha":   true,
	"image/color.Gray16":  true,
	"image/color.Gray":    true,
	"image/color.NRGBA64": true,
	"image/color.NRGBA":   true,
	"image/color.RGBA64":  true,
	"image/color.RGBA":    true,
	"image/color.YCbCr":   true,
	"image.Point":         true,
	"image.Rectangle":     true,
	"image.Uniform":       true,
}
<|endoftext|>


<commit_before>// Copyright 2016 <chaishushan{AT}gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"sync"
)

// 最大的缓存数目
const maxCachedSize = 16

// 查询缓冲
var cache struct {
	sync.Mutex
	keys    []string
	results map[string]string
}

func init() {
	cache.Lock()
	defer cache.Unlock()

	cache.keys = make([]string, 0, maxCachedSize)
	cache.results = make(map[string]string)
}

// 从缓存查询
func getFromCache(key string) (value string, ok bool) {
	cache.Lock()
	defer cache.Unlock()

	value, ok = cache.results[key]
	return
}

// 更新缓存
func setFromCache(key, value string) {
	cache.Lock()
	defer cache.Unlock()

	// 已经存在
	if _, ok := cache.results[key]; ok {
		// 将key移动到开头
		for idx, v := range cache.keys {
			if v == key {
				for i := idx; i > 0; i-- {
					cache.keys[i] = cache.keys[i-1]
				}
				cache.keys[0] = key
				break
			}
		}
		return
	}

	// 缓存已经满了, 需要清理一个空间
	if len(cache.keys) == cap(cache.keys) {
		delete(cache.results, cache.keys[len(cache.keys)-1])
		cache.keys = cache.keys[:len(cache.keys)-1]
	}

	// 添加新的数据
	cache.keys = append([]string{key}, cache.keys...)
	cache.results[key] = value
	return
}

// 清理缓存
func clearCache() {
	cache.Lock()
	defer cache.Unlock()

	cache.keys = make([]string, 0, maxCachedSize)
	cache.results = make(map[string]string)
}
<commit_msg>cmd/yjyy: 完善cache实现<commit_after>// Copyright 2016 <chaishushan{AT}gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"sync"
)

// 最大的缓存数目
const maxCachedSize = 16

// 查询缓冲
var cache struct {
	sync.Mutex
	keys    []string
	results map[string]string
}

func init() {
	cache.Lock()
	defer cache.Unlock()

	cache.keys = make([]string, 0, maxCachedSize)
	cache.results = make(map[string]string)
}

// 从缓存查询
func getFromCache(key string) (value string, ok bool) {
	cache.Lock()
	defer cache.Unlock()

	value, ok = cache.results[key]
	return
}

// 更新缓存
func setToCache(key, value string) {
	cache.Lock()
	defer cache.Unlock()

	// 已经存在
	if _, ok := cache.results[key]; ok {
		// 将key移动到开头
		for idx, v := range cache.keys {
			if v == key {
				for i := idx; i > 0; i-- {
					cache.keys[i] = cache.keys[i-1]
				}
				cache.keys[0] = key
				break
			}
		}
		cache.results[key] = value
		return
	}

	// 缓存已经满了, 需要清理一个空间
	if len(cache.keys) == cap(cache.keys) {
		delete(cache.results, cache.keys[len(cache.keys)-1])
		cache.keys = cache.keys[:len(cache.keys)-1]
	}

	// 添加新的数据
	cache.keys = append([]string{key}, cache.keys...)
	cache.results[key] = value
	return
}

// 清理缓存
func clearCache() {
	cache.Lock()
	defer cache.Unlock()

	cache.keys = cache.keys[:0]
	cache.results = make(map[string]string)
}
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    "menteslibres.net/gosexy/redis"
)

func main() {

    var client  *redis.Client
    var err error

    client = redis.New()

    err = client.Connect("127.0.0.1",6379)

    if err != nil {
        fmt.Println("Connect failed: %s\n")
        return
    }

    fmt.Println("Connected to redis-server.")

    fmt.Println("Welcome to my Coffee Counter. You can see how many times I've made coffee with the given brew type. Then you can increment one when you've made another cup")
  // Get list of Current coffee Items
    cl,err := client.LLen("coffees")// cl is a variable to store length of "coffees"
    // grab "coffees" list and store it in "Coffees" array
    Coffees := make([]string,int(cl))
    Coffees,err = client.LRange("coffees",0,-1)
    //print out each of the items
    var value string
    var n int64
    for n = 0; n < cl; n++ {
        value,err = client.Get(Coffees[n])
        option := string(int(n+1)) + ". " + Coffees[n] + " : " + value + " Cups"
        fmt.Println(option)
    }
    fmt.Println("Do you want to log a cup of coffee?","If so, input the number corresponding to the brewing method then hit enter, otherwise just hit enter")
    var input int
    var input_count int
    input_count,err = fmt.Scanln(&input)
    if input_count != 0 {
        client.Incr(Coffees[input])
    }

    client.Quit()

}

<commit_msg>added ability to choose and increment cup count Round 3<commit_after>package main

import (
    "fmt"
    "menteslibres.net/gosexy/redis"
)

func main() {

    var client  *redis.Client
    var err error

    client = redis.New()

    err = client.Connect("127.0.0.1",6379)

    if err != nil {
        fmt.Println("Connect failed: %s\n")
        return
    }

    fmt.Println("Connected to redis-server.")

    fmt.Println("Welcome to my Coffee Counter. You can see how many times I've made coffee with the given brew type. Then you can increment one when you've made another cup")
  // Get list of Current coffee Items
    cl,err := client.LLen("coffees")// cl is a variable to store length of "coffees"
    // grab "coffees" list and store it in "Coffees" array
    Coffees := make([]string,int(cl))
    Coffees,err = client.LRange("coffees",0,-1)
    //print out each of the items
    var value string
    var n int64
    for n = 0; n < cl; n++ {
        value,err = client.Get(Coffees[n])
        option := string(n+1) + ". " + Coffees[n] + " : " + value + " Cups"
        fmt.Println(option)
    }
    fmt.Println("Do you want to log a cup of coffee?","If so, input the number corresponding to the brewing method then hit enter, otherwise just hit enter")
    var input int
    var input_count int
    input_count,err = fmt.Scanln(&input)
    if input_count != 0 {
        client.Incr(Coffees[input])
    }

    client.Quit()

}

<|endoftext|>


<commit_before>// This file has handlers for zip-code reports.
package complaints

import (
	"fmt"
	"net/http"
	"sort"

	"appengine"

	"github.com/skypies/complaints/complaintdb"
	"github.com/skypies/date"
)

func init() {
	http.HandleFunc("/zip", zipFormHandler)
	http.HandleFunc("/zip/results", zipResultsHandler)
}

func zipFormHandler(w http.ResponseWriter, r *http.Request) {
	var params = map[string]interface{}{
		"Yesterday": date.NowInPdt().AddDate(0,0,-1),
	}
	if err := templates.ExecuteTemplate(w, "report-zip-form", params); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func zipResultsHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)
	cdb := complaintdb.ComplaintDB{C: ctx, Memcache:false}

	zip := r.FormValue("zip")
	s,e,_ := FormValueDateRange(r)

	var countsByHour [24]int
	countsByDate := map[string]int{}
	var uniquesByHour [24]map[string]int
	uniquesByDate := map[string]map[string]int{}
	uniquesAll := map[string]int{}

	// ??
	// for iter := cdb.NewIter(QueryInSpanInZip(s,e,zip)); !iter.EOF; c := iter.Next() {
	iter := cdb.NewIter(cdb.QueryInSpanInZip(s,e,zip))
	for {
		c := iter.Next();
		if c == nil { break }

		h := c.Timestamp.Hour()
		countsByHour[h]++
		if uniquesByHour[h] == nil { uniquesByHour[h] = map[string]int{} }
		uniquesByHour[h][c.Profile.EmailAddress]++

		d := c.Timestamp.Format("2006.01.02")
		countsByDate[d]++
		if uniquesByDate[d] == nil { uniquesByDate[d] = map[string]int{} }
		uniquesByDate[d][c.Profile.EmailAddress]++

		uniquesAll[c.Profile.EmailAddress]++
	}

	dateKeys := []string{}
	for k,_ := range countsByDate { dateKeys = append(dateKeys, k) }
	sort.Strings(dateKeys)

	data := [][]string{}
	for i,v := range countsByHour {
		data = append(data, []string{
			fmt.Sprintf("%d",i),
			fmt.Sprintf("%d",v),
			fmt.Sprintf("%d",len(uniquesByHour[i])),
		})
	}

	data = append(data, []string{"------"})
	for _,k := range dateKeys {
		data = append(data, []string{
			k,
			fmt.Sprintf("%d",countsByDate[k]),
			fmt.Sprintf("%d",len(uniquesByDate[k])),
		})
	}
	data = append(data, []string{"------"})
	data = append(data, []string{"All uniques", fmt.Sprintf("%d", len(uniquesAll))})

	var params = map[string]interface{}{ "Data": data }
	if err := templates.ExecuteTemplate(w, "report", params); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}
<commit_msg>Make the columns explicable<commit_after>// This file has handlers for zip-code reports.
package complaints

import (
	"fmt"
	"net/http"
	"sort"

	"appengine"

	"github.com/skypies/complaints/complaintdb"
	"github.com/skypies/date"
)

func init() {
	http.HandleFunc("/zip", zipFormHandler)
	http.HandleFunc("/zip/results", zipResultsHandler)
}

func zipFormHandler(w http.ResponseWriter, r *http.Request) {
	var params = map[string]interface{}{
		"Yesterday": date.NowInPdt().AddDate(0,0,-1),
	}
	if err := templates.ExecuteTemplate(w, "report-zip-form", params); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func zipResultsHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)
	cdb := complaintdb.ComplaintDB{C: ctx, Memcache:false}

	zip := r.FormValue("zip")
	s,e,_ := FormValueDateRange(r)

	var countsByHour [24]int
	countsByDate := map[string]int{}
	var uniquesByHour [24]map[string]int
	uniquesByDate := map[string]map[string]int{}
	uniquesAll := map[string]int{}

	// ??
	// for iter := cdb.NewIter(QueryInSpanInZip(s,e,zip)); !iter.EOF; c := iter.Next() {
	iter := cdb.NewIter(cdb.QueryInSpanInZip(s,e,zip))
	for {
		c := iter.Next();
		if c == nil { break }

		h := c.Timestamp.Hour()
		countsByHour[h]++
		if uniquesByHour[h] == nil { uniquesByHour[h] = map[string]int{} }
		uniquesByHour[h][c.Profile.EmailAddress]++

		d := c.Timestamp.Format("2006.01.02")
		countsByDate[d]++
		if uniquesByDate[d] == nil { uniquesByDate[d] = map[string]int{} }
		uniquesByDate[d][c.Profile.EmailAddress]++

		uniquesAll[c.Profile.EmailAddress]++
	}

	dateKeys := []string{}
	for k,_ := range countsByDate { dateKeys = append(dateKeys, k) }
	sort.Strings(dateKeys)

	data := [][]string{}

	data = append(data, []string{"Date", "NumComplaints", "UniqueComplainers"})
	for _,k := range dateKeys {
		data = append(data, []string{
			k,
			fmt.Sprintf("%d",countsByDate[k]),
			fmt.Sprintf("%d",len(uniquesByDate[k])),
		})
	}
	data = append(data, []string{"------"})

	data = append(data, []string{"HourAcrossAllDays", "NumComplaints", "UniqueComplainers"})
	for i,v := range countsByHour {
		data = append(data, []string{
			fmt.Sprintf("%02d:00",i),
			fmt.Sprintf("%d",v),
			fmt.Sprintf("%d",len(uniquesByHour[i])),
		})
	}
	data = append(data, []string{"------"})
	data = append(data, []string{"UniqueComplainersAcrossAllDays", fmt.Sprintf("%d", len(uniquesAll))})

	var params = map[string]interface{}{ "Data": data }
	if err := templates.ExecuteTemplate(w, "report", params); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}
<|endoftext|>


<commit_before>package watchers

import (
	"fmt"
	"math/big"
	"sync"

	ethcommon "github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/event"
	"github.com/livepeer/go-livepeer/eth/contracts"

	"github.com/golang/glog"
	"github.com/livepeer/go-livepeer/eth"
	"github.com/livepeer/go-livepeer/eth/blockwatch"
)

// TimeWatcher is a type for a thread safe in-memory cache that watches for the following on-chain events:
//	* New rounds
//	* New blocks
//	* Transcoder (de)activation

// TimeWatcher allows for subscriptions to certain data feeds using a caller provided sink channel
// consumers of the TimeWatcher can subscribe to following data feeds:
// 	* Last Initialized Round Number
//	* Last Seen Block Number
type TimeWatcher struct {
	// state
	mu                       sync.RWMutex
	lastInitializedRound     *big.Int
	lastInitializedBlockHash [32]byte
	transcoderPoolSize       *big.Int
	lastSeenBlock            *big.Int

	// last initialized round number subscription feeds
	roundSubFeed  event.Feed
	roundSubScope event.SubscriptionScope
	// last seen block number subscription feeds
	blockSubFeed  event.Feed
	blockSubScope event.SubscriptionScope

	watcher BlockWatcher
	lpEth   eth.LivepeerEthClient
	dec     *EventDecoder

	quit chan struct{}
}

// NewTimeWatcher creates a new instance of TimeWatcher and sets the initial cache through an RPC call to an ethereum node
func NewTimeWatcher(roundsManagerAddr ethcommon.Address, watcher BlockWatcher, lpEth eth.LivepeerEthClient) (*TimeWatcher, error) {
	dec, err := NewEventDecoder(roundsManagerAddr, contracts.RoundsManagerABI)
	if err != nil {
		return nil, fmt.Errorf("error creating decoder: %v", err)
	}

	return &TimeWatcher{
		quit:    make(chan struct{}),
		watcher: watcher,
		lpEth:   lpEth,
		dec:     dec,
	}, nil
}

// LastInitializedRound gets the last initialized round from cache
func (tw *TimeWatcher) LastInitializedRound() *big.Int {
	tw.mu.RLock()
	defer tw.mu.RUnlock()
	return tw.lastInitializedRound
}

// LastInitializedBlockHash returns the blockhash of the block the last round was initiated in
func (tw *TimeWatcher) LastInitializedBlockHash() [32]byte {
	tw.mu.RLock()
	defer tw.mu.RUnlock()
	return tw.lastInitializedBlockHash
}

func (tw *TimeWatcher) setLastInitializedRound(round *big.Int, hash [32]byte) {
	tw.mu.Lock()
	defer tw.mu.Unlock()
	tw.lastInitializedRound = round
	tw.lastInitializedBlockHash = hash
}

func (tw *TimeWatcher) GetTranscoderPoolSize() *big.Int {
	tw.mu.RLock()
	defer tw.mu.RUnlock()
	return tw.transcoderPoolSize
}

func (tw *TimeWatcher) setTranscoderPoolSize(size *big.Int) {
	tw.mu.Lock()
	defer tw.mu.Unlock()
	tw.transcoderPoolSize = size
}

func (tw *TimeWatcher) LastSeenBlock() *big.Int {
	tw.mu.RLock()
	defer tw.mu.RUnlock()
	return tw.lastSeenBlock
}

func (tw *TimeWatcher) setLastSeenBlock(blockNum *big.Int) {
	tw.mu.Lock()
	defer tw.mu.Unlock()
	tw.lastSeenBlock = blockNum
}

// Watch the blockwatch subscription for NewRound events
func (tw *TimeWatcher) Watch() error {
	lr, err := tw.lpEth.LastInitializedRound()
	if err != nil {
		return fmt.Errorf("error fetching initial lastInitializedRound value: %v", err)
	}
	bh, err := tw.lpEth.BlockHashForRound(lr)
	if err != nil {
		return fmt.Errorf("error fetching initial lastInitializedBlockHash value: %v", err)
	}
	tw.setLastInitializedRound(lr, bh)

	if err := tw.fetchAndSetTranscoderPoolSize(); err != nil {
		return fmt.Errorf("error fetching initial transcoderPoolSize: %v", err)
	}

	events := make(chan []*blockwatch.Event, 10)
	sub := tw.watcher.Subscribe(events)
	defer sub.Unsubscribe()
	for {
		select {
		case <-tw.quit:
			return nil
		case err := <-sub.Err():
			glog.Error(err)
		case events := <-events:
			tw.handleBlockEvents(events)
		}
	}
}

// SubscribeRounds allows one to subscribe to new round events
// To unsubscribe, simply call `Unsubscribe` on the returned subscription.
// The sink channel should have ample buffer space to avoid blocking other subscribers.
// Slow subscribers are not dropped.
func (tw *TimeWatcher) SubscribeRounds(sink chan<- types.Log) event.Subscription {
	return tw.roundSubScope.Track(tw.roundSubFeed.Subscribe(sink))
}

// SubscribeBlocks allows one to subscribe to newly seen block numbers
// To unsubscribe, simply call `Unsubscribe` on the returned subscription.
// The sink channel should have ample buffer space to avoid blocking other subscribers.
// Slow subscribers are not dropped.
func (tw *TimeWatcher) SubscribeBlocks(sink chan<- *big.Int) event.Subscription {
	return tw.blockSubScope.Track(tw.blockSubFeed.Subscribe(sink))
}

// Stop TimeWatcher
func (tw *TimeWatcher) Stop() {
	close(tw.quit)
	tw.blockSubScope.Close()
	tw.roundSubScope.Close()
}

func (tw *TimeWatcher) handleBlockEvents(events []*blockwatch.Event) {
	for _, event := range events {
		tw.handleBlockNum(event)
		for _, log := range event.BlockHeader.Logs {
			if event.Type == blockwatch.Removed {
				log.Removed = true
			}
			if err := tw.handleLog(log); err != nil {
				glog.Error(err)
			}
		}
	}
}

func (tw *TimeWatcher) handleBlockNum(event *blockwatch.Event) {
	last := tw.LastSeenBlock()
	new := event.BlockHeader.Number
	if last == nil || last.Cmp(new) != 0 {
		tw.setLastSeenBlock(new)
		tw.blockSubFeed.Send(new)
	}
}

func (tw *TimeWatcher) handleLog(log types.Log) error {
	eventName, err := tw.dec.FindEventName(log)
	if err != nil {
		// Noop if we cannot find the event name
		return nil
	}

	if eventName != "NewRound" {
		return fmt.Errorf("eventName is not NewRound")
	}

	var nr contracts.RoundsManagerNewRound
	if err := tw.dec.Decode("NewRound", log, &nr); err != nil {
		return fmt.Errorf("unable to decode event: %v", err)
	}

	tw.roundSubFeed.Send(log)

	if log.Removed {
		lr, err := tw.lpEth.LastInitializedRound()
		if err != nil {
			return err
		}
		bh, err := tw.lpEth.BlockHashForRound(lr)
		if err != nil {
			return err
		}
		tw.setLastInitializedRound(lr, bh)
	} else {
		tw.setLastInitializedRound(nr.Round, nr.BlockHash)
	}

	// Get the active transcoder pool size when we receive a NewRound event
	if err := tw.fetchAndSetTranscoderPoolSize(); err != nil {
		return err
	}

	return nil
}

func (tw *TimeWatcher) fetchAndSetTranscoderPoolSize() error {
	size, err := tw.lpEth.GetTranscoderPoolSize()
	if err != nil {
		return fmt.Errorf("error fetching initial transcoderPoolSize: %v", err)
	}
	tw.setTranscoderPoolSize(size)
	return nil
}
<commit_msg>eth/watcher: cache last seen block when starting timeWatcher Watch() loop<commit_after>package watchers

import (
	"fmt"
	"math/big"
	"sync"

	ethcommon "github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/event"
	"github.com/livepeer/go-livepeer/eth/contracts"

	"github.com/golang/glog"
	"github.com/livepeer/go-livepeer/eth"
	"github.com/livepeer/go-livepeer/eth/blockwatch"
)

// TimeWatcher is a type for a thread safe in-memory cache that watches for the following on-chain events:
//	* New rounds
//	* New blocks
//	* Transcoder (de)activation

// TimeWatcher allows for subscriptions to certain data feeds using a caller provided sink channel
// consumers of the TimeWatcher can subscribe to following data feeds:
// 	* Last Initialized Round Number
//	* Last Seen Block Number
type TimeWatcher struct {
	// state
	mu                       sync.RWMutex
	lastInitializedRound     *big.Int
	lastInitializedBlockHash [32]byte
	transcoderPoolSize       *big.Int
	lastSeenBlock            *big.Int

	// last initialized round number subscription feeds
	roundSubFeed  event.Feed
	roundSubScope event.SubscriptionScope
	// last seen block number subscription feeds
	blockSubFeed  event.Feed
	blockSubScope event.SubscriptionScope

	watcher BlockWatcher
	lpEth   eth.LivepeerEthClient
	dec     *EventDecoder

	quit chan struct{}
}

// NewTimeWatcher creates a new instance of TimeWatcher and sets the initial cache through an RPC call to an ethereum node
func NewTimeWatcher(roundsManagerAddr ethcommon.Address, watcher BlockWatcher, lpEth eth.LivepeerEthClient) (*TimeWatcher, error) {
	dec, err := NewEventDecoder(roundsManagerAddr, contracts.RoundsManagerABI)
	if err != nil {
		return nil, fmt.Errorf("error creating decoder: %v", err)
	}

	return &TimeWatcher{
		quit:    make(chan struct{}),
		watcher: watcher,
		lpEth:   lpEth,
		dec:     dec,
	}, nil
}

// LastInitializedRound gets the last initialized round from cache
func (tw *TimeWatcher) LastInitializedRound() *big.Int {
	tw.mu.RLock()
	defer tw.mu.RUnlock()
	return tw.lastInitializedRound
}

// LastInitializedBlockHash returns the blockhash of the block the last round was initiated in
func (tw *TimeWatcher) LastInitializedBlockHash() [32]byte {
	tw.mu.RLock()
	defer tw.mu.RUnlock()
	return tw.lastInitializedBlockHash
}

func (tw *TimeWatcher) setLastInitializedRound(round *big.Int, hash [32]byte) {
	tw.mu.Lock()
	defer tw.mu.Unlock()
	tw.lastInitializedRound = round
	tw.lastInitializedBlockHash = hash
}

func (tw *TimeWatcher) GetTranscoderPoolSize() *big.Int {
	tw.mu.RLock()
	defer tw.mu.RUnlock()
	return tw.transcoderPoolSize
}

func (tw *TimeWatcher) setTranscoderPoolSize(size *big.Int) {
	tw.mu.Lock()
	defer tw.mu.Unlock()
	tw.transcoderPoolSize = size
}

func (tw *TimeWatcher) LastSeenBlock() *big.Int {
	tw.mu.RLock()
	defer tw.mu.RUnlock()
	return tw.lastSeenBlock
}

func (tw *TimeWatcher) setLastSeenBlock(blockNum *big.Int) {
	tw.mu.Lock()
	defer tw.mu.Unlock()
	tw.lastSeenBlock = blockNum
}

// Watch the blockwatch subscription for NewRound events
func (tw *TimeWatcher) Watch() error {
	lr, err := tw.lpEth.LastInitializedRound()
	if err != nil {
		return fmt.Errorf("error fetching initial lastInitializedRound value err=%v", err)
	}
	bh, err := tw.lpEth.BlockHashForRound(lr)
	if err != nil {
		return fmt.Errorf("error fetching initial lastInitializedBlockHash value err=%v", err)
	}
	tw.setLastInitializedRound(lr, bh)

	if err := tw.fetchAndSetTranscoderPoolSize(); err != nil {
		return fmt.Errorf("error fetching initial transcoderPoolSize err=%v", err)
	}

	events := make(chan []*blockwatch.Event, 10)
	sub := tw.watcher.Subscribe(events)
	defer sub.Unsubscribe()
	for {
		select {
		case <-tw.quit:
			return nil
		case err := <-sub.Err():
			glog.Error(err)
		case events := <-events:
			tw.handleBlockEvents(events)
		}
	}
}

// SubscribeRounds allows one to subscribe to new round events
// To unsubscribe, simply call `Unsubscribe` on the returned subscription.
// The sink channel should have ample buffer space to avoid blocking other subscribers.
// Slow subscribers are not dropped.
func (tw *TimeWatcher) SubscribeRounds(sink chan<- types.Log) event.Subscription {
	return tw.roundSubScope.Track(tw.roundSubFeed.Subscribe(sink))
}

// SubscribeBlocks allows one to subscribe to newly seen block numbers
// To unsubscribe, simply call `Unsubscribe` on the returned subscription.
// The sink channel should have ample buffer space to avoid blocking other subscribers.
// Slow subscribers are not dropped.
func (tw *TimeWatcher) SubscribeBlocks(sink chan<- *big.Int) event.Subscription {
	return tw.blockSubScope.Track(tw.blockSubFeed.Subscribe(sink))
}

// Stop TimeWatcher
func (tw *TimeWatcher) Stop() {
	close(tw.quit)
	tw.blockSubScope.Close()
	tw.roundSubScope.Close()
}

func (tw *TimeWatcher) handleBlockEvents(events []*blockwatch.Event) {
	for _, event := range events {
		tw.handleBlockNum(event)
		for _, log := range event.BlockHeader.Logs {
			if event.Type == blockwatch.Removed {
				log.Removed = true
			}
			if err := tw.handleLog(log); err != nil {
				glog.Error(err)
			}
		}
	}
}

func (tw *TimeWatcher) handleBlockNum(event *blockwatch.Event) {
	last := tw.LastSeenBlock()
	new := event.BlockHeader.Number
	if last == nil || last.Cmp(new) != 0 {
		tw.setLastSeenBlock(new)
		tw.blockSubFeed.Send(new)
	}
}

func (tw *TimeWatcher) handleLog(log types.Log) error {
	eventName, err := tw.dec.FindEventName(log)
	if err != nil {
		// Noop if we cannot find the event name
		return nil
	}

	if eventName != "NewRound" {
		return fmt.Errorf("eventName is not NewRound")
	}

	var nr contracts.RoundsManagerNewRound
	if err := tw.dec.Decode("NewRound", log, &nr); err != nil {
		return fmt.Errorf("unable to decode event: %v", err)
	}

	tw.roundSubFeed.Send(log)

	if log.Removed {
		lr, err := tw.lpEth.LastInitializedRound()
		if err != nil {
			return err
		}
		bh, err := tw.lpEth.BlockHashForRound(lr)
		if err != nil {
			return err
		}
		tw.setLastInitializedRound(lr, bh)
	} else {
		tw.setLastInitializedRound(nr.Round, nr.BlockHash)
	}

	// Get the active transcoder pool size when we receive a NewRound event
	if err := tw.fetchAndSetTranscoderPoolSize(); err != nil {
		return err
	}

	return nil
}

func (tw *TimeWatcher) fetchAndSetTranscoderPoolSize() error {
	size, err := tw.lpEth.GetTranscoderPoolSize()
	if err != nil {
		return fmt.Errorf("error fetching initial transcoderPoolSize: %v", err)
	}
	tw.setTranscoderPoolSize(size)
	return nil
}
<|endoftext|>


<commit_before>package collision2d_test

import (
	"github.com/Tarliton/collision2d"
	"github.com/stretchr/testify/assert"
	"math"
	"testing"
)

func TestPointInCircle(t *testing.T) {
	point := collision2d.NewVector(11, 11)
	circle := collision2d.NewCircle(collision2d.NewVector(10, 10), 5)
	result := collision2d.PointInCircle(point, circle)
	assert.Equal(t, true, result, "they should be equal")
}

func TestPointNotInCircle(t *testing.T) {
	point := collision2d.NewVector(155, 11)
	circle := collision2d.NewCircle(collision2d.NewVector(10, 10), 5)
	result := collision2d.PointInCircle(point, circle)
	assert.Equal(t, false, result, "they should be equal")
}

func TestPointInPolygon(t *testing.T) {
	point := collision2d.NewVector(35, 5)
	polygonCorners := []float64{
		0, 0,
		30, 0,
		0, 30,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(30, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	result := collision2d.PointInPolygon(point, polygon)
	assert.Equal(t, true, result, "they should be equal")
}

func TestPointNotInPolygon(t *testing.T) {
	point := collision2d.NewVector(0, 0)
	polygonCorners := []float64{
		0, 0,
		30, 0,
		0, 30,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(30, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	result := collision2d.PointInPolygon(point, polygon)
	assert.Equal(t, false, result, "they should be equal")
}

func TestTestCircleCircle(t *testing.T) {
	circle1 := collision2d.NewCircle(collision2d.NewVector(0, 0), 20)
	circle2 := collision2d.NewCircle(collision2d.NewVector(30, 0), 20)
	result, response := collision2d.TestCircleCircle(circle1, circle2)
	assert.Equal(t, true, result, "they should be equal")
	assert.Equal(t, float64(10), response.Overlap, "they should be equal")
	assert.Equal(t, true, response.OverlapV.X == float64(10) && response.OverlapV.Y == float64(0), "they should be equal")
}

func TestTestNotCircleCircle(t *testing.T) {
	circle1 := collision2d.NewCircle(collision2d.NewVector(0, 0), 20)
	circle2 := collision2d.NewCircle(collision2d.NewVector(30, 50), 20)
	result, response := collision2d.TestCircleCircle(circle1, circle2)
	assert.Equal(t, false, result, "they should be equal")
	assert.Equal(t, -math.MaxFloat64, response.Overlap, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.X, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.Y, "they should be equal")
}

func TestTestPolygonCircle(t *testing.T) {
	polygonCorners := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	circle := collision2d.NewCircle(collision2d.NewVector(50, 50), 20)
	result, response := collision2d.TestPolygonCircle(polygon, circle)
	assert.Equal(t, true, result, "they should be equal")
	assert.Equal(t, float64(5.857864376269049), response.Overlap, "they should be equal")
	assert.Equal(t, float64(4.14213562373095), response.OverlapV.X, "they should be equal")
	assert.Equal(t, float64(4.14213562373095), response.OverlapV.Y, "they should be equal")
}

func TestTestNotPolygonCircle(t *testing.T) {
	polygonCorners := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	circle := collision2d.NewCircle(collision2d.NewVector(200, 200), 1)
	result, response := collision2d.TestPolygonCircle(polygon, circle)
	assert.Equal(t, false, result, "they should be equal")
	assert.Equal(t, -math.MaxFloat64, response.Overlap, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.X, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.Y, "they should be equal")
}

func TestTestCirclePolygon(t *testing.T) {
	polygonCorners := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	circle := collision2d.NewCircle(collision2d.NewVector(50, 50), 20)
	result, response := collision2d.TestCirclePolygon(circle, polygon)
	assert.Equal(t, true, result, "they should be equal")
	assert.Equal(t, float64(5.857864376269049), response.Overlap, "they should be equal")
	assert.Equal(t, float64(-4.14213562373095), response.OverlapV.X, "they should be equal")
	assert.Equal(t, float64(-4.14213562373095), response.OverlapV.Y, "they should be equal")
}

func TestTestPolygonPolygon(t *testing.T) {
	polygonCorners := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	result, response := collision2d.TestPolygonPolygon(polygon, polygon)
	assert.Equal(t, true, result, "they should be equal")
	assert.Equal(t, float64(40), response.Overlap, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.X, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.Y, "they should be equal")
}
<commit_msg>add benchmark in collisions<commit_after>package collision2d_test

import (
	"github.com/Tarliton/collision2d"
	"github.com/stretchr/testify/assert"
	"math"
	"testing"
)

func TestPointInCircle(t *testing.T) {
	point := collision2d.NewVector(11, 11)
	circle := collision2d.NewCircle(collision2d.NewVector(10, 10), 5)
	result := collision2d.PointInCircle(point, circle)
	assert.Equal(t, true, result, "they should be equal")
}

func TestPointNotInCircle(t *testing.T) {
	point := collision2d.NewVector(155, 11)
	circle := collision2d.NewCircle(collision2d.NewVector(10, 10), 5)
	result := collision2d.PointInCircle(point, circle)
	assert.Equal(t, false, result, "they should be equal")
}

func TestPointInPolygon(t *testing.T) {
	point := collision2d.NewVector(35, 5)
	polygonCorners := []float64{
		0, 0,
		30, 0,
		0, 30,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(30, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	result := collision2d.PointInPolygon(point, polygon)
	assert.Equal(t, true, result, "they should be equal")
}

func TestPointNotInPolygon(t *testing.T) {
	point := collision2d.NewVector(0, 0)
	polygonCorners := []float64{
		0, 0,
		30, 0,
		0, 30,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(30, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	result := collision2d.PointInPolygon(point, polygon)
	assert.Equal(t, false, result, "they should be equal")
}

func TestTestCircleCircle(t *testing.T) {
	circle1 := collision2d.NewCircle(collision2d.NewVector(0, 0), 20)
	circle2 := collision2d.NewCircle(collision2d.NewVector(30, 0), 20)
	result, response := collision2d.TestCircleCircle(circle1, circle2)
	assert.Equal(t, true, result, "they should be equal")
	assert.Equal(t, float64(10), response.Overlap, "they should be equal")
	assert.Equal(t, true, response.OverlapV.X == float64(10) && response.OverlapV.Y == float64(0), "they should be equal")
}

func TestTestNotCircleCircle(t *testing.T) {
	circle1 := collision2d.NewCircle(collision2d.NewVector(0, 0), 20)
	circle2 := collision2d.NewCircle(collision2d.NewVector(30, 50), 20)
	result, response := collision2d.TestCircleCircle(circle1, circle2)
	assert.Equal(t, false, result, "they should be equal")
	assert.Equal(t, -math.MaxFloat64, response.Overlap, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.X, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.Y, "they should be equal")
}

func TestTestPolygonCircle(t *testing.T) {
	polygonCorners := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	circle := collision2d.NewCircle(collision2d.NewVector(50, 50), 20)
	result, response := collision2d.TestPolygonCircle(polygon, circle)
	assert.Equal(t, true, result, "they should be equal")
	assert.Equal(t, float64(5.857864376269049), response.Overlap, "they should be equal")
	assert.Equal(t, float64(4.14213562373095), response.OverlapV.X, "they should be equal")
	assert.Equal(t, float64(4.14213562373095), response.OverlapV.Y, "they should be equal")
}

func TestTestNotPolygonCircle(t *testing.T) {
	polygonCorners := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	circle := collision2d.NewCircle(collision2d.NewVector(200, 200), 1)
	result, response := collision2d.TestPolygonCircle(polygon, circle)
	assert.Equal(t, false, result, "they should be equal")
	assert.Equal(t, -math.MaxFloat64, response.Overlap, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.X, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.Y, "they should be equal")
}

func TestTestCirclePolygon(t *testing.T) {
	polygonCorners := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	circle := collision2d.NewCircle(collision2d.NewVector(50, 50), 20)
	result, response := collision2d.TestCirclePolygon(circle, polygon)
	assert.Equal(t, true, result, "they should be equal")
	assert.Equal(t, float64(5.857864376269049), response.Overlap, "they should be equal")
	assert.Equal(t, float64(-4.14213562373095), response.OverlapV.X, "they should be equal")
	assert.Equal(t, float64(-4.14213562373095), response.OverlapV.Y, "they should be equal")
}

func TestTestPolygonPolygon(t *testing.T) {
	polygonCorners := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	result, response := collision2d.TestPolygonPolygon(polygon, polygon)
	assert.Equal(t, true, result, "they should be equal")
	assert.Equal(t, float64(40), response.Overlap, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.X, "they should be equal")
	assert.Equal(t, float64(0), response.OverlapV.Y, "they should be equal")
}

var response collision2d.Response

func BenchmarkPointInCircle(b *testing.B) {
	circle := collision2d.NewCircle(collision2d.NewVector(0, 0), 20)
	point := collision2d.NewVector(1, 2)
	for i := 0; i < b.N; i++ {
		collision2d.PointInCircle(point, circle)
	}
}

func BenchmarkPointInPolygon(b *testing.B) {
	polygonCorners := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	point := collision2d.NewVector(1, 2)
	for i := 0; i < b.N; i++ {
		collision2d.PointInPolygon(point, polygon)
	}
}

func BenchmarkTestCircleCircle(b *testing.B) {
	circle1 := collision2d.NewCircle(collision2d.NewVector(0, 0), 20)
	circle2 := collision2d.NewCircle(collision2d.NewVector(30, 0), 20)
	for i := 0; i < b.N; i++ {
		_, response = collision2d.TestCircleCircle(circle1, circle2)
	}
}

func BenchmarkTestPolygonCircle(b *testing.B) {
	circle := collision2d.NewCircle(collision2d.NewVector(0, 0), 20)
	polygonCorners := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	for i := 0; i < b.N; i++ {
		_, response = collision2d.TestPolygonCircle(polygon, circle)
	}
}

func BenchmarkTestCirclePolygon(b *testing.B) {
	circle := collision2d.NewCircle(collision2d.NewVector(0, 0), 20)
	polygonCorners := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners)
	for i := 0; i < b.N; i++ {
		_, response = collision2d.TestCirclePolygon(circle, polygon)
	}
}

func BenchmarkTestPolygonPolygon(b *testing.B) {
	polygonCorners1 := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon1 := collision2d.NewPolygon(collision2d.NewVector(0, 0), collision2d.NewVector(0, 0), 0, polygonCorners1)
	polygonCorners2 := []float64{
		0, 0,
		40, 0,
		40, 40,
		0, 40,
	}
	polygon2 := collision2d.NewPolygon(collision2d.NewVector(15, 25), collision2d.NewVector(0, 0), 0, polygonCorners2)
	for i := 0; i < b.N; i++ {
		_, response = collision2d.TestPolygonPolygon(polygon1, polygon2)
	}
}
<|endoftext|>


<commit_before>package colorable

import (
	"bytes"
	"os"
	"runtime"
	"testing"
)

// checkEncoding checks that colorable is output encoding agnostic as long as
// the encoding is a superset of ASCII. This implies that one byte not part of
// an ANSI sequence must give exactly one byte in output
func checkEncoding(t *testing.T, data []byte) {
	// Send non-UTF8 data to colorable
	b := bytes.NewBuffer(make([]byte, 0, 10))
	if b.Len() != 0 {
		t.FailNow()
	}
	// TODO move colorable wrapping outside the test
	c := NewNonColorable(b)
	c.Write(data)
	if b.Len() != len(data) {
		t.Fatalf("%d bytes expected, got %d", len(data), b.Len())
	}
}

func TestEncoding(t *testing.T) {
	checkEncoding(t, []byte{})      // Empty
	checkEncoding(t, []byte(`abc`)) // "abc"
	checkEncoding(t, []byte(`é`))   // "é" in UTF-8
	checkEncoding(t, []byte{233})   // 'é' in Latin-1
}

func TestColorable(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skipf("skip this test on windows")
	}
	_, ok := NewColorableStdout().(*os.File)
	if !ok {
		t.Fatalf("should os.Stdout on UNIX")
	}
	_, ok = NewColorableStderr().(*os.File)
	if !ok {
		t.Fatalf("should os.Stdout on UNIX")
	}
	_, ok = NewColorable(os.Stdout).(*os.File)
	if !ok {
		t.Fatalf("should os.Stdout on UNIX")
	}
}
<commit_msg>add test<commit_after>package colorable

import (
	"bytes"
	"os"
	"runtime"
	"testing"
)

// checkEncoding checks that colorable is output encoding agnostic as long as
// the encoding is a superset of ASCII. This implies that one byte not part of
// an ANSI sequence must give exactly one byte in output
func checkEncoding(t *testing.T, data []byte) {
	// Send non-UTF8 data to colorable
	b := bytes.NewBuffer(make([]byte, 0, 10))
	if b.Len() != 0 {
		t.FailNow()
	}
	// TODO move colorable wrapping outside the test
	c := NewNonColorable(b)
	c.Write(data)
	if b.Len() != len(data) {
		t.Fatalf("%d bytes expected, got %d", len(data), b.Len())
	}
}

func TestEncoding(t *testing.T) {
	checkEncoding(t, []byte{})      // Empty
	checkEncoding(t, []byte(`abc`)) // "abc"
	checkEncoding(t, []byte(`é`))   // "é" in UTF-8
	checkEncoding(t, []byte{233})   // 'é' in Latin-1
}

func TestNonColorable(t *testing.T) {
	var buf bytes.Buffer
	want := "hello"
	NewNonColorable(&buf).Write([]byte("\x1b[0m" + want + "\x1b[2J"))
	got := buf.String()
	if got != "hello" {
		t.Fatalf("want %q but %q", "hello", got)
	}
}

func TestColorable(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skipf("skip this test on windows")
	}
	_, ok := NewColorableStdout().(*os.File)
	if !ok {
		t.Fatalf("should os.Stdout on UNIX")
	}
	_, ok = NewColorableStderr().(*os.File)
	if !ok {
		t.Fatalf("should os.Stdout on UNIX")
	}
	_, ok = NewColorable(os.Stdout).(*os.File)
	if !ok {
		t.Fatalf("should os.Stdout on UNIX")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	hr "github.com/andviro/noodle/adapt/httprouter"
	"github.com/julienschmidt/httprouter"
	"golang.org/x/net/context"
	"net/http"
)

func index(c context.Context, w http.ResponseWriter, r *http.Request) error {
	fmt.Fprintln(w, "index")
	return nil
}

func products(c context.Context, w http.ResponseWriter, r *http.Request) error {
	params := hr.GetParams(c)
	fmt.Fprintf(w, "products: %s", params.ByName("id"))
	return nil
}

func main() {
	r := httprouter.New()
	n := hr.Default()
	r.GET("/", n.Then(index))
	r.GET("/products/:id", n.Then(products))
	http.ListenAndServe(":8080", r)
}
<commit_msg>removed httprouter adaptor in favor of wok<commit_after><|endoftext|>


<commit_before>package cli

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"

	"gopkg.in/yaml.v2"

	log "github.com/Sirupsen/logrus"
	models "github.com/bitrise-io/bitrise-cli/models/models_1_0_0"
	"github.com/bitrise-io/go-pathutil/pathutil"
	"github.com/bitrise-io/goinp/goinp"
	"github.com/codegangsta/cli"
)

func doInit(c *cli.Context) {
	log.Info("[BITRISE_CLI] - Init -- Work-in-progress!")
	bitriseConfigFileRelPath := "./bitrise.yml"

	if exists, err := pathutil.IsPathExists(bitriseConfigFileRelPath); err != nil {
		log.Fatalln("Error:", err)
	} else if exists {
		ask := fmt.Sprintf("A config file already exists at %s - do you want to overwrite it?", bitriseConfigFileRelPath)
		if val, err := goinp.AskForBool(ask); err != nil {
			log.Fatalln("Error:", err)
		} else if val == false {
			log.Infoln("Init canceled, existing file won't be overwritten.")
			os.Exit(0)
		}
	}

	projectSettingsEnvs := []models.EnvironmentItemModel{}
	if val, err := goinp.AskForString("What's the BITRISE_PROJECT_TITLE?"); err != nil {
		log.Fatalln(err)
	} else {
		projectSettingsEnvs = append(projectSettingsEnvs,
			models.EnvironmentItemModel{"BITRISE_PROJECT_TITLE": val, "is_expand": "no"})
	}
	if val, err := goinp.AskForString("What's your primary development branch's name?"); err != nil {
		log.Fatalln(err)
	} else {
		projectSettingsEnvs = append(projectSettingsEnvs,
			models.EnvironmentItemModel{"BITRISE_DEV_BRANCH": val, "is_expand": "no"})
	}

	bitriseConf := models.BitriseConfigModel{
		FormatVersion: "1.0.0", // TODO: move this into a project config file!
		App: models.AppModel{
			Environments: projectSettingsEnvs,
		},
		Workflows: map[string]models.WorkflowModel{
			"primary": models.WorkflowModel{},
		},
	}

	if err := SaveToFile(bitriseConfigFileRelPath, bitriseConf); err != nil {
		log.Fatalln("Failed to init:", err)
	}
	os.Exit(1)
}

// SaveToFile ...
func SaveToFile(pth string, bitriseConf models.BitriseConfigModel) error {
	if pth == "" {
		return errors.New("No path provided")
	}

	file, err := os.Create(pth)
	if err != nil {
		return err
	}
	defer func() {
		if err := file.Close(); err != nil {
			log.Fatalln("[BITRISE] - Failed to close file:", err)
		}
	}()

	contBytes, err := generateYAML(bitriseConf)
	if err != nil {
		return err
	}

	if _, err := file.Write(contBytes); err != nil {
		return err
	}
	log.Println()
	log.Infoln("=> Init success!")
	log.Infoln("File created at path:", pth)
	log.Infoln("With the content:")
	log.Infoln(string(contBytes))

	return nil
}

func generateYAML(v interface{}) ([]byte, error) {
	bytes, err := yaml.Marshal(v)
	if err != nil {
		return []byte{}, err
	}
	return bytes, nil
}

func generateNonFormattedJSON(v interface{}) ([]byte, error) {
	jsonContBytes, err := json.Marshal(v)
	if err != nil {
		return []byte{}, err
	}
	return jsonContBytes, nil
}
<commit_msg>removed now unused JSON generator code<commit_after>package cli

import (
	"errors"
	"fmt"
	"os"

	"gopkg.in/yaml.v2"

	log "github.com/Sirupsen/logrus"
	models "github.com/bitrise-io/bitrise-cli/models/models_1_0_0"
	"github.com/bitrise-io/go-pathutil/pathutil"
	"github.com/bitrise-io/goinp/goinp"
	"github.com/codegangsta/cli"
)

func doInit(c *cli.Context) {
	log.Info("[BITRISE_CLI] - Init -- Work-in-progress!")
	bitriseConfigFileRelPath := "./bitrise.yml"

	if exists, err := pathutil.IsPathExists(bitriseConfigFileRelPath); err != nil {
		log.Fatalln("Error:", err)
	} else if exists {
		ask := fmt.Sprintf("A config file already exists at %s - do you want to overwrite it?", bitriseConfigFileRelPath)
		if val, err := goinp.AskForBool(ask); err != nil {
			log.Fatalln("Error:", err)
		} else if val == false {
			log.Infoln("Init canceled, existing file won't be overwritten.")
			os.Exit(0)
		}
	}

	projectSettingsEnvs := []models.EnvironmentItemModel{}
	if val, err := goinp.AskForString("What's the BITRISE_PROJECT_TITLE?"); err != nil {
		log.Fatalln(err)
	} else {
		projectSettingsEnvs = append(projectSettingsEnvs,
			models.EnvironmentItemModel{"BITRISE_PROJECT_TITLE": val, "is_expand": "no"})
	}
	if val, err := goinp.AskForString("What's your primary development branch's name?"); err != nil {
		log.Fatalln(err)
	} else {
		projectSettingsEnvs = append(projectSettingsEnvs,
			models.EnvironmentItemModel{"BITRISE_DEV_BRANCH": val, "is_expand": "no"})
	}

	bitriseConf := models.BitriseConfigModel{
		FormatVersion: "1.0.0", // TODO: move this into a project config file!
		App: models.AppModel{
			Environments: projectSettingsEnvs,
		},
		Workflows: map[string]models.WorkflowModel{
			"primary": models.WorkflowModel{},
		},
	}

	if err := SaveToFile(bitriseConfigFileRelPath, bitriseConf); err != nil {
		log.Fatalln("Failed to init:", err)
	}
	os.Exit(1)
}

// SaveToFile ...
func SaveToFile(pth string, bitriseConf models.BitriseConfigModel) error {
	if pth == "" {
		return errors.New("No path provided")
	}

	file, err := os.Create(pth)
	if err != nil {
		return err
	}
	defer func() {
		if err := file.Close(); err != nil {
			log.Fatalln("[BITRISE] - Failed to close file:", err)
		}
	}()

	contBytes, err := generateYAML(bitriseConf)
	if err != nil {
		return err
	}

	if _, err := file.Write(contBytes); err != nil {
		return err
	}
	log.Println()
	log.Infoln("=> Init success!")
	log.Infoln("File created at path:", pth)
	log.Infoln("With the content:")
	log.Infoln(string(contBytes))

	return nil
}

func generateYAML(v interface{}) ([]byte, error) {
	bytes, err := yaml.Marshal(v)
	if err != nil {
		return []byte{}, err
	}
	return bytes, nil
}
<|endoftext|>