<commit_before>package deploy

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/jobtalk/thor/api"
	"github.com/jobtalk/thor/lib"
	"github.com/jobtalk/thor/lib/setting"
)

var flagSet = &flag.FlagSet{}
var cred *credentials.Credentials
var (
	file         *string
	f            *string
	profile      *string
	kmsKeyID     *string
	region       *string
	externalPath *string
)

func init() {
	kmsKeyID = flagSet.String("key_id", "", "Amazon KMS key ID")
	file = flagSet.String("file", "", "target file")
	f = flagSet.String("f", "", "target file")
	profile = flagSet.String("profile", "default", "aws credentials profile name")
	region = flagSet.String("region", "ap-northeast-1", "aws region")
	externalPath = flagSet.String("external_path", "", "external conf path")
}

func fileList(root string) ([]string, error) {
	if root == "" {
		return nil, nil
	}
	ret := []string{}
	err := filepath.Walk(root,
		func(path string, info os.FileInfo, err error) error {
			if info.IsDir() {
				return nil
			}

			rel, err := filepath.Rel(root, path)
			if strings.Contains(rel, ".json") {
				ret = append(ret, rel)
			}

			return nil
		})

	if err != nil {
		return nil, err
	}

	return ret, nil
}

type deployConfigure struct {
	*setting.Setting
}

func isEncrypted(data []byte) bool {
	var buffer = map[string]interface{}{}
	if err := json.Unmarshal(data, &buffer); err != nil {
		return false
	}
	elem, ok := buffer["cipher"]
	if !ok {
		return false
	}
	str, ok := elem.(string)
	if !ok {
		return false
	}

	return len(str) != 0
}

func decrypt(bin []byte) ([]byte, error) {
	awsConfig := &aws.Config{
		Credentials: cred,
		Region:      region,
	}
	kms := lib.NewKMSFromBinary(bin)
	if kms == nil {
		return nil, errors.New(fmt.Sprintf("%v format is illegal", string(bin)))
	}
	plainText, err := kms.SetKeyID(*kmsKeyID).SetAWSConfig(awsConfig).Decrypt()
	if err != nil {
		return nil, err
	}
	return plainText, nil
}

func readConf(baseConfPath string, externalPathList []string) (*deployConfigure, error) {
	var root = *externalPath
	var ret = &deployConfigure{}
	base, err := ioutil.ReadFile(baseConfPath)
	baseStr := string(base)
	if err != nil {
		return nil, err
	}
	root = strings.TrimSuffix(root, "/")
	for _, externalPath := range externalPathList {
		external, err := ioutil.ReadFile(root + "/" + externalPath)
		if err != nil {
			return nil, err
		}
		if isEncrypted(external) {
			plain, err := decrypt(external)
			if err != nil {
				return nil, err
			}
			external = plain
		}
		baseStr, err = lib.Embedde(baseStr, string(external))
		if err != nil {
			return nil, err
		}
	}
	if err := json.Unmarshal([]byte(baseStr), ret); err != nil {
		return nil, err
	}
	return ret, nil
}

type Deploy struct{}

func (c *Deploy) Run(args []string) int {
	var config = &deployConfigure{}
	if err := flagSet.Parse(args); err != nil {
		log.Fatalln(err)
	}
	if *file == "" {
		file = f
	}
	cred = credentials.NewSharedCredentials("", *profile)
	awsConfig := &aws.Config{
		Credentials: cred,
		Region:      region,
	}

	externalList, err := fileList(*externalPath)
	if err != nil {
		log.Fatalln(err)
	}
	if externalList != nil {
		c, err := readConf(*file, externalList)
		if err != nil {
			log.Fatalln(err)
		}
		config = c
	} else {
		bin, err := ioutil.ReadFile(*file)
		if err != nil {
			log.Fatalln(err)
		}
		if err := json.Unmarshal(bin, config); err != nil {
			log.Fatalln(err)
		}
	}

	result, err := api.Deploy(awsConfig, config.Setting)
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println(result)
	return 0
}

func (c *Deploy) Synopsis() string {
	synopsis := ""
	synopsis += "usage: thor deploy [options ...]\n"
	synopsis += "options:\n"
	synopsis += "    -f thor_setting.json\n"
	synopsis += "\n"
	synopsis += "    -profile=${aws profile name}\n"
	synopsis += "        -profile option is arbitrary parameter.\n"
	synopsis += "    -region\n"
	synopsis += "        aws region\n"
	synopsis += "    -external_path\n"
	synopsis += "        setting external path file\n"
	synopsis += "===================================================\n"

	return synopsis
}

func (c *Deploy) Help() string {
	return c.Synopsis()
}
<commit_msg>拡張子の読み込み部分を修正<commit_after>package deploy

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/jobtalk/thor/api"
	"github.com/jobtalk/thor/lib"
	"github.com/jobtalk/thor/lib/setting"
)

var re = regexp.MustCompile(`.*\.json$`)

var flagSet = &flag.FlagSet{}
var cred *credentials.Credentials
var (
	file         *string
	f            *string
	profile      *string
	kmsKeyID     *string
	region       *string
	externalPath *string
)

func init() {
	kmsKeyID = flagSet.String("key_id", "", "Amazon KMS key ID")
	file = flagSet.String("file", "", "target file")
	f = flagSet.String("f", "", "target file")
	profile = flagSet.String("profile", "default", "aws credentials profile name")
	region = flagSet.String("region", "ap-northeast-1", "aws region")
	externalPath = flagSet.String("external_path", "", "external conf path")
}

func fileList(root string) ([]string, error) {
	if root == "" {
		return nil, nil
	}
	ret := []string{}
	err := filepath.Walk(root,
		func(path string, info os.FileInfo, err error) error {
			if info.IsDir() {
				return nil
			}

			rel, err := filepath.Rel(root, path)
			if re.MatchString(rel) {
				ret = append(ret, rel)
			}

			return nil
		})

	if err != nil {
		return nil, err
	}

	return ret, nil
}

type deployConfigure struct {
	*setting.Setting
}

func isEncrypted(data []byte) bool {
	var buffer = map[string]interface{}{}
	if err := json.Unmarshal(data, &buffer); err != nil {
		return false
	}
	elem, ok := buffer["cipher"]
	if !ok {
		return false
	}
	str, ok := elem.(string)
	if !ok {
		return false
	}

	return len(str) != 0
}

func decrypt(bin []byte) ([]byte, error) {
	awsConfig := &aws.Config{
		Credentials: cred,
		Region:      region,
	}
	kms := lib.NewKMSFromBinary(bin)
	if kms == nil {
		return nil, errors.New(fmt.Sprintf("%v format is illegal", string(bin)))
	}
	plainText, err := kms.SetKeyID(*kmsKeyID).SetAWSConfig(awsConfig).Decrypt()
	if err != nil {
		return nil, err
	}
	return plainText, nil
}

func readConf(baseConfPath string, externalPathList []string) (*deployConfigure, error) {
	var root = *externalPath
	var ret = &deployConfigure{}
	base, err := ioutil.ReadFile(baseConfPath)
	baseStr := string(base)
	if err != nil {
		return nil, err
	}
	root = strings.TrimSuffix(root, "/")
	for _, externalPath := range externalPathList {
		external, err := ioutil.ReadFile(root + "/" + externalPath)
		if err != nil {
			return nil, err
		}
		if isEncrypted(external) {
			plain, err := decrypt(external)
			if err != nil {
				return nil, err
			}
			external = plain
		}
		baseStr, err = lib.Embedde(baseStr, string(external))
		if err != nil {
			return nil, err
		}
	}
	if err := json.Unmarshal([]byte(baseStr), ret); err != nil {
		return nil, err
	}
	return ret, nil
}

type Deploy struct{}

func (c *Deploy) Run(args []string) int {
	var config = &deployConfigure{}
	if err := flagSet.Parse(args); err != nil {
		log.Fatalln(err)
	}
	if *file == "" {
		file = f
	}
	cred = credentials.NewSharedCredentials("", *profile)
	awsConfig := &aws.Config{
		Credentials: cred,
		Region:      region,
	}

	externalList, err := fileList(*externalPath)
	if err != nil {
		log.Fatalln(err)
	}
	if externalList != nil {
		c, err := readConf(*file, externalList)
		if err != nil {
			log.Fatalln(err)
		}
		config = c
	} else {
		bin, err := ioutil.ReadFile(*file)
		if err != nil {
			log.Fatalln(err)
		}
		if err := json.Unmarshal(bin, config); err != nil {
			log.Fatalln(err)
		}
	}

	result, err := api.Deploy(awsConfig, config.Setting)
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println(result)
	return 0
}

func (c *Deploy) Synopsis() string {
	synopsis := ""
	synopsis += "usage: thor deploy [options ...]\n"
	synopsis += "options:\n"
	synopsis += "    -f thor_setting.json\n"
	synopsis += "\n"
	synopsis += "    -profile=${aws profile name}\n"
	synopsis += "        -profile option is arbitrary parameter.\n"
	synopsis += "    -region\n"
	synopsis += "        aws region\n"
	synopsis += "    -external_path\n"
	synopsis += "        setting external path file\n"
	synopsis += "===================================================\n"

	return synopsis
}

func (c *Deploy) Help() string {
	return c.Synopsis()
}
<|endoftext|>


<commit_before>package mixpanel

import "time"

const (
	fmt_mptime = "2006-01-02T15:04:05"
)

func TimeToMPFmt(t time.Time) string {
	return t.Format(fmt_mptime)
}

func Now() string {
	return TimeToMPFmt(time.Now().UTC())
}
<commit_msg>force UTC in formatting<commit_after>package mixpanel

import "time"

const (
	fmt_mptime = "2006-01-02T15:04:05"
)

func TimeToMPFmt(t time.Time) string {
	return t.UTC().Format(fmt_mptime)
}

func Now() string {
	return TimeToMPFmt(time.Now())
}
<|endoftext|>


<commit_before>package imaging

import (
	"fmt"
	"image"
	"image/color"
	_ "image/gif"
	"image/jpeg"
	"image/png"
	"os"
	"path/filepath"
	"strings"
)

// Open loads an image from file
func Open(filename string) (img image.Image, err error) {
	file, err := os.Open(filename)
	if err != nil {
		return
	}
	defer file.Close()

	img, _, err = image.Decode(file)
	if err != nil {
		return
	}

	img = toNRGBA(img)
	return
}

// Save saves the image to file with the specified filename.
// The format is determined from the filename extension, "jpg" (or "jpeg") and "png" are supported.
func Save(img image.Image, filename string) (err error) {
	format := strings.ToLower(filepath.Ext(filename))
	if format != ".jpg" && format != ".jpeg" && format != ".png" {
		err = fmt.Errorf("unknown image format: %s", format)
		return
	}

	file, err := os.Create(filename)
	if err != nil {
		return
	}
	defer file.Close()

	switch format {
	case ".jpg", ".jpeg":
		var rgba *image.RGBA
		if nrgba, ok := img.(*image.NRGBA); ok {
			if nrgba.Opaque() {
				rgba = &image.RGBA{
					Pix:    nrgba.Pix,
					Stride: nrgba.Stride,
					Rect:   nrgba.Rect,
				}
			}
		}
		if rgba != nil {
			err = jpeg.Encode(file, rgba, &jpeg.Options{Quality: 95})
		} else {
			err = jpeg.Encode(file, img, &jpeg.Options{Quality: 95})
		}

	case ".png":
		err = png.Encode(file, img)
	}
	return
}

// New creates a new image with the specified width and height, and fills it with the specified color.
func New(width, height int, fillColor color.Color) *image.NRGBA {
	dst := image.NewNRGBA(image.Rect(0, 0, width, height))

	c := color.NRGBAModel.Convert(fillColor).(color.NRGBA)
	cs := []uint8{c.R, c.G, c.B, c.A}

	// fill the first row
	for x := 0; x < width; x++ {
		copy(dst.Pix[x*4:(x+1)*4], cs)
	}
	// copy the first row to other rows
	for y := 1; y < height; y++ {
		copy(dst.Pix[y*dst.Stride:y*dst.Stride+width*4], dst.Pix[0:width*4])
	}

	return dst
}

// This function used internally to convert any image type to NRGBA if needed.
func toNRGBA(img image.Image) *image.NRGBA {
	srcBounds := img.Bounds()
	if srcBounds.Min.X == 0 && srcBounds.Min.Y == 0 {
		if src0, ok := img.(*image.NRGBA); ok {
			return src0
		}
	}
	return Clone(img)
}
<commit_msg>better err msg<commit_after>package imaging

import (
	"fmt"
	"image"
	"image/color"
	_ "image/gif"
	"image/jpeg"
	"image/png"
	"os"
	"path/filepath"
	"strings"
)

// Open loads an image from file
func Open(filename string) (img image.Image, err error) {
	file, err := os.Open(filename)
	if err != nil {
		return
	}
	defer file.Close()

	img, _, err = image.Decode(file)
	if err != nil {
		return
	}

	img = toNRGBA(img)
	return
}

// Save saves the image to file with the specified filename.
// The format is determined from the filename extension, "jpg" (or "jpeg") and "png" are supported.
func Save(img image.Image, filename string) (err error) {
	format := strings.ToLower(filepath.Ext(filename))
	if format != ".jpg" && format != ".jpeg" && format != ".png" {
		err = fmt.Errorf(`imaging: unsupported image format: "%s"`, format)
		return
	}

	file, err := os.Create(filename)
	if err != nil {
		return
	}
	defer file.Close()

	switch format {
	case ".jpg", ".jpeg":
		var rgba *image.RGBA
		if nrgba, ok := img.(*image.NRGBA); ok {
			if nrgba.Opaque() {
				rgba = &image.RGBA{
					Pix:    nrgba.Pix,
					Stride: nrgba.Stride,
					Rect:   nrgba.Rect,
				}
			}
		}
		if rgba != nil {
			err = jpeg.Encode(file, rgba, &jpeg.Options{Quality: 95})
		} else {
			err = jpeg.Encode(file, img, &jpeg.Options{Quality: 95})
		}

	case ".png":
		err = png.Encode(file, img)
	}
	return
}

// New creates a new image with the specified width and height, and fills it with the specified color.
func New(width, height int, fillColor color.Color) *image.NRGBA {
	dst := image.NewNRGBA(image.Rect(0, 0, width, height))

	c := color.NRGBAModel.Convert(fillColor).(color.NRGBA)
	cs := []uint8{c.R, c.G, c.B, c.A}

	// fill the first row
	for x := 0; x < width; x++ {
		copy(dst.Pix[x*4:(x+1)*4], cs)
	}
	// copy the first row to other rows
	for y := 1; y < height; y++ {
		copy(dst.Pix[y*dst.Stride:y*dst.Stride+width*4], dst.Pix[0:width*4])
	}

	return dst
}

// This function used internally to convert any image type to NRGBA if needed.
func toNRGBA(img image.Image) *image.NRGBA {
	srcBounds := img.Bounds()
	if srcBounds.Min.X == 0 && srcBounds.Min.Y == 0 {
		if src0, ok := img.(*image.NRGBA); ok {
			return src0
		}
	}
	return Clone(img)
}
<|endoftext|>


<commit_before>package ts3

import (
	"strings"
)

// Escapes special chars
func Ts3Quote(s string) string {
	s = strings.Replace(s, "/", "\\/", -1)
	s = strings.Replace(s, " ", "\\s", -1)
	s = strings.Replace(s, "|", "\\p", -1)
	return strings.Trim(s, "\r")
}

// Unescapes special chars
func Ts3Unquote(s string) string {
	s = strings.Replace(s, "\\/", "/", -1)
	s = strings.Replace(s, "\\s", " ", -1)
	s = strings.Replace(s, "\\p", "|", -1)
	return strings.Trim(s, "\r")
}

// Keeps only printable ASCII runes, also cleans "\r"
func StringsTrimNet(s string) string {
	var res []rune

	s = strings.Trim(s, "\r")

	// Just pretty ASCII runes
	for _, r := range s {
		switch {
		case 32 >= r || r <= 127:
			res = append(res, r)
		}
	}

	return string(res)
}
<commit_msg>Remove clutter from helpers.<commit_after>package ts3

import (
	"strings"
)

// Escapes special chars
func Quote(s string) string {
	s = strings.Replace(s, "/", "\\/", -1)
	s = strings.Replace(s, " ", "\\s", -1)
	s = strings.Replace(s, "|", "\\p", -1)
	return strings.Trim(s, "\r")
}

// Unescapes special chars
func Unquote(s string) string {
	s = strings.Replace(s, "\\/", "/", -1)
	s = strings.Replace(s, "\\s", " ", -1)
	s = strings.Replace(s, "\\p", "|", -1)
	return strings.Trim(s, "\r")
}

// Keeps only printable ASCII runes, also cleans "\r"
func trimNet(s string) string {
	var res []rune

	s = strings.Trim(s, "\r")

	// Just pretty ASCII runes
	for _, r := range s {
		switch {
		case 32 >= r || r <= 127:
			res = append(res, r)
		}
	}

	return string(res)
}
<|endoftext|>


<commit_before>package gerrittest

import (
	"errors"
	"net/url"
	"os"
	"os/exec"
	"strings"
)

// Helpers provides structs and functions for setting up and
// interacting with Gerrit.

var (
	// ErrGerritDown is returned by Ping() if Gerrit appears to be down.
	ErrGerritDown = errors.New(
		"Gerrrit is not running or failed to start.")
)

// GerritHelpers is a struct which provides helper methods for interacting
// with a running instance of Gerrit.
type GerritHelpers struct {
	PortHTTP int
	PortSSH  int
	Address  string
}

// AddressOnly returns the address part of the given value. For example:
//           127.0.0.1:5000 -> 127.0.0.1
//    tcp://127.0.0.1:5000/ -> 127.0.0.1
func AddressOnly(value string) string {
	value = strings.TrimSpace(value)
	if parsed, err := url.Parse(value); err == nil {
		if parsed.Host == "" {
			return value
		}
		value = parsed.Host
	}
	if strings.Contains(value, ":") {
		value = strings.Split(value, ":")[0]
	}

	return value
}

// GetAddress attempts to returns the address where we should expect to
// connect to. This will try $DOCKER_HOST first and failing that attempt
// to use docker-machine before finally giving up and returning 127.0.0.1.
func GetAddress() string {
	address := "127.0.0.1"

	if dockerhost, set := os.LookupEnv("DOCKER_HOST"); set {
		address = AddressOnly(dockerhost)
	} else {
		command := exec.Command("docker-machine", "ip")
		if data, err := command.Output(); err == nil {
			address = AddressOnly(string(data))
		}
	}

	return address
}

// NewGerritHelpers produces a new *GerritHelpers struct.
func NewGerritHelpers(container *Container) (*GerritHelpers, error) {

	helpers := &GerritHelpers{
		PortHTTP: int(container.HTTP),
		PortSSH:  int(container.SSH),
	}
	return helpers, helpers.Ping()
}

// Ping returns nil if Gerrit appears to be running.
func (helpers *GerritHelpers) Ping() error {
	return nil
}
<commit_msg>added Ping(), added some comments<commit_after>package gerrittest

import (
	"fmt"
	"golang.org/x/crypto/ssh"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"strings"
)

// Helpers provides structs and functions for setting up and
// interacting with Gerrit.

// GerritHelpers is a struct which provides helper methods for interacting
// with a running instance of Gerrit.
type GerritHelpers struct {
	// PortHTTP is the port that should be used when attempting to connect
	// to Gerrit.
	PortHTTP int

	// PortSSH is the port that should be used when attempting to connect
	// to Gerrit.
	PortSSH int

	// Address is the IP address or hostname that is running the docker
	// container.
	Address string

	// URL is the root url to make API requests to.  It will be
	// something like http://127.0.0.1:8080
	URL string
}

// AddressOnly returns the address part of the given value. For example:
//           127.0.0.1:5000 -> 127.0.0.1
//    tcp://127.0.0.1:5000/ -> 127.0.0.1
func AddressOnly(value string) string {
	value = strings.TrimSpace(value)
	if parsed, err := url.Parse(value); err == nil {
		if parsed.Host == "" {
			return value
		}
		value = parsed.Host
	}
	if strings.Contains(value, ":") {
		value = strings.Split(value, ":")[0]
	}

	return value
}

// GetAddress attempts to returns the address where we should expect to
// connect to. This will try $DOCKER_HOST first and failing that attempt
// to use docker-machine before finally giving up and returning 127.0.0.1.
func GetAddress() string {
	address := "127.0.0.1"

	if dockerhost, set := os.LookupEnv("DOCKER_HOST"); set {
		address = AddressOnly(dockerhost)
	} else {
		command := exec.Command("docker-machine", "ip")
		if data, err := command.Output(); err == nil {
			address = AddressOnly(string(data))
		}
	}

	return address
}

// NewGerritHelpers produces a new *GerritHelpers struct.
func NewGerritHelpers(container *Container) (*GerritHelpers, error) {
	address := GetAddress()
	httpport := int(container.HTTP)
	helpers := &GerritHelpers{
		PortHTTP: httpport,
		PortSSH:  int(container.SSH),
		Address:  address,
		URL:      fmt.Sprintf("http://%s:%d", address, httpport)}
	return helpers, helpers.Ping()
}

// Ping returns nil if Gerrit appears to be running. This will ensures that
// we can make a successful HTTP request and that w can connect to ssh.
func (helpers *GerritHelpers) Ping() error {
	// Attempt to connect to http by making a request.
	if _, err := http.Get(helpers.URL); err != nil {
		return err
	}

	_, err := ssh.Dial(
		"tcp",
		fmt.Sprintf("%s:%d", helpers.Address, helpers.PortSSH),
		&ssh.ClientConfig{})
	if strings.Contains(err.Error(), "unable to authenticate") {
		return nil
	}
	return err
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 TSUYUSATO Kitsune
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php

// Package heredoc provides the here-document with keeping indent.
//
// Golang supports raw-string syntax.
//     doc := `
//     	Foo
//     	Bar
//     `
// But raw-string cannot recognize indent. Thus such content is indented string, equivalent to
//     "\n\tFoo\n\tBar\n"
// I dont't want this!
//
// However this problem is solved by package heredoc.
//     doc := heredoc.Doc(`
//     	Foo
//     	Bar
//     `)
// It is equivalent to
//     "Foo\nBar\n"
package heredoc

import (
	"strings"
	"unicode"
)

// heredoc.Doc retutns unindented string as here-document.
//
// Process of making here-document:
//     1. Find most little indent size. (Skip empty lines)
//     2. Remove this indents of lines.
func Doc(raw string) string {
	skipFirstLine := false
	if raw[0] == '\n' {
		raw = raw[1:]
	} else {
		skipFirstLine = true
	}

	minIndentSize := int(^uint(0) >> 1) // Max value of type int
	lines := strings.Split(raw, "\n")

	// 1.
	for i, line := range lines {
		if i == 0 && skipFirstLine {
			continue
		}

		indentSize := 0
		for _, r := range []rune(line) {
			if unicode.IsSpace(r) {
				indentSize += 1
			} else {
				break
			}
		}

		if len(line) == indentSize {
			if i == len(lines)-1 && indentSize < minIndentSize {
				lines[i] = ""
			}
		} else if indentSize < minIndentSize {
			minIndentSize = indentSize
		}
	}

	// 2.
	for i, line := range lines {
		if i == 0 && skipFirstLine {
			continue
		}

		if len(lines[i]) >= minIndentSize {
			lines[i] = line[minIndentSize:]
		}
	}

	return strings.Join(lines, "\n")
}
<commit_msg>For using as heredoc, we want the string interpolation like syntax, add heredoc.Docf<commit_after>// Copyright (c) 2014 TSUYUSATO Kitsune
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php

// Package heredoc provides the here-document with keeping indent.
//
// Golang supports raw-string syntax.
//     doc := `
//     	Foo
//     	Bar
//     `
// But raw-string cannot recognize indent. Thus such content is indented string, equivalent to
//     "\n\tFoo\n\tBar\n"
// I dont't want this!
//
// However this problem is solved by package heredoc.
//     doc := heredoc.Doc(`
//     	Foo
//     	Bar
//     `)
// It is equivalent to
//     "Foo\nBar\n"
package heredoc

import (
	"fmt"
	"strings"
	"unicode"
)

// heredoc.Doc retutns unindented string as here-document.
//
// Process of making here-document:
//     1. Find most little indent size. (Skip empty lines)
//     2. Remove this indents of lines.
func Doc(raw string) string {
	skipFirstLine := false
	if raw[0] == '\n' {
		raw = raw[1:]
	} else {
		skipFirstLine = true
	}

	minIndentSize := int(^uint(0) >> 1) // Max value of type int
	lines := strings.Split(raw, "\n")

	// 1.
	for i, line := range lines {
		if i == 0 && skipFirstLine {
			continue
		}

		indentSize := 0
		for _, r := range []rune(line) {
			if unicode.IsSpace(r) {
				indentSize += 1
			} else {
				break
			}
		}

		if len(line) == indentSize {
			if i == len(lines)-1 && indentSize < minIndentSize {
				lines[i] = ""
			}
		} else if indentSize < minIndentSize {
			minIndentSize = indentSize
		}
	}

	// 2.
	for i, line := range lines {
		if i == 0 && skipFirstLine {
			continue
		}

		if len(lines[i]) >= minIndentSize {
			lines[i] = line[minIndentSize:]
		}
	}

	return strings.Join(lines, "\n")
}

// heredoc.Docf returns unindented and formatted string as here-document.
// This format is same with package fmt's format.
func Docf(raw string, args ...interface{}) string {
	return fmt.Sprintf(Doc(raw), args...)
}
<|endoftext|>


<commit_before>package hexgrid

import (
	"math"

	morton "github.com/gojuno/go.morton"
)

type Point struct {
	x float64
	y float64
}

type Hex struct {
	q int64
	r int64
}

type FractionalHex struct {
	q float64
	r float64
}

type Orientation struct {
	f          [4]float64
	b          [4]float64
	startAngle float64
	sinuses    [6]float64
	cosinuses  [6]float64
}

type Grid struct {
	orientation Orientation
	origin      Point
	size        Point
	mort        *morton.Morton64
}

type Region struct {
	grid   *Grid
	hexes  []Hex
	lookup map[int64]int
}

var OrientationPointy = Orientation{
	f:          [4]float64{math.Sqrt(3.0), math.Sqrt(3.0) / 2.0, 0.0, 3.0 / 2.0},
	b:          [4]float64{math.Sqrt(3.0) / 3.0, -1.0 / 3.0, 0.0, 2.0 / 3.0},
	startAngle: 0.5}

var OrientationFlat = Orientation{
	f:          [4]float64{3.0 / 2.0, 0.0, math.Sqrt(3.0) / 2.0, math.Sqrt(3.0)},
	b:          [4]float64{2.0 / 3.0, 0.0, -1.0 / 3.0, math.Sqrt(3.0) / 3.0},
	startAngle: 0.0}

func init() {
	prehashAngles(&OrientationPointy)
	prehashAngles(&OrientationFlat)
}

func prehashAngles(orientation *Orientation) {
	for i := 0; i < 6; i++ {
		angle := 2.0 * math.Pi * (float64(i) + orientation.startAngle) / 6.0
		orientation.sinuses[i] = math.Sin(angle)
		orientation.cosinuses[i] = math.Cos(angle)
	}
}

func round(val float64) int64 {
	if val < 0 {
		return int64(val - 0.5)
	}
	return int64(val + 0.5)
}

func max(a int64, b int64) int64 {
	if a >= b {
		return a
	}
	return b
}

func min(a int64, b int64) int64 {
	if a <= b {
		return a
	}
	return b
}

func MakePoint(x float64, y float64) Point {
	return Point{x: x, y: y}
}

func (point Point) X() float64 {
	return point.x
}

func (point Point) Y() float64 {
	return point.y
}

func MakeHex(q int64, r int64) Hex {
	return Hex{q: q, r: r}
}

func (hex Hex) Q() int64 {
	return hex.q
}

func (hex Hex) R() int64 {
	return hex.r
}

func (hex Hex) S() int64 {
	return -(hex.q + hex.r)
}

func MakeFractionalHex(q float64, r float64) FractionalHex {
	return FractionalHex{q: q, r: r}
}

func (fhex FractionalHex) Q() float64 {
	return fhex.q
}

func (fhex FractionalHex) R() float64 {
	return fhex.r
}

func (fhex FractionalHex) S() float64 {
	return -(fhex.q + fhex.r)
}

func (fhex FractionalHex) ToHex() Hex {
	q := round(fhex.Q())
	r := round(fhex.R())
	s := round(fhex.S())
	qDiff := math.Abs(float64(q) - fhex.Q())
	rDiff := math.Abs(float64(r) - fhex.R())
	sDiff := math.Abs(float64(s) - fhex.S())

	if qDiff > rDiff && qDiff > sDiff {
		q = -(r + s)
	} else if rDiff > sDiff {
		r = -(q + s)
	}

	return Hex{q: q, r: r}
}

func MakeGrid(orientation Orientation, origin Point, size Point, mort *morton.Morton64) *Grid {
	return &Grid{orientation: orientation, origin: origin, size: size, mort: mort}
}

func (grid *Grid) HexToCode(hex Hex) int64 {
	return grid.mort.SPack(hex.Q(), hex.R())
}

func (grid *Grid) HexFromCode(code int64) Hex {
	qr := grid.mort.SUnpack(code)
	return MakeHex(qr[0], qr[1])
}

func (grid *Grid) HexAt(point Point) Hex {
	x := (point.X() - grid.origin.X()) / grid.size.X()
	y := (point.Y() - grid.origin.Y()) / grid.size.Y()
	q := grid.orientation.b[0]*x + grid.orientation.b[1]*y
	r := grid.orientation.b[2]*x + grid.orientation.b[3]*y
	return MakeFractionalHex(q, r).ToHex()
}

func (grid *Grid) HexCenter(hex Hex) Point {
	x := (grid.orientation.f[0]*float64(hex.Q())+grid.orientation.f[1]*float64(hex.R()))*grid.size.X() + grid.origin.X()
	y := (grid.orientation.f[2]*float64(hex.Q())+grid.orientation.f[3]*float64(hex.R()))*grid.size.Y() + grid.origin.Y()
	return MakePoint(x, y)
}

func (grid *Grid) HexCorners(hex Hex) [6]Point {
	var corners [6]Point
	center := grid.HexCenter(hex)
	for i := 0; i < 6; i++ {
		x := grid.size.X()*grid.orientation.cosinuses[i] + center.X()
		y := grid.size.Y()*grid.orientation.sinuses[i] + center.Y()
		corners[i] = MakePoint(x, y)
	}
	return corners
}

func (grid *Grid) HexNeighbors(hex Hex, layers int64) []Hex {
	total := (layers + 1) * layers * 3
	neighbors := make([]Hex, total)
	i := 0
	for q := -layers; q <= layers; q++ {
		r1 := max(-layers, -q-layers)
		r2 := min(layers, -q+layers)
		for r := r1; r <= r2; r++ {
			if q == 0 && r == 0 {
				continue
			}
			neighbors[i] = MakeHex(q+hex.Q(), r+hex.R())
			i += 1
		}
	}
	return neighbors
}

func pointInGeometry(geometry []Point, point Point) bool {
	contains := intersectsWithRaycast(point, geometry[len(geometry)-1], geometry[0])
	for i := 1; i < len(geometry); i++ {
		if intersectsWithRaycast(point, geometry[i-1], geometry[i]) {
			contains = !contains
		}
	}
	return contains
}

/* from https://github.com/kellydunn/golang-geo */
func intersectsWithRaycast(point Point, start Point, end Point) bool {
	if start.Y() > end.Y() {
		start, end = end, start
	}

	for point.Y() == start.Y() || point.Y() == end.Y() {
		newY := math.Nextafter(point.Y(), math.Inf(1))
		point = MakePoint(point.X(), newY)
	}

	if point.Y() < start.Y() || point.Y() > end.Y() {
		return false
	}

	if start.X() > end.X() {
		if point.X() > start.X() {
			return false
		}
		if point.X() < end.X() {
			return true
		}
	} else {
		if point.X() > end.X() {
			return false
		}
		if point.X() < start.X() {
			return true
		}
	}

	raySlope := (point.Y() - start.Y()) / (point.X() - start.X())
	diagSlope := (end.Y() - start.Y()) / (end.X() - start.X())

	return raySlope >= diagSlope
}

func (grid *Grid) MakeRegion(geometry []Point) *Region {
	if geometry[0] == geometry[len(geometry)-1] {
		geometry = geometry[:len(geometry)-1]
	}

	hex := grid.HexAt(geometry[0])
	q1 := hex.Q()
	q2 := hex.Q()
	r1 := hex.R()
	r2 := hex.R()

	for i := 1; i < len(geometry); i++ {
		hex = grid.HexAt(geometry[i])
		q1 = min(q1, hex.Q())
		q2 = max(q2, hex.Q())
		r1 = min(r1, hex.R())
		r2 = max(r2, hex.R())
	}

	q1 -= 1
	q2 += 1
	r1 -= 1
	r2 += 1

	hexes := make([]Hex, 0)

	for q := q1; q <= q2; q++ {
		for r := r1; r <= r2; r++ {
			hex := MakeHex(q, r)
			corners := grid.HexCorners(hex)
			add := false
			for c := 0; c < 6; c++ {
				if pointInGeometry(geometry, corners[c]) {
					add = true
					break
				}
			}

			if !add {
				for i := 0; i < len(geometry); i++ {
					if pointInGeometry(corners[:], geometry[i]) {
						add = true
						break
					}
				}
			}

			if add {
				hexes = append(hexes, hex)
			}
		}
	}

	lookup := make(map[int64]int)
	for i := 0; i < len(hexes); i++ {
		lookup[grid.HexToCode(hexes[i])] = i
	}

	return &Region{grid: grid, hexes: hexes, lookup: lookup}
}

func (region *Region) Hexes() []Hex {
	return region.hexes
}

func (region *Region) Contains(hex Hex) bool {
	_, contains := region.lookup[region.grid.HexToCode(hex)]
	return contains
}
<commit_msg>Support for multipolygons.<commit_after>package hexgrid

import (
	"math"

	morton "github.com/gojuno/go.morton"
)

type Point struct {
	x float64
	y float64
}

type Hex struct {
	q int64
	r int64
}

type FractionalHex struct {
	q float64
	r float64
}

type Orientation struct {
	f          [4]float64
	b          [4]float64
	startAngle float64
	sinuses    [6]float64
	cosinuses  [6]float64
}

type Grid struct {
	orientation Orientation
	origin      Point
	size        Point
	mort        *morton.Morton64
}

type Region struct {
	grid   *Grid
	hexes  []Hex
	lookup map[int64]int
}

var OrientationPointy = Orientation{
	f:          [4]float64{math.Sqrt(3.0), math.Sqrt(3.0) / 2.0, 0.0, 3.0 / 2.0},
	b:          [4]float64{math.Sqrt(3.0) / 3.0, -1.0 / 3.0, 0.0, 2.0 / 3.0},
	startAngle: 0.5}

var OrientationFlat = Orientation{
	f:          [4]float64{3.0 / 2.0, 0.0, math.Sqrt(3.0) / 2.0, math.Sqrt(3.0)},
	b:          [4]float64{2.0 / 3.0, 0.0, -1.0 / 3.0, math.Sqrt(3.0) / 3.0},
	startAngle: 0.0}

func init() {
	prehashAngles(&OrientationPointy)
	prehashAngles(&OrientationFlat)
}

func prehashAngles(orientation *Orientation) {
	for i := 0; i < 6; i++ {
		angle := 2.0 * math.Pi * (float64(i) + orientation.startAngle) / 6.0
		orientation.sinuses[i] = math.Sin(angle)
		orientation.cosinuses[i] = math.Cos(angle)
	}
}

func round(val float64) int64 {
	if val < 0 {
		return int64(val - 0.5)
	}
	return int64(val + 0.5)
}

func max(a int64, b int64) int64 {
	if a >= b {
		return a
	}
	return b
}

func min(a int64, b int64) int64 {
	if a <= b {
		return a
	}
	return b
}

func MakePoint(x float64, y float64) Point {
	return Point{x: x, y: y}
}

func (point Point) X() float64 {
	return point.x
}

func (point Point) Y() float64 {
	return point.y
}

func MakeHex(q int64, r int64) Hex {
	return Hex{q: q, r: r}
}

func (hex Hex) Q() int64 {
	return hex.q
}

func (hex Hex) R() int64 {
	return hex.r
}

func (hex Hex) S() int64 {
	return -(hex.q + hex.r)
}

func MakeFractionalHex(q float64, r float64) FractionalHex {
	return FractionalHex{q: q, r: r}
}

func (fhex FractionalHex) Q() float64 {
	return fhex.q
}

func (fhex FractionalHex) R() float64 {
	return fhex.r
}

func (fhex FractionalHex) S() float64 {
	return -(fhex.q + fhex.r)
}

func (fhex FractionalHex) ToHex() Hex {
	q := round(fhex.Q())
	r := round(fhex.R())
	s := round(fhex.S())
	qDiff := math.Abs(float64(q) - fhex.Q())
	rDiff := math.Abs(float64(r) - fhex.R())
	sDiff := math.Abs(float64(s) - fhex.S())

	if qDiff > rDiff && qDiff > sDiff {
		q = -(r + s)
	} else if rDiff > sDiff {
		r = -(q + s)
	}

	return Hex{q: q, r: r}
}

func MakeGrid(orientation Orientation, origin Point, size Point, mort *morton.Morton64) *Grid {
	return &Grid{orientation: orientation, origin: origin, size: size, mort: mort}
}

func (grid *Grid) HexToCode(hex Hex) int64 {
	return grid.mort.SPack(hex.Q(), hex.R())
}

func (grid *Grid) HexFromCode(code int64) Hex {
	qr := grid.mort.SUnpack(code)
	return MakeHex(qr[0], qr[1])
}

func (grid *Grid) HexAt(point Point) Hex {
	x := (point.X() - grid.origin.X()) / grid.size.X()
	y := (point.Y() - grid.origin.Y()) / grid.size.Y()
	q := grid.orientation.b[0]*x + grid.orientation.b[1]*y
	r := grid.orientation.b[2]*x + grid.orientation.b[3]*y
	return MakeFractionalHex(q, r).ToHex()
}

func (grid *Grid) HexCenter(hex Hex) Point {
	x := (grid.orientation.f[0]*float64(hex.Q())+grid.orientation.f[1]*float64(hex.R()))*grid.size.X() + grid.origin.X()
	y := (grid.orientation.f[2]*float64(hex.Q())+grid.orientation.f[3]*float64(hex.R()))*grid.size.Y() + grid.origin.Y()
	return MakePoint(x, y)
}

func (grid *Grid) HexCorners(hex Hex) [6]Point {
	var corners [6]Point
	center := grid.HexCenter(hex)
	for i := 0; i < 6; i++ {
		x := grid.size.X()*grid.orientation.cosinuses[i] + center.X()
		y := grid.size.Y()*grid.orientation.sinuses[i] + center.Y()
		corners[i] = MakePoint(x, y)
	}
	return corners
}

func (grid *Grid) HexNeighbors(hex Hex, layers int64) []Hex {
	total := (layers + 1) * layers * 3
	neighbors := make([]Hex, total)
	i := 0
	for q := -layers; q <= layers; q++ {
		r1 := max(-layers, -q-layers)
		r2 := min(layers, -q+layers)
		for r := r1; r <= r2; r++ {
			if q == 0 && r == 0 {
				continue
			}
			neighbors[i] = MakeHex(q+hex.Q(), r+hex.R())
			i += 1
		}
	}
	return neighbors
}

/* from https://github.com/kellydunn/golang-geo */
func intersectsWithRaycast(point Point, start Point, end Point) bool {
	if start.Y() > end.Y() {
		start, end = end, start
	}

	for point.Y() == start.Y() || point.Y() == end.Y() {
		newY := math.Nextafter(point.Y(), math.Inf(1))
		point = MakePoint(point.X(), newY)
	}

	if point.Y() < start.Y() || point.Y() > end.Y() {
		return false
	}

	if start.X() > end.X() {
		if point.X() > start.X() {
			return false
		}
		if point.X() < end.X() {
			return true
		}
	} else {
		if point.X() > end.X() {
			return false
		}
		if point.X() < start.X() {
			return true
		}
	}

	raySlope := (point.Y() - start.Y()) / (point.X() - start.X())
	diagSlope := (end.Y() - start.Y()) / (end.X() - start.X())

	return raySlope >= diagSlope
}

func pointInGeometry(geometry [][]Point, point Point) bool {
	contains := false
	for g := 0; g < len(geometry); g++ {
		if intersectsWithRaycast(point, geometry[g][len(geometry[g])-1], geometry[g][0]) {
			contains = !contains
		}
		for i := 1; i < len(geometry[g]); i++ {
			if intersectsWithRaycast(point, geometry[g][i-1], geometry[g][i]) {
				contains = !contains
			}
		}
	}
	return contains
}

func (grid *Grid) MakeRegionFromMultiPolygon(geometry [][]Point) *Region {
	for g := 0; g < len(geometry); g++ {
		if geometry[g][0] == geometry[g][len(geometry[g])-1] {
			geometry[g] = geometry[g][:len(geometry[g])-1]
		}
	}

	hex := grid.HexAt(geometry[0][0])
	q1 := hex.Q()
	q2 := hex.Q()
	r1 := hex.R()
	r2 := hex.R()

	for g := 0; g < len(geometry); g++ {
		for i := 0; i < len(geometry[g]); i++ {
			hex = grid.HexAt(geometry[g][i])
			q1 = min(q1, hex.Q())
			q2 = max(q2, hex.Q())
			r1 = min(r1, hex.R())
			r2 = max(r2, hex.R())
		}
	}

	q1 -= 1
	q2 += 1
	r1 -= 1
	r2 += 1

	hexes := make([]Hex, 0)

	for q := q1; q <= q2; q++ {
		for r := r1; r <= r2; r++ {
			hex := MakeHex(q, r)
			corners := grid.HexCorners(hex)
			add := false

			for c := 0; c < 6; c++ {
				if pointInGeometry(geometry, corners[c]) {
					add = true
					break
				}
			}

			if !add {
				mcorners := make([][]Point, 1)
				mcorners[0] = corners[:]
				for g := 0; g < len(geometry); g++ {
					for i := 0; i < len(geometry[g]); i++ {
						if pointInGeometry(mcorners, geometry[g][i]) {
							add = true
							break
						}
					}
					if add == true {
						break
					}
				}
			}

			if add {
				hexes = append(hexes, hex)
			}
		}
	}

	lookup := make(map[int64]int)
	for i := 0; i < len(hexes); i++ {
		lookup[grid.HexToCode(hexes[i])] = i
	}

	return &Region{grid: grid, hexes: hexes, lookup: lookup}
}

func (grid *Grid) MakeRegion(geometry []Point) *Region {
	mgeometry := make([][]Point, 1)
	mgeometry[0] = geometry
	return grid.MakeRegionFromMultiPolygon(mgeometry)
}

func (region *Region) Hexes() []Hex {
	return region.hexes
}

func (region *Region) Contains(hex Hex) bool {
	_, contains := region.lookup[region.grid.HexToCode(hex)]
	return contains
}
<|endoftext|>


<commit_before>package input

import (
	"bufio"
	"errors"
	"io"
	"os"
	"syscall"

	log "github.com/Sirupsen/logrus"
)

func init() {
	registerInput("namedpipe", newNamedPipeInput)
}

var (
	pipePath = flag.String("input.namedpipe.path", "", "Path where pipe should be created")
)

func newNamedPipeInput() (StreamInput, error) {
	if *filePath == "" {
		return nil, errors.New("-input.namedpipe.path not set")
	}

	return NamedPipeInput{
		path: *pipePath,
	}, nil
}

func (input NamedPipeInput) StartStream(ch chan<- string) {
	err := syscall.Mkfifo(input.path, 0666)
	if err != nil {
		log.Fatal(err)
	}

	pipe, err := os.OpenFile(input.path, os.O_RDONLY, os.ModeNamedPipe)
	if err != nil {
		log.Fatal(err)
	}
	defer os.Remove(input.path)

	reader := bufio.NewReader(pipe)
	scanner := bufio.NewScanner(reader)

	for scanner.Scan() {
		ch <- scanner.Text()
	}
}
<commit_msg>Fix namedpipe compilation error<commit_after>package input

import (
	"bufio"
	"errors"
	"flag"
	"os"
	"syscall"

	log "github.com/Sirupsen/logrus"
)

func init() {
	registerInput("namedpipe", newNamedPipeInput)
}

var (
	pipePath = flag.String("input.namedpipe.path", "", "Path where pipe should be created")
)

func newNamedPipeInput() (StreamInput, error) {
	if *filePath == "" {
		return nil, errors.New("-input.namedpipe.path not set")
	}

	return NamedPipeInput{
		path: *pipePath,
	}, nil
}

func (input NamedPipeInput) StartStream(ch chan<- string) {
	err := syscall.Mkfifo(input.path, 0666)
	if err != nil {
		log.Fatal(err)
	}

	pipe, err := os.OpenFile(input.path, os.O_RDONLY, os.ModeNamedPipe)
	if err != nil {
		log.Fatal(err)
	}
	defer os.Remove(input.path)

	reader := bufio.NewReader(pipe)
	scanner := bufio.NewScanner(reader)

	for scanner.Scan() {
		ch <- scanner.Text()
	}
}
<|endoftext|>


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

package symbol

import (
	blake2b "github.com/minio/blake2b-simd"
	"github.com/zchee/clang-server/internal/hashutil"
)

// ID id of cursor.USR with blake2b hash.
type ID [blake2b.Size]byte

func (id ID) String() string {
	return hashutil.EncodeToString(id)
}

func (id ID) Bytes() []byte {
	return id[:]
}

// FileID id of filename with blake2b hash.
type FileID [blake2b.Size]byte

func (id FileID) String() string {
	return hashutil.EncodeToString(id)
}

func (id FileID) Bytes() []byte {
	return id[:]
}

var (
	NoID     ID     = [64]byte{} // empty
	NoFileID FileID = [64]byte{} // empty
)

// ToID converts the string to blake2b sum512 hash.
func ToID(s string) ID {
	return hashutil.NewHashString(s)
}

// ToFileID converts the string to blake2b sum512 hash.
func ToFileID(s string) FileID {
	return hashutil.NewHashString(s)
}
<commit_msg>symbol: add IsEmpty function and godoc comments<commit_after>// Copyright 2017 The clang-server Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package symbol

import (
	blake2b "github.com/minio/blake2b-simd"
	"github.com/zchee/clang-server/internal/hashutil"
)

// ID id of cursor.USR with blake2b hash.
type ID [blake2b.Size]byte

func (id ID) String() string {
	return hashutil.EncodeToString(id)
}

// Bytes reterun the ID byte slice.
func (id ID) Bytes() []byte {
	return id[:]
}

// IsEmpty reports whether id is empty.
func (id ID) IsEmpty() bool {
	return len(id) == 0
}

// FileID id of filename with blake2b hash.
type FileID [blake2b.Size]byte

func (id FileID) String() string {
	return hashutil.EncodeToString(id)
}

// Bytes reterun the FileID byte slice.
func (id FileID) Bytes() []byte {
	return id[:]
}

// IsEmpty reports whether id is empty.
func (id FileID) IsEmpty() bool {
	return len(id) == 0
}

// ToID converts the string to blake2b sum512 hash.
func ToID(s string) ID {
	return hashutil.NewHashString(s)
}

// ToFileID converts the string to blake2b sum512 hash.
func ToFileID(s string) FileID {
	return hashutil.NewHashString(s)
}
<|endoftext|>


<commit_before>package kafka

import (
	l "log"
	"os"
	"sync"

	"github.com/Shopify/sarama"
	"github.com/funkygao/gafka/cmd/kateway/store"
	"github.com/funkygao/gafka/ctx"
	"github.com/funkygao/golib/color"
	log "github.com/funkygao/log4go"
)

type subStore struct {
	shutdownCh   chan struct{}
	closedConnCh <-chan string // remote addr
	wg           *sync.WaitGroup
	hostname     string

	subManager *subManager
}

func NewSubStore(wg *sync.WaitGroup, closedConnCh <-chan string, debug bool) *subStore {
	if debug {
		sarama.Logger = l.New(os.Stdout, color.Blue("[Sarama]"),
			l.LstdFlags|l.Lshortfile)
	}

	return &subStore{
		hostname:     ctx.Hostname(),
		wg:           wg,
		shutdownCh:   make(chan struct{}),
		closedConnCh: closedConnCh,
	}
}

func (this *subStore) Name() string {
	return "kafka"
}

func (this *subStore) Start() (err error) {
	this.wg.Add(1)

	this.subManager = newSubManager()

	go func() {
		defer this.wg.Done()

		var remoteAddr string
		for {
			select {
			case <-this.shutdownCh:
				log.Trace("sub store[%s] stopped", this.Name())
				return

			case remoteAddr = <-this.closedConnCh:
				go this.subManager.killClient(remoteAddr)

			}
		}
	}()

	return
}

func (this *subStore) Stop() {
	this.subManager.Stop()
	close(this.shutdownCh)
}

func (this *subStore) Fetch(cluster, topic, group, remoteAddr, realIp,
	resetOffset string, permitStandby bool) (store.Fetcher, error) {
	cg, err := this.subManager.PickConsumerGroup(cluster, topic, group, remoteAddr, realIp, resetOffset, permitStandby)
	if err != nil {
		return nil, err
	}

	return &consumerFetcher{
		ConsumerGroup: cg,
		remoteAddr:    remoteAddr,
		store:         this,
	}, nil
}

func (this *subStore) IsSystemError(err error) bool {
	switch err {
	case store.ErrTooManyConsumers:
		return false

	default:
		return true
	}
}
<commit_msg>consumergroup.ErrTooManyConsumers is not system error<commit_after>package kafka

import (
	l "log"
	"os"
	"sync"

	"github.com/Shopify/sarama"
	"github.com/funkygao/gafka/cmd/kateway/store"
	"github.com/funkygao/gafka/ctx"
	"github.com/funkygao/golib/color"
	"github.com/funkygao/kafka-cg/consumergroup"
	log "github.com/funkygao/log4go"
)

type subStore struct {
	shutdownCh   chan struct{}
	closedConnCh <-chan string // remote addr
	wg           *sync.WaitGroup
	hostname     string

	subManager *subManager
}

func NewSubStore(wg *sync.WaitGroup, closedConnCh <-chan string, debug bool) *subStore {
	if debug {
		sarama.Logger = l.New(os.Stdout, color.Blue("[Sarama]"),
			l.LstdFlags|l.Lshortfile)
	}

	return &subStore{
		hostname:     ctx.Hostname(),
		wg:           wg,
		shutdownCh:   make(chan struct{}),
		closedConnCh: closedConnCh,
	}
}

func (this *subStore) Name() string {
	return "kafka"
}

func (this *subStore) Start() (err error) {
	this.wg.Add(1)

	this.subManager = newSubManager()

	go func() {
		defer this.wg.Done()

		var remoteAddr string
		for {
			select {
			case <-this.shutdownCh:
				log.Trace("sub store[%s] stopped", this.Name())
				return

			case remoteAddr = <-this.closedConnCh:
				go this.subManager.killClient(remoteAddr)

			}
		}
	}()

	return
}

func (this *subStore) Stop() {
	this.subManager.Stop()
	close(this.shutdownCh)
}

func (this *subStore) Fetch(cluster, topic, group, remoteAddr, realIp,
	resetOffset string, permitStandby bool) (store.Fetcher, error) {
	cg, err := this.subManager.PickConsumerGroup(cluster, topic, group, remoteAddr, realIp, resetOffset, permitStandby)
	if err != nil {
		return nil, err
	}

	return &consumerFetcher{
		ConsumerGroup: cg,
		remoteAddr:    remoteAddr,
		store:         this,
	}, nil
}

func (this *subStore) IsSystemError(err error) bool {
	switch err {
	case consumergroup.ErrTooManyConsumers, store.ErrTooManyConsumers:
		return false

	default:
		return true
	}
}
<|endoftext|>


<commit_before>package mc

import (
	"fmt"
	"path/filepath"
	"strings"

	"github.com/jmoiron/sqlx"
	"github.com/materials-commons/gohandy/file"
	"github.com/materials-commons/mcstore/pkg/app"
)

type sqlProjectDBOpener struct {
	configer Configer
}

var ProjectOpener sqlProjectDBOpener = sqlProjectDBOpener{
	configer: NewOSUserConfiger(),
}

func (p sqlProjectDBOpener) CreateProjectDB(dbSpec ProjectDBSpec) (ProjectDB, error) {
	dirPath := p.configer.ConfigDir()
	dbFilePath := filepath.Join(dirPath, dbSpec.Name+".db")

	if err := validateDBPaths(dirPath, dbFilePath); err != nil {
		return nil, err
	}

	if db, err := p.openSqlDB(dbFilePath); err != nil {
		return nil, err
	} else {
		return p.loadDB(db, dbSpec)
	}
}

func validateDBPaths(dirPath, dbFilePath string) error {
	switch {
	case !file.Exists(dirPath):
		return app.ErrNotFound
	case file.Exists(dbFilePath):
		return app.ErrExists
	default:
		return nil
	}
}

// openDB will attempt to open the project.db file.
func (p sqlProjectDBOpener) openSqlDB(dbpath string) (*sqlx.DB, error) {
	dbargs := fmt.Sprintf("file:%s?cached=shared&mode=rwc", dbpath)
	db, err := sqlx.Open("sqlite3", dbargs)
	if err != nil {
		return nil, err
	}
	return db, nil
}

func (p sqlProjectDBOpener) loadDB(db *sqlx.DB, dbSpec ProjectDBSpec) (*sqlProjectDB, error) {
	if err := createSchema(db); err != nil {
		db.Close()
		return nil, err
	}

	proj := &Project{
		ProjectID: dbSpec.ProjectID,
		Name:      dbSpec.Name,
		Path:      dbSpec.Path,
	}

	projectdb := &sqlProjectDB{
		db: db,
	}

	if _, err := projectdb.insertProject(proj); err != nil {
		db.Close()
		return nil, err
	}

	return projectdb, nil
}

func (p sqlProjectDBOpener) OpenProjectDB(name string) (ProjectDB, error) {
	dirPath := p.configer.ConfigDir()
	dbFilePath := filepath.Join(dirPath, name+".db")

	if !file.Exists(dbFilePath) {
		return nil, app.ErrNotFound
	}

	if db, err := p.openSqlDB(dbFilePath); err != nil {
		return nil, err
	} else {
		proj := &sqlProjectDB{
			db: db,
		}
		return proj, nil
	}
}

func (p sqlProjectDBOpener) PathToName(path string) string {
	dbfile := filepath.Base(path)
	lastDot := strings.LastIndex(dbfile, ".")

	// Remove extension if it exists
	if lastDot == -1 {
		return dbfile
	}
	return dbfile[:lastDot]
}
<commit_msg>Add ProjectExists command to check for project existence.<commit_after>package mc

import (
	"fmt"
	"path/filepath"
	"strings"

	"github.com/jmoiron/sqlx"
	"github.com/materials-commons/gohandy/file"
	"github.com/materials-commons/mcstore/pkg/app"
)

type sqlProjectDBOpener struct {
	configer Configer
}

var ProjectOpener sqlProjectDBOpener = sqlProjectDBOpener{
	configer: NewOSUserConfiger(),
}

func (p sqlProjectDBOpener) ProjectExists(name string) bool {
	dirPath := p.configer.ConfigDir()
	dbFilePath := filepath.Join(dirPath, name+".db")
	return file.Exists(dbFilePath)
}

func (p sqlProjectDBOpener) CreateProjectDB(dbSpec ProjectDBSpec) (ProjectDB, error) {
	dirPath := p.configer.ConfigDir()
	dbFilePath := filepath.Join(dirPath, dbSpec.Name+".db")

	if err := validateDBPaths(dirPath, dbFilePath); err != nil {
		return nil, err
	}

	if db, err := p.openSqlDB(dbFilePath); err != nil {
		return nil, err
	} else {
		return p.loadDB(db, dbSpec)
	}
}

func validateDBPaths(dirPath, dbFilePath string) error {
	switch {
	case !file.Exists(dirPath):
		return app.ErrNotFound
	case file.Exists(dbFilePath):
		return app.ErrExists
	default:
		return nil
	}
}

// openDB will attempt to open the project.db file.
func (p sqlProjectDBOpener) openSqlDB(dbpath string) (*sqlx.DB, error) {
	dbargs := fmt.Sprintf("file:%s?cached=shared&mode=rwc", dbpath)
	db, err := sqlx.Open("sqlite3", dbargs)
	if err != nil {
		return nil, err
	}
	return db, nil
}

func (p sqlProjectDBOpener) loadDB(db *sqlx.DB, dbSpec ProjectDBSpec) (*sqlProjectDB, error) {
	if err := createSchema(db); err != nil {
		db.Close()
		return nil, err
	}

	proj := &Project{
		ProjectID: dbSpec.ProjectID,
		Name:      dbSpec.Name,
		Path:      dbSpec.Path,
	}

	projectdb := &sqlProjectDB{
		db: db,
	}

	if _, err := projectdb.insertProject(proj); err != nil {
		db.Close()
		return nil, err
	}

	return projectdb, nil
}

func (p sqlProjectDBOpener) OpenProjectDB(name string) (ProjectDB, error) {
	dirPath := p.configer.ConfigDir()
	dbFilePath := filepath.Join(dirPath, name+".db")

	if !file.Exists(dbFilePath) {
		return nil, app.ErrNotFound
	}

	if db, err := p.openSqlDB(dbFilePath); err != nil {
		return nil, err
	} else {
		proj := &sqlProjectDB{
			db: db,
		}
		return proj, nil
	}
}

func (p sqlProjectDBOpener) PathToName(path string) string {
	dbfile := filepath.Base(path)
	lastDot := strings.LastIndex(dbfile, ".")

	// Remove extension if it exists
	if lastDot == -1 {
		return dbfile
	}
	return dbfile[:lastDot]
}
<|endoftext|>


<commit_before>package commands

import (
	"fmt"

	"github.com/spf13/cobra"

	nm "github.com/tendermint/tendermint/node"
)

// AddNodeFlags exposes some common configuration options on the command-line
// These are exposed for convenience of commands embedding a tendermint node
func AddNodeFlags(cmd *cobra.Command) {
	// bind flags
	cmd.Flags().String("moniker", config.Moniker, "Node Name")

	// priv val flags
	cmd.Flags().String("priv_validator_addr", config.PrivValidatorAddr, "Socket address for PrivValidator")

	// node flags
	cmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing")

	// abci flags
	cmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or 'nilapp' or 'dummy' for local testing.")
	cmd.Flags().String("abci", config.ABCI, "Specify abci transport (socket | grpc)")

	// rpc flags
	cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required")
	cmd.Flags().String("rpc.grpc_laddr", config.RPC.GRPCListenAddress, "GRPC listen address (BroadcastTx only). Port required")
	cmd.Flags().Bool("rpc.unsafe", config.RPC.Unsafe, "Enabled unsafe rpc methods")

	// p2p flags
	cmd.Flags().String("p2p.laddr", config.P2P.ListenAddress, "Node listen address. (0.0.0.0:0 means any interface, any port)")
	cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma delimited host:port seed nodes")
	cmd.Flags().String("p2p.persistent_peers", config.P2P.PersistentPeers, "Comma delimited host:port persistent peers")
	cmd.Flags().Bool("p2p.skip_upnp", config.P2P.SkipUPNP, "Skip UPNP configuration")
	cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable/disable Peer-Exchange")
	cmd.Flags().Bool("p2p.seed_mode", config.P2P.SeedMode, "Enable/disable seed mode")

	// consensus flags
	cmd.Flags().Bool("consensus.create_empty_blocks", config.Consensus.CreateEmptyBlocks, "Set this to false to only produce blocks when there are txs or when the AppHash changes")
}

// NewRunNodeCmd returns the command that allows the CLI to start a
// node. It can be used with a custom PrivValidator and in-process ABCI application.
func NewRunNodeCmd(nodeProvider nm.NodeProvider) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "node",
		Short: "Run the tendermint node",
		RunE: func(cmd *cobra.Command, args []string) error {
			// Create & start node
			n, err := nodeProvider(config, logger)
			if err != nil {
				return fmt.Errorf("Failed to create node: %v", err)
			}

			if err := n.Start(); err != nil {
				return fmt.Errorf("Failed to start node: %v", err)
			} else {
				logger.Info("Started node", "nodeInfo", n.Switch().NodeInfo())
			}

			// Trap signal, run forever.
			n.RunForever()

			return nil
		},
	}

	AddNodeFlags(cmd)
	return cmd
}
<commit_msg>Correct config description<commit_after>package commands

import (
	"fmt"

	"github.com/spf13/cobra"

	nm "github.com/tendermint/tendermint/node"
)

// AddNodeFlags exposes some common configuration options on the command-line
// These are exposed for convenience of commands embedding a tendermint node
func AddNodeFlags(cmd *cobra.Command) {
	// bind flags
	cmd.Flags().String("moniker", config.Moniker, "Node Name")

	// priv val flags
	cmd.Flags().String("priv_validator_addr", config.PrivValidatorAddr, "Socket address for private validator")

	// node flags
	cmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing")

	// abci flags
	cmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or 'nilapp' or 'dummy' for local testing.")
	cmd.Flags().String("abci", config.ABCI, "Specify abci transport (socket | grpc)")

	// rpc flags
	cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required")
	cmd.Flags().String("rpc.grpc_laddr", config.RPC.GRPCListenAddress, "GRPC listen address (BroadcastTx only). Port required")
	cmd.Flags().Bool("rpc.unsafe", config.RPC.Unsafe, "Enabled unsafe rpc methods")

	// p2p flags
	cmd.Flags().String("p2p.laddr", config.P2P.ListenAddress, "Node listen address. (0.0.0.0:0 means any interface, any port)")
	cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma delimited host:port seed nodes")
	cmd.Flags().String("p2p.persistent_peers", config.P2P.PersistentPeers, "Comma delimited host:port persistent peers")
	cmd.Flags().Bool("p2p.skip_upnp", config.P2P.SkipUPNP, "Skip UPNP configuration")
	cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable/disable Peer-Exchange")
	cmd.Flags().Bool("p2p.seed_mode", config.P2P.SeedMode, "Enable/disable seed mode")

	// consensus flags
	cmd.Flags().Bool("consensus.create_empty_blocks", config.Consensus.CreateEmptyBlocks, "Set this to false to only produce blocks when there are txs or when the AppHash changes")
}

// NewRunNodeCmd returns the command that allows the CLI to start a
// node. It can be used with a custom PrivValidator and in-process ABCI application.
func NewRunNodeCmd(nodeProvider nm.NodeProvider) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "node",
		Short: "Run the tendermint node",
		RunE: func(cmd *cobra.Command, args []string) error {
			// Create & start node
			n, err := nodeProvider(config, logger)
			if err != nil {
				return fmt.Errorf("Failed to create node: %v", err)
			}

			if err := n.Start(); err != nil {
				return fmt.Errorf("Failed to start node: %v", err)
			} else {
				logger.Info("Started node", "nodeInfo", n.Switch().NodeInfo())
			}

			// Trap signal, run forever.
			n.RunForever()

			return nil
		},
	}

	AddNodeFlags(cmd)
	return cmd
}
<|endoftext|>


<commit_before>/*
Package telsh provides "middleware" (for the telnet package) that can be used to implement a TELNET server
that provides a "shell" interface.

Shell interfaces you may be familiar with include: "bash", "csh", "sh", "zsk", etc.

TELNET Server

Here is an example usage:

	package main

	import (
		"github.com/reiver/go-oi"
		"github.com/reiver/go-telnet"
		"github.com/reiver/go-telnet/telsh"

		"io"
	)

	func main() {

		telnetHandler := telsh.NewShellHandler()

		if err := telnetHandler.RegisterElse(
			telsh.ProducerFunc(
				func(ctx telsh.Context, name string, args ...string) telsh.Handler {
					return telsh.PromoteHandlerFunc(
						func(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
							oi.LongWrite(stdout, []byte{'w','a','t','?', '\r','\n'})

							return nil
						},
					)
				},
			),
		); nil != err {
			panic(err)
		}

		if err := telnetHandler.Register("help",
			telsh.ProducerFunc(
				func(ctx telsh.Context, name string, args ...string) telsh.Handler {
				return telsh.PromoteHandlerFunc(
						func(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
							oi.LongWrite(stdout, []byte{'r','t','f','m','!', '\r','\n'})

							return nil
						},
					)
				},
			),
		); nil != err {
			panic(err)
		}

		err := telnet.ListenAndServe(":5555", telnetHandler)
		if nil != err {
			//@TODO: Handle this error better.
			panic(err)
		}
	}

Here is a more "unpacked" example:

	package main

	import (
		"github.com/reiver/go-oi"
		"github.com/reiver/go-telnet"
		"github.com/reiver/go-telnet/telsh"

		"fmt"
		"io"
		"time"
	)

	var (
		shellHandler := telsh.NewShellHandler()
	)

	func init() {

		shellHandler.Register("dance", telsh.ProducerFunc(producer))

		shellHandler.WelcomeMessage = `
	 __          __ ______  _        _____   ____   __  __  ______
	 \ \        / /|  ____|| |      / ____| / __ \ |  \/  ||  ____|
	  \ \  /\  / / | |__   | |     | |     | |  | || \  / || |__
	   \ \/  \/ /  |  __|  | |     | |     | |  | || |\/| ||  __|
	    \  /\  /   | |____ | |____ | |____ | |__| || |  | || |____
	     \/  \/    |______||______| \_____| \____/ |_|  |_||______|

	`
	}

	func producer(ctx telsh.Context, name string, args ...string) telsh.Handler{
		return telsh.PromoteHandlerFunc(handler)
	}

	func handler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
		for i:=0; i<20; i++ {
			oi.LongWriteString(stdout, "\r⠋")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠙")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠹")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠸")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠼")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠴")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠦")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠧")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠇")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠏")
			time.Sleep(50*time.Millisecond)
		}
		oi.LongWriteString(stdout, "\r \r\n")

		return nil
	}

	func main() {

		addr := ":5555"
		if err := telnet.ListenAndServe(addr, shellHandler); nil != err {
			panic(err)
		}
	}

*/
package telsh
<commit_msg>updated docs<commit_after>/*
Package telsh provides "middleware" (for the telnet package) that can be used to implement a TELNET or TELNETS server
that provides a "shell" interface (also known as a "command-line interface" or "CLI").

Shell interfaces you may be familiar with include: "bash", "csh", "sh", "zsk", etc.

TELNET Server

Here is an example usage:

	package main

	import (
		"github.com/reiver/go-oi"
		"github.com/reiver/go-telnet"
		"github.com/reiver/go-telnet/telsh"

		"io"
	)

	func main() {

		telnetHandler := telsh.NewShellHandler()

		if err := telnetHandler.RegisterElse(
			telsh.ProducerFunc(
				func(ctx telsh.Context, name string, args ...string) telsh.Handler {
					return telsh.PromoteHandlerFunc(
						func(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
							oi.LongWrite(stdout, []byte{'w','a','t','?', '\r','\n'})

							return nil
						},
					)
				},
			),
		); nil != err {
			panic(err)
		}

		if err := telnetHandler.Register("help",
			telsh.ProducerFunc(
				func(ctx telsh.Context, name string, args ...string) telsh.Handler {
				return telsh.PromoteHandlerFunc(
						func(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
							oi.LongWrite(stdout, []byte{'r','t','f','m','!', '\r','\n'})

							return nil
						},
					)
				},
			),
		); nil != err {
			panic(err)
		}

		err := telnet.ListenAndServe(":5555", telnetHandler)
		if nil != err {
			//@TODO: Handle this error better.
			panic(err)
		}
	}

Here is a more "unpacked" example:

	package main

	import (
		"github.com/reiver/go-oi"
		"github.com/reiver/go-telnet"
		"github.com/reiver/go-telnet/telsh"

		"fmt"
		"io"
		"time"
	)

	var (
		shellHandler := telsh.NewShellHandler()
	)

	func init() {

		shellHandler.Register("dance", telsh.ProducerFunc(producer))

		shellHandler.WelcomeMessage = `
	 __          __ ______  _        _____   ____   __  __  ______
	 \ \        / /|  ____|| |      / ____| / __ \ |  \/  ||  ____|
	  \ \  /\  / / | |__   | |     | |     | |  | || \  / || |__
	   \ \/  \/ /  |  __|  | |     | |     | |  | || |\/| ||  __|
	    \  /\  /   | |____ | |____ | |____ | |__| || |  | || |____
	     \/  \/    |______||______| \_____| \____/ |_|  |_||______|

	`
	}

	func producer(ctx telsh.Context, name string, args ...string) telsh.Handler{
		return telsh.PromoteHandlerFunc(handler)
	}

	func handler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
		for i:=0; i<20; i++ {
			oi.LongWriteString(stdout, "\r⠋")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠙")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠹")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠸")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠼")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠴")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠦")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠧")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠇")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠏")
			time.Sleep(50*time.Millisecond)
		}
		oi.LongWriteString(stdout, "\r \r\n")

		return nil
	}

	func main() {

		addr := ":5555"
		if err := telnet.ListenAndServe(addr, shellHandler); nil != err {
			panic(err)
		}
	}

*/
package telsh
<|endoftext|>


<commit_before>package main

import (
	"html/template"
	"log"
	"path"
)

func loadTemplates(dir string) *template.Template {
	if dir == "" {
		return getTemplates()
	}
	log.Printf("using custom template directory %q", dir)
	t, err := template.New("").ParseFiles(path.Join(dir, "sign_in.html"), path.Join(dir, "error.html"))
	if err != nil {
		log.Fatalf("failed parsing template %s", err)
	}
	return t
}

func getTemplates() *template.Template {
	t, err := template.New("foo").Parse(`{{define "sign_in.html"}}
<!DOCTYPE html>

	<title>Sign In</title>
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

	<form method="GET" action="{{.ProxyPrefix}}/start">
	<input type="hidden" name="rd" value="{{.Redirect}}">
	{{ if .SignInMessage }}

{{.SignInMessage}}

	{{ end}}
	<button type="submit" class="btn">Sign in with {{.ProviderName}}</button>

	</form>

	{{ if .CustomLogin }}

	<form method="POST" action="{{.ProxyPrefix}}/sign_in">
		<input type="hidden" name="rd" value="{{.Redirect}}">
		Username:<input type="text" name="username" id="username" size="10">

		Password:<input type="password" name="password" id="password" size="10">

		<button type="submit" class="btn">Sign In</button>
	</form>

	{{ end }}

	{{ if eq .Footer "-" }}
	{{ else if eq .Footer ""}}
	Secured with OAuth2 Proxy version {{.Version}}
	{{ else }}
	{{.Footer}}
	{{ end }}

{{end}}`)
	if err != nil {
		log.Fatalf("failed parsing template %s", err)
	}

	t, err = t.Parse(`{{define "error.html"}}
<!DOCTYPE html>

	<title>{{.Title}}</title>
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

{{.Title}}

{{.Message}}

Sign In

{{end}}`)
	if err != nil {
		log.Fatalf("failed parsing template %s", err)
	}
	return t
}
<commit_msg>fix sign_in page url fragment after reload on Firefox<commit_after>package main

import (
	"html/template"
	"log"
	"path"
)

func loadTemplates(dir string) *template.Template {
	if dir == "" {
		return getTemplates()
	}
	log.Printf("using custom template directory %q", dir)
	t, err := template.New("").ParseFiles(path.Join(dir, "sign_in.html"), path.Join(dir, "error.html"))
	if err != nil {
		log.Fatalf("failed parsing template %s", err)
	}
	return t
}

func getTemplates() *template.Template {
	t, err := template.New("foo").Parse(`{{define "sign_in.html"}}
<!DOCTYPE html>

	<title>Sign In</title>
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

	<form method="GET" action="{{.ProxyPrefix}}/start">
	<input type="hidden" name="rd" value="{{.Redirect}}">
	{{ if .SignInMessage }}

{{.SignInMessage}}

	{{ end}}
	<button type="submit" class="btn">Sign in with {{.ProviderName}}</button>

	</form>

	{{ if .CustomLogin }}

	<form method="POST" action="{{.ProxyPrefix}}/sign_in">
		<input type="hidden" name="rd" value="{{.Redirect}}">
		Username:<input type="text" name="username" id="username" size="10">

		Password:<input type="password" name="password" id="password" size="10">

		<button type="submit" class="btn">Sign In</button>
	</form>

	{{ end }}

	{{ if eq .Footer "-" }}
	{{ else if eq .Footer ""}}
	Secured with OAuth2 Proxy version {{.Version}}
	{{ else }}
	{{.Footer}}
	{{ end }}

{{end}}`)
	if err != nil {
		log.Fatalf("failed parsing template %s", err)
	}

	t, err = t.Parse(`{{define "error.html"}}
<!DOCTYPE html>

	<title>{{.Title}}</title>
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

{{.Title}}

{{.Message}}

Sign In

{{end}}`)
	if err != nil {
		log.Fatalf("failed parsing template %s", err)
	}
	return t
}
<|endoftext|>


<commit_before>// Represent and unify Prolog terms.  Along with golog.Machine, term.Term
// is one of the most important data types in Golog.  It provides a Go
// representation of Prolog terms.  Terms represent Prolog code,
// Prolog queries and Prolog results.
//
// The current term API is messy and will definitely change in the future.
package term

import . "fmt"
import . "regexp"
import "hash/fnv"
import "math"
import "strconv"
import "strings"
import "github.com/mndrix/golog/lex"
import "github.com/mndrix/ps"

// Returned by Unify() if the unification fails
var CantUnify error = Errorf("Can't unify the given terms")

// Term represents a single Prolog term which might be an atom, a
// compound structure, an integer, etc.  Many methods on Term will
// be replaced with functions in the future.  The Term interface is
// also likely to be split into several smaller interfaces like Atomic,
// Number, etc.
type Term interface {
    // Functor returns the term's name
    Functor() string

    // Arity returns the number of arguments a term has. An atom has 0 arity.
    Arity() int

    // Arguments returns a slice of this term's arguments, if any
    Arguments() []Term

    // Body returns a term's second argument; otherwise, panics
    Body() Term

    // Head returns a term's first argument; otherwise, panics
    Head() Term

    // Error returns an error value if this is an error term
    Error() error

    // IsClause returns true if the term is like 'Head :- Body'
    IsClause() bool

    // ReplaceVariables replaces any internal variables with the values
    // to which they're bound.  Unbound variables are left as they are
    ReplaceVariables(Bindings) Term

    // String provides a string representation of a term
    String() string

    // Indicator() provides a "predicate indicator" representation of a term
    Indicator() string

    // Unifies the invocant and another term in the presence of an
    // environment.
    // On succes, returns a new environment with additional variable
    // bindings.  On failure, returns CantUnify error along with the
    // original environment
    Unify(Bindings, Term) (Bindings, error)
}

// Returns true if term t is an atom
func IsAtom(t Term) bool {
    switch t.(type) {
        case *Atom:
            return true
        default:
            return false
    }
    panic("Impossible")
}

// Returns true if term t is a compound term.
func IsCompound(t Term) bool {
    switch t.(type) {
        case *Compound:
            return true
        case *Atom,
             *Variable,
             *Integer,
             *Float,
             *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is a variable.
func IsVariable(t Term) bool {
    switch t.(type) {
        case *Variable:
            return true
        case *Atom,
             *Compound,
             *Integer,
             *Float,
             *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is an error term.
func IsError(t Term) bool {
    switch t.(type) {
        case *Error:
            return true
        case *Atom,
             *Compound,
             *Variable,
             *Integer,
             *Float:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is a directive like `:- foo.`
func IsDirective(t Term) bool {
    return t.Indicator() == ":-/1"
}

// Returns true if term t is an integer
func IsInteger(t Term) bool {
    switch t.(type) {
        case *Compound:
            return false
        case *Variable:
            return false
        case *Integer:
            return true
        case *Float:
            return false
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is an floating point number
func IsFloat(t Term) bool {
    switch t.(type) {
        case *Compound:
            return false
        case *Variable:
            return false
        case *Integer:
            return false
        case *Float:
            return true
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// RenameVariables returns a new term like t with all variables replaced
// by fresh ones.
func RenameVariables(t Term) Term {
    renamed := make(map[string]*Variable)
    return renameVariables(t, renamed)
}

func renameVariables(t Term, renamed map[string]*Variable) Term {
    switch x := t.(type) {
        case *Float:    return x
        case *Integer:  return x
        case *Error:    return x
        case *Atom:     return x
        case *Compound:
            newArgs := make([]Term, x.Arity())
            for i, arg := range x.Arguments() {
                newArgs[i] = renameVariables(arg, renamed)
            }
            return NewTerm(x.Functor(), newArgs...)
        case *Variable:
            name := x.Name
            v, ok := renamed[name]
            if ok {
                return v
            } else {
                v = x.WithNewId()
                renamed[name] = v
                return v
            }
    }
    panic("Unexpected term implementation")
}

// Variables returns a ps.Map whose keys are human-readable variable names
// and those values are *Variable used inside term t.
func Variables(t Term) ps.Map {
    names := ps.NewMap()
    switch x := t.(type) {
        case *Atom:     return names
        case *Float:    return names
        case *Integer:  return names
        case *Error:    return names
        case *Compound:
            if x.Arity() == 0 { return names }  // no variables in an atom
            for _, arg := range x.Arguments() {
                innerNames := Variables(arg)
                innerNames.ForEach(func (key string, val ps.Any) {
                    names = names.Set(key, val)
                })
            }
            return names
        case *Variable:
            return names.Set(x.Name, x)
    }
    panic("Unexpected term implementation")
}

// QuoteFunctor returns a canonical representation of a term's name
// by quoting characters that require quoting
func QuoteFunctor(name string) string {
    // cons must be quoted (to avoid confusion with full stop)
    if name == "." || name == "" {
        return Sprintf("'%s'", name)
    }

    // names composed entirely of graphic characters need no quoting
    allGraphic := true
    for _, c := range name {
        if !lex.IsGraphic(c) {
            allGraphic = false
            break
        }
    }
    if allGraphic || name == "[]" || name == "!" || name == ";" {
        return name
    }

    nonAlpha, err := MatchString(`\W`, name)
    maybePanic(err)
    nonLower, err := MatchString(`^[^a-z]`, name)
    if nonAlpha || nonLower {
        escapedName := strings.Replace(name, `'`, `\'`, -1)
        return Sprintf("'%s'", escapedName)
    }

    return name
}

// NewCodeList constructs a list of character codes from a string.
// The string should include opening and closing " characters.
// Nominally, the resulting term is just a chain of cons cells ('.'/2),
// but it might actually be a more efficient implementation under the hood.
func NewCodeListFromDoubleQuotedString(s string) Term {
    // make sure the content is long enough
    runes := []rune(s)
    end := len(runes) - 2
    if end < 0 {
        msg := Sprintf("Code list string must have bracketing double quotes: %s", s)
        panic(msg)
    }

    // build a cons cell chain, starting at the end ([])
    codes := NewAtom(`[]`)
    for i := end; i > 0; i-- {
        c := NewCode(runes[i])
        codes = NewTerm(`.`, c, codes)
    }

    return codes
}

// Precedes returns true if the first argument 'term-precedes'
// the second argument according to ISO §7.2
func Precedes(a, b Term) bool {
    aP := precedence(a)
    bP := precedence(b)
    if aP < bP { return true }
    if aP > bP { return false }

    // both terms have the same precedence by type, so delve deeper
    switch x := a.(type) {
        case *Variable:
            y := b.(*Variable)
            return x.Id() < y.Id()
        case *Float:
            y := b.(*Float)
            return x.Value() < y.Value()
        case *Integer:
            y := b.(*Integer)
            return x.Value().Cmp(y.Value()) < 0
        case *Atom:
            y := b.(*Atom)
            return x.Functor() < y.Functor()
        case *Compound:
            y := b.(*Compound)
            if x.Arity() < y.Arity() { return true }
            if x.Arity() > y.Arity() { return false }
            if x.Functor() < y.Functor() { return true }
            if x.Functor() > y.Functor() { return false }
            for i:=0; i<x.Arity(); i++ {
                if Precedes(x.Arguments()[i], y.Arguments()[i]) {
                    return true
                } else if Precedes(y.Arguments()[i], x.Arguments()[i]) {
                    return false
                }
            }
            return false    // identical terms
    }

    msg := Sprintf("Unexpected term type %s\n", a)
    panic(msg)
}
func precedence(t Term) int {
    switch t.(type) {
        case *Variable:
            return 0
        case *Float:
            return 1
        case *Integer:
            return 2
        case *Atom:
            return 3
        case *Compound:
            return 4
    }
    msg := Sprintf("Unexpected term type %s\n", t)
    panic(msg)
}

// UnificationHash generates a special hash value representing the
// terms in a slice.  Golog uses these hashes to optimize
// unification.  You probably don't need to call this function directly.
//
// In more detail, UnificationHash generates a 64-bit hash which
// represents the shape and content of a term.  If two terms share the same
// hash, those terms are likely to unify, although not guaranteed.  If
// two terms have different hashes, the two terms are guaranteed not
// to unify.  A compound term splits its 64-bit hash into multiple, smaller
// n-bit hashes for its functor and arguments.  Other terms occupy the entire
// hash space themselves.
//
// Variables require special handling.  During "preparation" we can think of
// 1-bits as representing what content a term "provides".  During "query" we
// can think of 1-bits as representing what content a term "requires".
// In the first phase, a variable hashes to all 1s since it can provide
// whatever is needed.  In the second phase, a variable hashes to all 0s since
// it demands nothing of the opposing term.
func UnificationHash(terms []Term, n uint, preparation bool) uint64 {
    var hash uint64 = 0
    var blockSize uint = n / uint(len(terms))

    // mask to select blockSize least significant bits
    var mask uint64
    if blockSize == 64 {
        mask = math.MaxUint64
    } else if blockSize == 0 {
        // pretend that terms was a single variable
        if preparation {
            return (1 << n) - 1
        } else {
            return 0
        }
    } else {
        mask = (1 << blockSize) - 1
    }

    for _, term := range terms {
        hash = hash << blockSize
        switch t := term.(type) {
            case *Atom:
                hash = hash | (hashString(t.Functor()) & mask)
            case *Integer:
                str := Sprintf("%x", t.Value())
                hash = hash | (hashString(str) & mask)
            case *Float:
                str := strconv.FormatFloat(t.Value(), 'b', 0, 64)
                hash = hash | (hashString(str) & mask)
            case *Error:
                panic("No UnificationHash for Error terms")
            case *Compound:
                hash = hash | UnificationHash(t.Univ(), blockSize, preparation)
            case *Variable:
                if preparation {
                    hash = hash | mask
                }
            default:
                msg := Sprintf("Unexpected term type %s\n", t)
                panic(msg)
        }
    }

    return hash
}

// hashString returns a string's hash code
func hashString(x string) uint64 {
    hasher := fnv.New64()
    Fprint(hasher, x)
    return hasher.Sum64()
}

// Converts a '.'/2 list terminated in []/0 into a slice of the associated
// terms.  Panics if the argument is not a proper list.
func ProperListToTermSlice(t Term) []Term {
    l := make([]Term, 0)
    if !IsCompound(t) && !IsAtom(t) { panic("Not a list") }
    for {
        switch t.Indicator() {
            case "[]/0":
                return l
            case "./2":
                l = append(l, t.Arguments()[0])
                t = t.Arguments()[1]
            default:
                panic("Improper list")
        }
    }
    return l
}

// Implement sort.Interface for []Term
type TermSlice []Term
func (self *TermSlice) Len() int {
    ts := []Term(*self)
    return len(ts)
}
func (self *TermSlice) Less(i, j int) bool {
    ts := []Term(*self)
    return Precedes(ts[i], ts[j]);
}
func (self *TermSlice) Swap(i, j int) {
    ts := []Term(*self)
    tmp := ts[i]
    ts[i] = ts[j]
    ts[j] = tmp
}

func maybePanic(err error) {
    if err != nil {
        panic(err)
    }
}
<commit_msg>Preserve unification hashes across variable renaming<commit_after>// Represent and unify Prolog terms.  Along with golog.Machine, term.Term
// is one of the most important data types in Golog.  It provides a Go
// representation of Prolog terms.  Terms represent Prolog code,
// Prolog queries and Prolog results.
//
// The current term API is messy and will definitely change in the future.
package term

import . "fmt"
import . "regexp"
import "hash/fnv"
import "math"
import "strconv"
import "strings"
import "github.com/mndrix/golog/lex"
import "github.com/mndrix/ps"

// Returned by Unify() if the unification fails
var CantUnify error = Errorf("Can't unify the given terms")

// Term represents a single Prolog term which might be an atom, a
// compound structure, an integer, etc.  Many methods on Term will
// be replaced with functions in the future.  The Term interface is
// also likely to be split into several smaller interfaces like Atomic,
// Number, etc.
type Term interface {
    // Functor returns the term's name
    Functor() string

    // Arity returns the number of arguments a term has. An atom has 0 arity.
    Arity() int

    // Arguments returns a slice of this term's arguments, if any
    Arguments() []Term

    // Body returns a term's second argument; otherwise, panics
    Body() Term

    // Head returns a term's first argument; otherwise, panics
    Head() Term

    // Error returns an error value if this is an error term
    Error() error

    // IsClause returns true if the term is like 'Head :- Body'
    IsClause() bool

    // ReplaceVariables replaces any internal variables with the values
    // to which they're bound.  Unbound variables are left as they are
    ReplaceVariables(Bindings) Term

    // String provides a string representation of a term
    String() string

    // Indicator() provides a "predicate indicator" representation of a term
    Indicator() string

    // Unifies the invocant and another term in the presence of an
    // environment.
    // On succes, returns a new environment with additional variable
    // bindings.  On failure, returns CantUnify error along with the
    // original environment
    Unify(Bindings, Term) (Bindings, error)
}

// Returns true if term t is an atom
func IsAtom(t Term) bool {
    switch t.(type) {
        case *Atom:
            return true
        default:
            return false
    }
    panic("Impossible")
}

// Returns true if term t is a compound term.
func IsCompound(t Term) bool {
    switch t.(type) {
        case *Compound:
            return true
        case *Atom,
             *Variable,
             *Integer,
             *Float,
             *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is a variable.
func IsVariable(t Term) bool {
    switch t.(type) {
        case *Variable:
            return true
        case *Atom,
             *Compound,
             *Integer,
             *Float,
             *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is an error term.
func IsError(t Term) bool {
    switch t.(type) {
        case *Error:
            return true
        case *Atom,
             *Compound,
             *Variable,
             *Integer,
             *Float:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is a directive like `:- foo.`
func IsDirective(t Term) bool {
    return t.Indicator() == ":-/1"
}

// Returns true if term t is an integer
func IsInteger(t Term) bool {
    switch t.(type) {
        case *Compound:
            return false
        case *Variable:
            return false
        case *Integer:
            return true
        case *Float:
            return false
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// Returns true if term t is an floating point number
func IsFloat(t Term) bool {
    switch t.(type) {
        case *Compound:
            return false
        case *Variable:
            return false
        case *Integer:
            return false
        case *Float:
            return true
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// RenameVariables returns a new term like t with all variables replaced
// by fresh ones.
func RenameVariables(t Term) Term {
    renamed := make(map[string]*Variable)
    return renameVariables(t, renamed)
}

func renameVariables(t Term, renamed map[string]*Variable) Term {
    switch x := t.(type) {
        case *Float:    return x
        case *Integer:  return x
        case *Error:    return x
        case *Atom:     return x
        case *Compound:
            newArgs := make([]Term, x.Arity())
            for i, arg := range x.Arguments() {
                newArgs[i] = renameVariables(arg, renamed)
            }
            newTerm := NewTerm(x.Functor(), newArgs...)
            newTerm.(*Compound).ucache = x.ucache
            return newTerm
        case *Variable:
            name := x.Name
            v, ok := renamed[name]
            if ok {
                return v
            } else {
                v = x.WithNewId()
                renamed[name] = v
                return v
            }
    }
    panic("Unexpected term implementation")
}

// Variables returns a ps.Map whose keys are human-readable variable names
// and those values are *Variable used inside term t.
func Variables(t Term) ps.Map {
    names := ps.NewMap()
    switch x := t.(type) {
        case *Atom:     return names
        case *Float:    return names
        case *Integer:  return names
        case *Error:    return names
        case *Compound:
            if x.Arity() == 0 { return names }  // no variables in an atom
            for _, arg := range x.Arguments() {
                innerNames := Variables(arg)
                innerNames.ForEach(func (key string, val ps.Any) {
                    names = names.Set(key, val)
                })
            }
            return names
        case *Variable:
            return names.Set(x.Name, x)
    }
    panic("Unexpected term implementation")
}

// QuoteFunctor returns a canonical representation of a term's name
// by quoting characters that require quoting
func QuoteFunctor(name string) string {
    // cons must be quoted (to avoid confusion with full stop)
    if name == "." || name == "" {
        return Sprintf("'%s'", name)
    }

    // names composed entirely of graphic characters need no quoting
    allGraphic := true
    for _, c := range name {
        if !lex.IsGraphic(c) {
            allGraphic = false
            break
        }
    }
    if allGraphic || name == "[]" || name == "!" || name == ";" {
        return name
    }

    nonAlpha, err := MatchString(`\W`, name)
    maybePanic(err)
    nonLower, err := MatchString(`^[^a-z]`, name)
    if nonAlpha || nonLower {
        escapedName := strings.Replace(name, `'`, `\'`, -1)
        return Sprintf("'%s'", escapedName)
    }

    return name
}

// NewCodeList constructs a list of character codes from a string.
// The string should include opening and closing " characters.
// Nominally, the resulting term is just a chain of cons cells ('.'/2),
// but it might actually be a more efficient implementation under the hood.
func NewCodeListFromDoubleQuotedString(s string) Term {
    // make sure the content is long enough
    runes := []rune(s)
    end := len(runes) - 2
    if end < 0 {
        msg := Sprintf("Code list string must have bracketing double quotes: %s", s)
        panic(msg)
    }

    // build a cons cell chain, starting at the end ([])
    codes := NewAtom(`[]`)
    for i := end; i > 0; i-- {
        c := NewCode(runes[i])
        codes = NewTerm(`.`, c, codes)
    }

    return codes
}

// Precedes returns true if the first argument 'term-precedes'
// the second argument according to ISO §7.2
func Precedes(a, b Term) bool {
    aP := precedence(a)
    bP := precedence(b)
    if aP < bP { return true }
    if aP > bP { return false }

    // both terms have the same precedence by type, so delve deeper
    switch x := a.(type) {
        case *Variable:
            y := b.(*Variable)
            return x.Id() < y.Id()
        case *Float:
            y := b.(*Float)
            return x.Value() < y.Value()
        case *Integer:
            y := b.(*Integer)
            return x.Value().Cmp(y.Value()) < 0
        case *Atom:
            y := b.(*Atom)
            return x.Functor() < y.Functor()
        case *Compound:
            y := b.(*Compound)
            if x.Arity() < y.Arity() { return true }
            if x.Arity() > y.Arity() { return false }
            if x.Functor() < y.Functor() { return true }
            if x.Functor() > y.Functor() { return false }
            for i:=0; i<x.Arity(); i++ {
                if Precedes(x.Arguments()[i], y.Arguments()[i]) {
                    return true
                } else if Precedes(y.Arguments()[i], x.Arguments()[i]) {
                    return false
                }
            }
            return false    // identical terms
    }

    msg := Sprintf("Unexpected term type %s\n", a)
    panic(msg)
}
func precedence(t Term) int {
    switch t.(type) {
        case *Variable:
            return 0
        case *Float:
            return 1
        case *Integer:
            return 2
        case *Atom:
            return 3
        case *Compound:
            return 4
    }
    msg := Sprintf("Unexpected term type %s\n", t)
    panic(msg)
}

// UnificationHash generates a special hash value representing the
// terms in a slice.  Golog uses these hashes to optimize
// unification.  You probably don't need to call this function directly.
//
// In more detail, UnificationHash generates a 64-bit hash which
// represents the shape and content of a term.  If two terms share the same
// hash, those terms are likely to unify, although not guaranteed.  If
// two terms have different hashes, the two terms are guaranteed not
// to unify.  A compound term splits its 64-bit hash into multiple, smaller
// n-bit hashes for its functor and arguments.  Other terms occupy the entire
// hash space themselves.
//
// Variables require special handling.  During "preparation" we can think of
// 1-bits as representing what content a term "provides".  During "query" we
// can think of 1-bits as representing what content a term "requires".
// In the first phase, a variable hashes to all 1s since it can provide
// whatever is needed.  In the second phase, a variable hashes to all 0s since
// it demands nothing of the opposing term.
func UnificationHash(terms []Term, n uint, preparation bool) uint64 {
    var hash uint64 = 0
    var blockSize uint = n / uint(len(terms))

    // mask to select blockSize least significant bits
    var mask uint64
    if blockSize == 64 {
        mask = math.MaxUint64
    } else if blockSize == 0 {
        // pretend that terms was a single variable
        if preparation {
            return (1 << n) - 1
        } else {
            return 0
        }
    } else {
        mask = (1 << blockSize) - 1
    }

    for _, term := range terms {
        hash = hash << blockSize
        switch t := term.(type) {
            case *Atom:
                hash = hash | (hashString(t.Functor()) & mask)
            case *Integer:
                str := Sprintf("%x", t.Value())
                hash = hash | (hashString(str) & mask)
            case *Float:
                str := strconv.FormatFloat(t.Value(), 'b', 0, 64)
                hash = hash | (hashString(str) & mask)
            case *Error:
                panic("No UnificationHash for Error terms")
            case *Compound:
                hash = hash | UnificationHash(t.Univ(), blockSize, preparation)
            case *Variable:
                if preparation {
                    hash = hash | mask
                }
            default:
                msg := Sprintf("Unexpected term type %s\n", t)
                panic(msg)
        }
    }

    return hash
}

// hashString returns a string's hash code
func hashString(x string) uint64 {
    hasher := fnv.New64()
    Fprint(hasher, x)
    return hasher.Sum64()
}

// Converts a '.'/2 list terminated in []/0 into a slice of the associated
// terms.  Panics if the argument is not a proper list.
func ProperListToTermSlice(t Term) []Term {
    l := make([]Term, 0)
    if !IsCompound(t) && !IsAtom(t) { panic("Not a list") }
    for {
        switch t.Indicator() {
            case "[]/0":
                return l
            case "./2":
                l = append(l, t.Arguments()[0])
                t = t.Arguments()[1]
            default:
                panic("Improper list")
        }
    }
    return l
}

// Implement sort.Interface for []Term
type TermSlice []Term
func (self *TermSlice) Len() int {
    ts := []Term(*self)
    return len(ts)
}
func (self *TermSlice) Less(i, j int) bool {
    ts := []Term(*self)
    return Precedes(ts[i], ts[j]);
}
func (self *TermSlice) Swap(i, j int) {
    ts := []Term(*self)
    tmp := ts[i]
    ts[i] = ts[j]
    ts[j] = tmp
}

func maybePanic(err error) {
    if err != nil {
        panic(err)
    }
}
<|endoftext|>


<commit_before>package tern_test

import (
	"testing"

	"github.com/arteev/tern"
)

func TestOp(t *testing.T) {
	res := tern.Op(false, "Yes", "No")
	if res != "No" {
		t.Errorf("Excepted No,but %v", res)
	}

	res = tern.Op(true, "Yes", "No")
	if res != "Yes" {
		t.Errorf("Excepted Yes,but %v", res)
	}
}

func BenchmarkOp(b *testing.B) {
	for n:=0; n< b.N; n ++ {
		tern.Op(true, "Yes", "No")
	}
}

func doTestdecode(t *testing.T,vals map[int] interface{}, args... interface{}) {
	for key,pair := range vals {
		res := tern.Decode(key,args[0],args[1],args[2:]...)
		if res!=pair {
			t.Errorf("Excepted %v, got %v",pair,res)
		}
	}
}

func TestDecode(t *testing.T) {
	doTestdecode(t,map[int] interface{} {
		1:"one",
		0:nil,
	},1,"one")
	doTestdecode(t,map[int] interface{} {
		1:nil,
		0:nil,
	},2,"two")
	doTestdecode(t,map[int] interface{} {
		1:"one",
		2:"two",
		0:nil,
		100:nil,
	},1,"one",2,"two")
}

func BenchmarkDecode(b *testing.B){
	for n := 0; n < b.N; n++ {
		tern.Decode("test","test2","value3","test3","value3","test","tryvalue","default")
	}
}<commit_msg>test added<commit_after>package tern_test

import (
	"testing"

	"github.com/arteev/tern"
)

func TestOp(t *testing.T) {
	res := tern.Op(false, "Yes", "No")
	if res != "No" {
		t.Errorf("Excepted No,but %v", res)
	}

	res = tern.Op(true, "Yes", "No")
	if res != "Yes" {
		t.Errorf("Excepted Yes,but %v", res)
	}
}

func BenchmarkOp(b *testing.B) {
	for n:=0; n< b.N; n ++ {
		tern.Op(true, "Yes", "No")
	}
}

func doTestdecode(t *testing.T,vals map[int] interface{}, args... interface{}) {
	for key,pair := range vals {
		res := tern.Decode(key,args[0],args[1],args[2:]...)
		if res!=pair {
			t.Errorf("Excepted %v, got %v",pair,res)
		}
	}
}

func TestDecode(t *testing.T) {
	doTestdecode(t,map[int] interface{} {
		1:"one",
		0:nil,
	},1,"one")
	doTestdecode(t,map[int] interface{} {
		1:nil,
		0:nil,
	},2,"two")
	doTestdecode(t,map[int] interface{} {
		1:"one",
		2:"two",
		0:nil,
		100:nil,
	},1,"one",2,"two")

	doTestdecode(t,map[int] interface{} {
		1:nil,
		0:nil,
	},2,"two")

	doTestdecode(t,map[int] interface{} {
		1:nil,
	},2,"two",nil)
}

func BenchmarkDecode(b *testing.B){
	for n := 0; n < b.N; n++ {
		tern.Decode("test","test2","value3","test3","value3","test","tryvalue","default")
	}
}<|endoftext|>


<commit_before>package store_test

import (
	"io/ioutil"
	"os"
	"path"
	"testing"

	"github.com/wx13/genesis/store"
)

func TestStore(t *testing.T) {

	dir, err := ioutil.TempDir("", "genesis_test")
	if err != nil {
		t.Error("Could not create temp dir for testing purposes")
	}
	defer os.RemoveAll(dir)

	storeDir := path.Join(dir, "store")
	os.Mkdir(storeDir, 0755)
	s, err := store.New(storeDir)
	if err != nil {
		t.Error("Could not create store:", err)
	}

	filename := path.Join(dir, "myfile.txt")
	text := "This is line 1,\nand this is line two.\n\nNow line four.\n"
	ioutil.WriteFile(filename, []byte(text), 0644)

	s.SaveFile(filename, "")
	os.Remove(filename)
	s.RestoreFile(filename, "")

	data, err := ioutil.ReadFile(filename)
	if string(data) != text {
		t.Error("Restored file is not equal to original file.")
	}

	text2 := "This is line 27,\nand this is line owt.\n3\nNow line four.\n"
	s.SavePatch(filename, text, text2, "foo")
	ioutil.WriteFile(filename, []byte(text2), 0644)
	s.ApplyPatch(filename, "foo")
	data, err = ioutil.ReadFile(filename)
	if string(data) != text {
		t.Error("Patched file is not equal to original file.")
	}

}
<commit_msg>one more unit test<commit_after>package store_test

import (
	"io/ioutil"
	"os"
	"path"
	"testing"

	"github.com/wx13/genesis/store"
)

func TestHash(t *testing.T) {
	hash1 := store.Hash("hello", "bye", "yo")
	hash2 := store.Hash("hello", "bye", "yo")
	hash3 := store.Hash("hello", "bYe", "yo")
	if hash1 != hash2 || hash2 == hash3 {
		t.Error("Hashing is broken")
	}
}

func TestStore(t *testing.T) {

	// Create a temp directory for testing.
	dir, err := ioutil.TempDir("", "genesis_test")
	if err != nil {
		t.Error("Could not create temp dir for testing purposes")
	}
	defer os.RemoveAll(dir)

	// Generate a file for testing.
	filename := path.Join(dir, "myfile.txt")
	text := "This is line 1,\nand this is line two.\n\nNow line four.\n"
	ioutil.WriteFile(filename, []byte(text), 0644)

	// Create a new store.
	storeDir := path.Join(dir, "store")
	os.Mkdir(storeDir, 0755)
	s, err := store.New(storeDir)
	if err != nil {
		t.Error("Could not create store:", err)
	}

	// Save a snapshot, remove the file, and then restore it.
	s.SaveFile(filename, "")
	os.Remove(filename)
	s.RestoreFile(filename, "")

	// Test if restored file matches original.
	data, err := ioutil.ReadFile(filename)
	if string(data) != text {
		t.Error("Restored file is not equal to original file.")
	}

	// Modify the file to test patching.
	text2 := "This is line 27,\nand this is line owt.\n3\nNow line four.\n"
	s.SavePatch(filename, text, text2, "foo")
	ioutil.WriteFile(filename, []byte(text2), 0644)
	s.ApplyPatch(filename, "foo")
	data, err = ioutil.ReadFile(filename)
	if string(data) != text {
		t.Error("Patched file is not equal to original file.")
	}

}
<|endoftext|>