<commit_before>package board

import (
	"color"
	"matrix"
	"piece"
)

func (board Board) IsChecked(c color.Color) bool {
	var king matrix.Point
	for i := 0; i < 8; i++ {
		for j := 0; j < 8; j++ {
			symbol := board.Matrix[i][j]
			if piece.King.IsSymbol(symbol) && color.WhichColor(symbol) == c {
				king = matrix.Point{i, j}
				break
			}
		}
	}
	enemy := c.Enemy()
	enemies := board.Matrix.Positions(enemy)
	for _, i := range enemies {
		symbol := board.Matrix[i.Y][i.X]
		p := piece.WhichPiece(symbol)
		first := board.first[i.Y][i.X]
		var diff matrix.Point
		if c == color.White {
			diff = i.Diff(king)
		} else {
			diff = king.Diff(i)
		}

		canMove := p.CanMove(diff, first, true)
		existBarrier := board.Matrix.ExistBarrier(i, king)
		if canMove && (piece.Knight.IsSymbol(symbol) || existBarrier == false) {
			return true
		}
	}
	return false
}

func (board Board) IsCheckMate(c color.Color) bool {
	if board.IsChecked(c) == false {
		return false
	}

	friend := board.Matrix.Positions(c)
	movable := append(board.Matrix.Positions(color.Empty), board.Matrix.Positions(c.Enemy())...)

	for _, i := range movable {
		for _, j := range friend {
			fsymbol := board.Matrix[j.Y][j.X]
			tsymbol := board.Matrix[i.Y][i.X]
			tcolor := color.WhichColor(tsymbol)
			if tcolor == c || tcolor == color.Unknown {
				continue
			}

			piece := piece.WhichPiece(fsymbol)
			first := board.first[j.Y][j.X]
			var diff matrix.Point
			if c == color.White {
				diff = j.Diff(i)
			} else if c == color.Black {
				diff = i.Diff(j)
			}
			toEnemy := color.WhichColor(tsymbol) == c.Enemy()
			if piece.CanMove(diff, first, toEnemy) && board.Matrix.ExistBarrier(j, i) == false {
				board.Matrix[i.Y][i.X] = fsymbol
				board.Matrix[j.Y][j.X] = ' '
				if board.IsChecked(c) == false {
					board.Matrix[i.Y][i.X] = tsymbol
					board.Matrix[j.Y][j.X] = fsymbol
					return false
				}
				board.Matrix[i.Y][i.X] = tsymbol
				board.Matrix[j.Y][j.X] = fsymbol
			}
		}
	}
	return true
}
<commit_msg>Fix color check in IsChecked<commit_after>package board

import (
	"color"
	"matrix"
	"piece"
)

func (board Board) IsChecked(c color.Color) bool {
	var king matrix.Point
	for i := 0; i < 8; i++ {
		for j := 0; j < 8; j++ {
			symbol := board.Matrix[i][j]
			if piece.King.IsSymbol(symbol) && color.WhichColor(symbol) == c {
				king = matrix.Point{i, j}
				break
			}
		}
	}
	enemy := c.Enemy()
	enemies := board.Matrix.Positions(enemy)
	for _, i := range enemies {
		symbol := board.Matrix[i.Y][i.X]
		p := piece.WhichPiece(symbol)
		first := board.first[i.Y][i.X]
		var diff matrix.Point
		if enemy == color.White {
			diff = i.Diff(king)
		} else {
			diff = king.Diff(i)
		}

		canMove := p.CanMove(diff, first, true)
		existBarrier := board.Matrix.ExistBarrier(i, king)
		if canMove && (piece.Knight.IsSymbol(symbol) || existBarrier == false) {
			return true
		}
	}
	return false
}

func (board Board) IsCheckMate(c color.Color) bool {
	if board.IsChecked(c) == false {
		return false
	}

	friend := board.Matrix.Positions(c)
	movable := append(board.Matrix.Positions(color.Empty), board.Matrix.Positions(c.Enemy())...)

	for _, i := range movable {
		for _, j := range friend {
			fsymbol := board.Matrix[j.Y][j.X]
			tsymbol := board.Matrix[i.Y][i.X]
			tcolor := color.WhichColor(tsymbol)
			if tcolor == c || tcolor == color.Unknown {
				continue
			}

			piece := piece.WhichPiece(fsymbol)
			first := board.first[j.Y][j.X]
			var diff matrix.Point
			if c == color.White {
				diff = j.Diff(i)
			} else if c == color.Black {
				diff = i.Diff(j)
			}
			toEnemy := color.WhichColor(tsymbol) == c.Enemy()
			if piece.CanMove(diff, first, toEnemy) && board.Matrix.ExistBarrier(j, i) == false {
				board.Matrix[i.Y][i.X] = fsymbol
				board.Matrix[j.Y][j.X] = ' '
				if board.IsChecked(c) == false {
					board.Matrix[i.Y][i.X] = tsymbol
					board.Matrix[j.Y][j.X] = fsymbol
					return false
				}
				board.Matrix[i.Y][i.X] = tsymbol
				board.Matrix[j.Y][j.X] = fsymbol
			}
		}
	}
	return true
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"koding/tools/dnode"
	"koding/tools/kite"
	"koding/tools/log"
	"koding/tools/pty"
	"koding/tools/utils"
	"koding/virt"
	"strconv"
	"strings"
	"syscall"
	"time"
	"unicode/utf8"
)

type WebtermServer struct {
	Session          string `json:"session"`
	remote           WebtermRemote
	vm               *virt.VM
	user             *virt.User
	pty              *pty.PTY
	currentSecond    int64
	messageCounter   int
	byteCounter      int
	lineFeeedCounter int
}

type WebtermRemote struct {
	Output       dnode.Callback
	SessionEnded dnode.Callback
}

func registerWebtermMethods(k *kite.Kite) {
	registerVmMethod(k, "webterm.getSessions", false, func(args *dnode.Partial, channel *kite.Channel, vos *virt.VOS) (interface{}, error) {
		// We need to use ls here, because /var/run/screen mount is only visible from inside of container. Errors are ignored.
		out, _ := vos.VM.AttachCommand(vos.User.Uid, "", "ls", "/var/run/screen/S-"+vos.User.Name).Output()
		names := strings.Split(string(out[:len(out)-1]), "\n")
		sessions := make([]string, len(names))
		for i, name := range names {
			segements := strings.SplitN(name, ".", 2)
			sessions[i] = segements[1]
		}
		return sessions, nil
	})

	// this method is special cased in oskite.go to allow foreign access
	registerVmMethod(k, "webterm.connect", false, func(args *dnode.Partial, channel *kite.Channel, vos *virt.VOS) (interface{}, error) {
		var params struct {
			Remote       WebtermRemote
			Session      string
			SizeX, SizeY int
		}
		if args.Unmarshal(&params) != nil || params.SizeX <= 0 || params.SizeY <= 0 {
			return nil, &kite.ArgumentError{Expected: "{ remote: [object], session: [string], sizeX: [integer], sizeY: [integer] }"}
		}

		server := newWebtermServer(vos.VM, vos.User, params.Remote, params.Session, params.SizeX, params.SizeY)
		channel.OnDisconnect(func() { server.Close() })
		return server, nil
	})
}

func newWebtermServer(vm *virt.VM, user *virt.User, remote WebtermRemote, session string, sizeX, sizeY int) *WebtermServer {
	newSession := false
	if session == "" {
		session = utils.RandomString()
		newSession = true
	}

	server := &WebtermServer{
		Session: session,
		remote:  remote,
		vm:      vm,
		user:    user,
		pty:     pty.New(vm.PtsDir()),
	}
	server.SetSize(float64(sizeX), float64(sizeY))

	args := []string{"/usr/bin/screen", "-e~~", "-S", session}
	if !newSession {
		args = append(args, "-x")
	}
	server.pty.Slave.Chown(user.Uid, -1)
	cmd := vm.AttachCommand(user.Uid, "/dev/pts/"+strconv.Itoa(server.pty.No), args...)

	err := cmd.Start()
	if err != nil {
		panic(err)
	}

	go func() {
		defer log.RecoverAndLog()

		cmd.Wait()
		server.pty.Slave.Close()
		server.pty.Master.Close()
		server.remote.SessionEnded()
	}()

	go func() {
		defer log.RecoverAndLog()

		buf := make([]byte, (1<<12)-utf8.UTFMax, 1<<12)
		for {
			n, err := server.pty.Master.Read(buf)
			for n < cap(buf)-1 {
				r, _ := utf8.DecodeLastRune(buf[:n])
				if r != utf8.RuneError {
					break
				}
				server.pty.Master.Read(buf[n : n+1])
				n++
			}

			s := time.Now().Unix()
			if server.currentSecond != s {
				server.currentSecond = s
				server.messageCounter = 0
				server.byteCounter = 0
				server.lineFeeedCounter = 0
			}
			server.messageCounter += 1
			server.byteCounter += n
			server.lineFeeedCounter += bytes.Count(buf[:n], []byte{'\n'})
			if server.messageCounter > 100 || server.byteCounter > 1<<18 || server.lineFeeedCounter > 300 {
				time.Sleep(time.Second)
			}

			server.remote.Output(string(utils.FilterInvalidUTF8(buf[:n])))
			if err != nil {
				break
			}
		}
	}()

	return server
}

func (server *WebtermServer) Input(data string) {
	server.pty.Master.Write([]byte(data))
}

func (server *WebtermServer) ControlSequence(data string) {
	server.pty.MasterEncoded.Write([]byte(data))
}

func (server *WebtermServer) SetSize(x, y float64) {
	server.pty.SetSize(uint16(x), uint16(y))
}

func (server *WebtermServer) Close() error {
	server.pty.Signal(syscall.SIGHUP)
	return nil
}

func (server *WebtermServer) Terminate() error {
	server.vm.AttachCommand(server.user.Uid, "", "/usr/bin/screen", "-S", server.Session, "-X", "autodetach", "off").Run()
	server.pty.Signal(syscall.SIGHUP)
	server.vm.AttachCommand(server.user.Uid, "", "/usr/bin/screen", "-S", server.Session, "-X", "autodetach", "on").Run()
	return nil
}
<commit_msg>oskite: Always quit screen session on terminate command (to kick out other users of a shared session when closing it with X button).<commit_after>package main

import (
	"bytes"
	"koding/tools/dnode"
	"koding/tools/kite"
	"koding/tools/log"
	"koding/tools/pty"
	"koding/tools/utils"
	"koding/virt"
	"strconv"
	"strings"
	"syscall"
	"time"
	"unicode/utf8"
)

type WebtermServer struct {
	Session          string `json:"session"`
	remote           WebtermRemote
	vm               *virt.VM
	user             *virt.User
	pty              *pty.PTY
	currentSecond    int64
	messageCounter   int
	byteCounter      int
	lineFeeedCounter int
}

type WebtermRemote struct {
	Output       dnode.Callback
	SessionEnded dnode.Callback
}

func registerWebtermMethods(k *kite.Kite) {
	registerVmMethod(k, "webterm.getSessions", false, func(args *dnode.Partial, channel *kite.Channel, vos *virt.VOS) (interface{}, error) {
		// We need to use ls here, because /var/run/screen mount is only visible from inside of container. Errors are ignored.
		out, _ := vos.VM.AttachCommand(vos.User.Uid, "", "ls", "/var/run/screen/S-"+vos.User.Name).Output()
		names := strings.Split(string(out[:len(out)-1]), "\n")
		sessions := make([]string, len(names))
		for i, name := range names {
			segements := strings.SplitN(name, ".", 2)
			sessions[i] = segements[1]
		}
		return sessions, nil
	})

	// this method is special cased in oskite.go to allow foreign access
	registerVmMethod(k, "webterm.connect", false, func(args *dnode.Partial, channel *kite.Channel, vos *virt.VOS) (interface{}, error) {
		var params struct {
			Remote       WebtermRemote
			Session      string
			SizeX, SizeY int
		}
		if args.Unmarshal(&params) != nil || params.SizeX <= 0 || params.SizeY <= 0 {
			return nil, &kite.ArgumentError{Expected: "{ remote: [object], session: [string], sizeX: [integer], sizeY: [integer] }"}
		}

		server := newWebtermServer(vos.VM, vos.User, params.Remote, params.Session, params.SizeX, params.SizeY)
		channel.OnDisconnect(func() { server.Close() })
		return server, nil
	})
}

func newWebtermServer(vm *virt.VM, user *virt.User, remote WebtermRemote, session string, sizeX, sizeY int) *WebtermServer {
	newSession := false
	if session == "" {
		session = utils.RandomString()
		newSession = true
	}

	server := &WebtermServer{
		Session: session,
		remote:  remote,
		vm:      vm,
		user:    user,
		pty:     pty.New(vm.PtsDir()),
	}
	server.SetSize(float64(sizeX), float64(sizeY))

	args := []string{"/usr/bin/screen", "-e~~", "-S", session}
	if !newSession {
		args = append(args, "-x")
	}
	server.pty.Slave.Chown(user.Uid, -1)
	cmd := vm.AttachCommand(user.Uid, "/dev/pts/"+strconv.Itoa(server.pty.No), args...)

	err := cmd.Start()
	if err != nil {
		panic(err)
	}

	go func() {
		defer log.RecoverAndLog()

		cmd.Wait()
		server.pty.Slave.Close()
		server.pty.Master.Close()
		server.remote.SessionEnded()
	}()

	go func() {
		defer log.RecoverAndLog()

		buf := make([]byte, (1<<12)-utf8.UTFMax, 1<<12)
		for {
			n, err := server.pty.Master.Read(buf)
			for n < cap(buf)-1 {
				r, _ := utf8.DecodeLastRune(buf[:n])
				if r != utf8.RuneError {
					break
				}
				server.pty.Master.Read(buf[n : n+1])
				n++
			}

			s := time.Now().Unix()
			if server.currentSecond != s {
				server.currentSecond = s
				server.messageCounter = 0
				server.byteCounter = 0
				server.lineFeeedCounter = 0
			}
			server.messageCounter += 1
			server.byteCounter += n
			server.lineFeeedCounter += bytes.Count(buf[:n], []byte{'\n'})
			if server.messageCounter > 100 || server.byteCounter > 1<<18 || server.lineFeeedCounter > 300 {
				time.Sleep(time.Second)
			}

			server.remote.Output(string(utils.FilterInvalidUTF8(buf[:n])))
			if err != nil {
				break
			}
		}
	}()

	return server
}

func (server *WebtermServer) Input(data string) {
	server.pty.Master.Write([]byte(data))
}

func (server *WebtermServer) ControlSequence(data string) {
	server.pty.MasterEncoded.Write([]byte(data))
}

func (server *WebtermServer) SetSize(x, y float64) {
	server.pty.SetSize(uint16(x), uint16(y))
}

func (server *WebtermServer) Close() error {
	server.pty.Signal(syscall.SIGHUP)
	return nil
}

func (server *WebtermServer) Terminate() error {
	server.Close()
	server.vm.AttachCommand(server.user.Uid, "", "/usr/bin/screen", "-S", server.Session, "-X", "quit").Run()
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"socialapi/models"
)

func testMessageOperations() {
	post, err := createPost(CHANNEL_ID, ACCOUNT_ID)
	if err != nil {
		fmt.Println("error while creating post", err)
		err = nil
	}
	_, err = updatePost(post)
	if err != nil {
		fmt.Println("error while creating post", err)
		err = nil
	}
}

func createPost(channelId, accountId int64) (*models.ChannelMessage, error) {
	return createPostWithBody(channelId, accountId, "create a message")
}

func createPostWithBody(channelId, accountId int64, body string) (*models.ChannelMessage, error) {
	cm := models.NewChannelMessage()
	cm.Body = body
	cm.AccountId = accountId

	url := fmt.Sprintf("/channel/%d/message", channelId)
	cmI, err := sendModel("POST", url, cm)
	if err != nil {
		return nil, err
	}
	return cmI.(*models.ChannelMessage), nil
}

func updatePost(cm *models.ChannelMessage) (*models.ChannelMessage, error) {
	cm.Body = "after update"

	url := fmt.Sprintf("/message/%d", cm.Id)
	cmI, err := sendModel("POST", url, cm)
	if err != nil {
		return nil, err
	}

	return cmI.(*models.ChannelMessage), nil
}

func getPost(id int64, accountId int64, groupName string) (*models.ChannelMessage, error) {
	url := fmt.Sprintf("/message/%d?accountId=%d&groupName=%s", id)
	cm := models.NewChannelMessage()
	cmI, err := sendModel("GET", url, cm)
	if err != nil {
		return nil, err
	}
	return cmI.(*models.ChannelMessage), nil
}

func deletePost(id int64, accountId int64, groupName string) error {
	url := fmt.Sprintf("/message/%d?accountId=%d&groupName=%s", id, accountId, groupName)
	_, err := sendRequest("DELETE", url, nil)
	return err
}
<commit_msg>Social: delete message file<commit_after><|endoftext|>


<commit_before>/* Copyright 2016 The Bazel Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package packages

import (
	"go/build"
	"go/parser"
	"go/token"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strings"
)

// A WalkFunc is a callback called by Walk for each package.
type WalkFunc func(pkg *build.Package) error

// Walk walks through directories under "root".
// It calls back "f" for each package.
//
// It is similar to "golang.org/x/tools/go/buildutil".ForEachPackage, but
// it does not assume the standard Go tree because Bazel rules_go uses
// go_prefix instead of the standard tree.
//
// If a directory contains no buildable Go code, "f" is not called. If a
// directory contains one package with any name, "f" will be called with that
// package. If a directory contains multiple packages and one of the package
// names matches the directory name, "f" will be called on that package and the
// other packages will be silently ignored. If none of the package names match
// the directory name, a *build.MultiplePackageError error is returned.
func Walk(bctx build.Context, repoRoot, goPrefix, dir string, f WalkFunc) error {
	return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if !info.IsDir() {
			return nil
		}
		if base := info.Name(); base == "" || base[0] == '.' || base[0] == '_' || base == "testdata" {
			return filepath.SkipDir
		}

		pkg, err := findPackage(bctx, defaultPackageName(path, repoRoot, goPrefix), path)
		if err != nil {
			if _, ok := err.(*build.NoGoError); ok {
				return nil
			}
			return err
		}
		return f(pkg)
	})
}

func findPackage(bctx build.Context, defaultName, dir string) (*build.Package, error) {
	packageGoFiles, otherFiles, err := findPackageFiles(dir)
	if err != nil {
		return nil, err
	}

	packageName, err := selectPackageName(packageGoFiles, defaultName, dir)
	if err != nil {
		return nil, err
	}

	var files []os.FileInfo
	files = append(files, packageGoFiles[packageName]...)
	files = append(files, otherFiles...)
	sort.Slice(files, func(i, j int) bool {
		return files[i].Name() < files[j].Name()
	})
	bctx.ReadDir = func(dir string) ([]os.FileInfo, error) {
		return files, nil
	}
	return bctx.ImportDir(dir, build.ImportComment)
}

func findPackageFiles(dir string) (packageGoFiles map[string][]os.FileInfo, otherFiles []os.FileInfo, err error) {
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil, nil, err
	}

	packageGoFiles = make(map[string][]os.FileInfo)
	for _, file := range files {
		if file.IsDir() {
			continue
		}

		name := file.Name()
		filename := filepath.Join(dir, name)
		ext := path.Ext(name)
		isGo := ext == ".go"

		if !isGo {
			otherFiles = append(otherFiles, file)
			continue
		}
		fset := token.NewFileSet()
		ast, err := parser.ParseFile(fset, filename, nil, parser.PackageClauseOnly)
		if err != nil {
			log.Printf("%s: error parsing package clause: %v", filename, err)
			continue
		}

		packageName := ast.Name.Name
		if packageName == "documentation" {
			// go/build ignores this package.
			continue
		}
		if strings.HasSuffix(packageName, "_test") {
			packageName = packageName[:len(packageName)-len("_test")]
		}
		packageGoFiles[packageName] = append(packageGoFiles[packageName], file)
	}
	return packageGoFiles, otherFiles, nil
}

func defaultPackageName(dir, repoRoot, goPrefix string) string {
	if dir != repoRoot {
		return filepath.Base(dir)
	}
	name := path.Base(goPrefix)
	if name == "." || name == "/" {
		// This can happen if go_prefix is empty or is all slashes.
		return "unnamed"
	}
	return name
}

func selectPackageName(packageGoFiles map[string][]os.FileInfo, defaultName, dir string) (string, error) {
	if len(packageGoFiles) == 0 {
		return "", &build.NoGoError{Dir: dir}
	}

	if len(packageGoFiles) == 1 {
		var packageName string
		for name, _ := range packageGoFiles {
			packageName = name
		}
		return packageName, nil
	}

	if _, ok := packageGoFiles[defaultName]; ok {
		return defaultName, nil
	}

	err := &build.MultiplePackageError{Dir: dir}
	for name, files := range packageGoFiles {
		// Add the first file for each package for the error message.
		// Error() method expects these lists to be the same length. File
		// lists must be non-empty. These lists are only created by
		// findPackageFiles for packages with .go files present.
		err.Packages = append(err.Packages, name)
		err.Files = append(err.Files, files[0].Name())
	}
	return "", err
}
<commit_msg>Stop skipping directories that start with '_' (#425)<commit_after>/* Copyright 2016 The Bazel Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package packages

import (
	"go/build"
	"go/parser"
	"go/token"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strings"
)

// A WalkFunc is a callback called by Walk for each package.
type WalkFunc func(pkg *build.Package) error

// Walk walks through directories under "root".
// It calls back "f" for each package.
//
// It is similar to "golang.org/x/tools/go/buildutil".ForEachPackage, but
// it does not assume the standard Go tree because Bazel rules_go uses
// go_prefix instead of the standard tree.
//
// If a directory contains no buildable Go code, "f" is not called. If a
// directory contains one package with any name, "f" will be called with that
// package. If a directory contains multiple packages and one of the package
// names matches the directory name, "f" will be called on that package and the
// other packages will be silently ignored. If none of the package names match
// the directory name, a *build.MultiplePackageError error is returned.
func Walk(bctx build.Context, repoRoot, goPrefix, dir string, f WalkFunc) error {
	return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if !info.IsDir() {
			return nil
		}
		if base := info.Name(); base == "" || base[0] == '.' || base == "testdata" {
			return filepath.SkipDir
		}

		pkg, err := findPackage(bctx, defaultPackageName(path, repoRoot, goPrefix), path)
		if err != nil {
			if _, ok := err.(*build.NoGoError); ok {
				return nil
			}
			return err
		}
		return f(pkg)
	})
}

func findPackage(bctx build.Context, defaultName, dir string) (*build.Package, error) {
	packageGoFiles, otherFiles, err := findPackageFiles(dir)
	if err != nil {
		return nil, err
	}

	packageName, err := selectPackageName(packageGoFiles, defaultName, dir)
	if err != nil {
		return nil, err
	}

	var files []os.FileInfo
	files = append(files, packageGoFiles[packageName]...)
	files = append(files, otherFiles...)
	sort.Slice(files, func(i, j int) bool {
		return files[i].Name() < files[j].Name()
	})
	bctx.ReadDir = func(dir string) ([]os.FileInfo, error) {
		return files, nil
	}
	return bctx.ImportDir(dir, build.ImportComment)
}

func findPackageFiles(dir string) (packageGoFiles map[string][]os.FileInfo, otherFiles []os.FileInfo, err error) {
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil, nil, err
	}

	packageGoFiles = make(map[string][]os.FileInfo)
	for _, file := range files {
		if file.IsDir() {
			continue
		}

		name := file.Name()
		filename := filepath.Join(dir, name)
		ext := path.Ext(name)
		isGo := ext == ".go"

		if !isGo {
			otherFiles = append(otherFiles, file)
			continue
		}
		fset := token.NewFileSet()
		ast, err := parser.ParseFile(fset, filename, nil, parser.PackageClauseOnly)
		if err != nil {
			log.Printf("%s: error parsing package clause: %v", filename, err)
			continue
		}

		packageName := ast.Name.Name
		if packageName == "documentation" {
			// go/build ignores this package.
			continue
		}
		if strings.HasSuffix(packageName, "_test") {
			packageName = packageName[:len(packageName)-len("_test")]
		}
		packageGoFiles[packageName] = append(packageGoFiles[packageName], file)
	}
	return packageGoFiles, otherFiles, nil
}

func defaultPackageName(dir, repoRoot, goPrefix string) string {
	if dir != repoRoot {
		return filepath.Base(dir)
	}
	name := path.Base(goPrefix)
	if name == "." || name == "/" {
		// This can happen if go_prefix is empty or is all slashes.
		return "unnamed"
	}
	return name
}

func selectPackageName(packageGoFiles map[string][]os.FileInfo, defaultName, dir string) (string, error) {
	if len(packageGoFiles) == 0 {
		return "", &build.NoGoError{Dir: dir}
	}

	if len(packageGoFiles) == 1 {
		var packageName string
		for name, _ := range packageGoFiles {
			packageName = name
		}
		return packageName, nil
	}

	if _, ok := packageGoFiles[defaultName]; ok {
		return defaultName, nil
	}

	err := &build.MultiplePackageError{Dir: dir}
	for name, files := range packageGoFiles {
		// Add the first file for each package for the error message.
		// Error() method expects these lists to be the same length. File
		// lists must be non-empty. These lists are only created by
		// findPackageFiles for packages with .go files present.
		err.Packages = append(err.Packages, name)
		err.Files = append(err.Files, files[0].Name())
	}
	return "", err
}
<|endoftext|>


<commit_before>package tree

import (
	"errors"
	"sort"
)

// Define a function Build(records []Record) (*Node, error)
// where Record is a struct containing int fields ID and Parent
// and Node is a struct containing int field ID and []*Node field Children.

type Record struct {
	ID     int
	Parent int
}

type Node struct {
	ID       int
	Children []*Node
}

// ByID implements sort.Interface based on the ID field.
type ByID []*Node

func (c ByID) Len() int {
	return len(c)
}

func (c ByID) Swap(a int, b int) {
	c[a], c[b] = c[b], c[a]
}

func (c ByID) Less(a int, b int) bool {
	return c[a].ID < c[b].ID
}

func Build(records []Record) (*Node, error) {
	if len(records) == 0 {
		return nil, nil
	}
	nodes := map[int]*Node{}
	nodes[0] = &Node{ID: 0}

	if rootNodeHasParent(records) {
		return &Node{}, errors.New("error root node has a parent")
	}

	for _, record := range records {
		// Initialize node if it doesn't exist
		if _, ok := nodes[record.ID]; !ok {
			nodes[record.ID] = &Node{ID: record.ID}
		}
		// Initialize parent if it doesn't exist
		if _, ok := nodes[record.Parent]; !ok {
			nodes[record.Parent] = &Node{ID: record.Parent}
		}
		// Continue if this is the root node
		if record.ID == 0 {
			continue
		}
		// Populate children for parent
		children := nodes[record.Parent].Children
		node := nodes[record.ID]
		if !contains(children, node) {
			children = append(children, node)
			sort.Sort(ByID(children))
			nodes[record.Parent].Children = children
		}
	}
	return nodes[0], nil
}

func rootNodeHasParent(records []Record) bool {
	for _, record := range records {
		if record.ID == 0 && record.Parent != 0 {
			return true
		}
	}
	return false
}

func contains(slice []*Node, node *Node) bool {
	for _, v := range slice {
		if v.ID == node.ID {
			return true
		}
	}
	return false
}
<commit_msg>Error for duplicate nodes<commit_after>package tree

import (
	"errors"
	"sort"
)

// Define a function Build(records []Record) (*Node, error)
// where Record is a struct containing int fields ID and Parent
// and Node is a struct containing int field ID and []*Node field Children.

type Record struct {
	ID     int
	Parent int
}

type Node struct {
	ID       int
	Children []*Node
}

// ByID implements sort.Interface based on the ID field.
type ByID []*Node

func (c ByID) Len() int {
	return len(c)
}

func (c ByID) Swap(a int, b int) {
	c[a], c[b] = c[b], c[a]
}

func (c ByID) Less(a int, b int) bool {
	return c[a].ID < c[b].ID
}

func Build(records []Record) (*Node, error) {
	if len(records) == 0 {
		return nil, nil
	}
	nodes := map[int]*Node{}
	nodes[0] = &Node{ID: 0}

	if rootNodeHasParent(records) {
		return &Node{}, errors.New("error root node has a parent")
	}
	if noRootNode(records) {
		return &Node{}, errors.New("error no root node")
	}
	if duplicateNode(records) {
		return &Node{}, errors.New("error duplicate node")
	}

	for _, record := range records {
		// Initialize node if it doesn't exist
		if _, ok := nodes[record.ID]; !ok {
			nodes[record.ID] = &Node{ID: record.ID}
		}
		// Initialize parent if it doesn't exist
		if _, ok := nodes[record.Parent]; !ok {
			nodes[record.Parent] = &Node{ID: record.Parent}
		}
		// Continue if this is the root node
		if record.ID == 0 {
			continue
		}
		// Populate children for parent
		children := nodes[record.Parent].Children
		node := nodes[record.ID]
		if !contains(children, node) {
			children = append(children, node)
			sort.Sort(ByID(children))
			nodes[record.Parent].Children = children
		}
	}
	return nodes[0], nil
}

func rootNodeHasParent(records []Record) bool {
	for _, record := range records {
		if record.ID == 0 && record.Parent != 0 {
			return true
		}
	}
	return false
}

func noRootNode(records []Record) bool {
	for _, record := range records {
		if record.ID == 0 {
			return false
		}
	}
	return true
}

func duplicateNode(records []Record) bool {
	seen := map[int]bool{}
	for _, record := range records {
		if _, hasSeen := seen[record.ID]; hasSeen {
			return true
		}
		seen[record.ID] = true
	}
	return false
}

func contains(slice []*Node, node *Node) bool {
	for _, v := range slice {
		if v.ID == node.ID {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package main

import (
    "net/http"

    "github.com/yhat/scrape"
    "golang.org/x/net/html"
    "golang.org/x/net/html/atom"
    "fmt"
    "net/url"
    "strings"
    "strconv"
)

func scrapr(stars float64, rateMin int64, rateMax int64, national bool, women bool) []team {

    var teamMap []team
    var body *html.Node
    page := 1

    for ok := true; ok; ok = more(body) {
        scrapeUrl := urlCreator(stars, rateMin, rateMax, national, women, page)
        body = readr(scrapeUrl)
        teamMap = append(teamMap, parsr(body)...)

        page++
    }

    return teamMap
}

func more(body *html.Node) bool {
    matcher := func(n *html.Node) bool {
        if n != nil && n.DataAtom == atom.Li && n.Parent != nil && n.Parent.Parent != nil {
            return scrape.Attr(n, "class") == "next"
        }

        return false
    }

    return (body != nil && len(scrape.FindAll(body, matcher)) > 0)
}

func parsr(body *html.Node) []team {
    teamRowMatcher := func(n *html.Node) bool {
        if n.DataAtom == atom.Tr && n.Parent != nil && n.Parent.Parent != nil {
            return strings.Contains(scrape.Attr(n.Parent.Parent, "class"), "teams") && n.Parent.Parent.DataAtom == atom.Table
        }

        return false
    }

    teamAttrMatcher := func(n *html.Node) bool {
        if n.DataAtom == atom.Td && n.Parent != nil && n.Parent.Parent != nil {
            return n.Parent.DataAtom == atom.Tr && scrape.Attr(n, "colspan") != "2"
        }

        return false
    }

    var teams []team
    teamRows := scrape.FindAll(body, teamRowMatcher)
    for _, teamRow := range teamRows {
        var team team
        teamAttrs := scrape.FindAll(teamRow, teamAttrMatcher)
        for _, teamAttr := range teamAttrs {

            title := scrape.Attr(teamAttr, "data-title")
            switch title {
                case "Name":
                    team.name = scrape.Text(teamAttr.FirstChild)

                case "League":
                    team.league = scrape.Text(teamAttr.FirstChild)

                case "ATT":
                    team.att, _ = strconv.ParseInt(scrape.Text(teamAttr.FirstChild), 10, 32)

                case "MID":
                    team.mid, _ = strconv.ParseInt(scrape.Text(teamAttr.FirstChild), 10, 32)

                case "DEF":
                    team.def, _ = strconv.ParseInt(scrape.Text(teamAttr.FirstChild), 10, 32)

                case "OVR":
                    team.ovr, _ = strconv.ParseInt(scrape.Text(teamAttr.FirstChild), 10, 32)

                case "Team Rating":
                    team.stars = float64(len(scrape.FindAll(teamAttr, scrape.ByClass("fa-star")))) + (float64(len(scrape.FindAll(teamAttr, scrape.ByClass("fa-star-half-o")))) * float64(.5))
            }
        }

        if (len(team.name) > 0) {

            teams = append(teams, team)
        }
    }

    return teams
}

func readr(scrapeUrl *url.URL) *html.Node {
    println(fmt.Sprintf("Fetching: %s", scrapeUrl.String()))
    resp, err := http.Get(scrapeUrl.String())
    if err != nil {
        panic(err)
    }

    body, err := html.Parse(resp.Body)
    if err != nil {
        panic(err)
    }

    return body
}

func urlCreator(stars float64, rateMin int64, rateMax int64, national bool, women bool, page int) *url.URL {

    baseUrl := fmt.Sprintf("https://www.fifaindex.com/teams/%d/?", page)
    if (rateMin > 0 && rateMax > 0) {
        baseUrl += fmt.Sprintf("overallrating_0=%d&overallrating_1=%d&", rateMin, rateMax)
        baseUrl += fmt.Sprintf("attackrating_0=%d&attackrating_1=%d&", rateMin, rateMax)
        baseUrl += fmt.Sprintf("midfieldrating_0=%d&midfieldrating_1=%d&", rateMin, rateMax)
        baseUrl += fmt.Sprintf("defenserating_0=%d&defenserating_1=%d&", rateMin, rateMax)
    }

    if national == true {
        baseUrl += "type=1&"
    } else if women == true {
        baseUrl += "type=2&"
    }

    if (stars > 0) {
        if (stars == float64(int64(stars))) {
            baseUrl += fmt.Sprintf("stars=%.0f", stars)
        } else {
            baseUrl += fmt.Sprintf("stars=%.1f", stars)
        }
    }

    returnUrl, _ := url.Parse(baseUrl);
    return returnUrl
}
<commit_msg>updated function name to the common naming scheme<commit_after>package main

import (
    "net/http"

    "github.com/yhat/scrape"
    "golang.org/x/net/html"
    "golang.org/x/net/html/atom"
    "fmt"
    "net/url"
    "strings"
    "strconv"
)

func scrapr(stars float64, rateMin int64, rateMax int64, national bool, women bool) []team {

    var teamMap []team
    var body *html.Node
    page := 1

    for ok := true; ok; ok = more(body) {
        scrapeUrl := urlCreatr(stars, rateMin, rateMax, national, women, page)
        body = readr(scrapeUrl)
        teamMap = append(teamMap, parsr(body)...)

        page++
    }

    return teamMap
}

func more(body *html.Node) bool {
    matcher := func(n *html.Node) bool {
        if n != nil && n.DataAtom == atom.Li && n.Parent != nil && n.Parent.Parent != nil {
            return scrape.Attr(n, "class") == "next"
        }

        return false
    }

    return (body != nil && len(scrape.FindAll(body, matcher)) > 0)
}

func parsr(body *html.Node) []team {
    teamRowMatcher := func(n *html.Node) bool {
        if n.DataAtom == atom.Tr && n.Parent != nil && n.Parent.Parent != nil {
            return strings.Contains(scrape.Attr(n.Parent.Parent, "class"), "teams") && n.Parent.Parent.DataAtom == atom.Table
        }

        return false
    }

    teamAttrMatcher := func(n *html.Node) bool {
        if n.DataAtom == atom.Td && n.Parent != nil && n.Parent.Parent != nil {
            return n.Parent.DataAtom == atom.Tr && scrape.Attr(n, "colspan") != "2"
        }

        return false
    }

    var teams []team
    teamRows := scrape.FindAll(body, teamRowMatcher)
    for _, teamRow := range teamRows {
        var team team
        teamAttrs := scrape.FindAll(teamRow, teamAttrMatcher)
        for _, teamAttr := range teamAttrs {

            title := scrape.Attr(teamAttr, "data-title")
            switch title {
                case "Name":
                    team.name = scrape.Text(teamAttr.FirstChild)

                case "League":
                    team.league = scrape.Text(teamAttr.FirstChild)

                case "ATT":
                    team.att, _ = strconv.ParseInt(scrape.Text(teamAttr.FirstChild), 10, 32)

                case "MID":
                    team.mid, _ = strconv.ParseInt(scrape.Text(teamAttr.FirstChild), 10, 32)

                case "DEF":
                    team.def, _ = strconv.ParseInt(scrape.Text(teamAttr.FirstChild), 10, 32)

                case "OVR":
                    team.ovr, _ = strconv.ParseInt(scrape.Text(teamAttr.FirstChild), 10, 32)

                case "Team Rating":
                    team.stars = float64(len(scrape.FindAll(teamAttr, scrape.ByClass("fa-star")))) + (float64(len(scrape.FindAll(teamAttr, scrape.ByClass("fa-star-half-o")))) * float64(.5))
            }
        }

        if (len(team.name) > 0) {

            teams = append(teams, team)
        }
    }

    return teams
}

func readr(scrapeUrl *url.URL) *html.Node {
    println(fmt.Sprintf("Fetching: %s", scrapeUrl.String()))
    resp, err := http.Get(scrapeUrl.String())
    if err != nil {
        panic(err)
    }

    body, err := html.Parse(resp.Body)
    if err != nil {
        panic(err)
    }

    return body
}

func urlCreatr(stars float64, rateMin int64, rateMax int64, national bool, women bool, page int) *url.URL {

    baseUrl := fmt.Sprintf("https://www.fifaindex.com/teams/%d/?", page)
    if (rateMin > 0 && rateMax > 0) {
        baseUrl += fmt.Sprintf("overallrating_0=%d&overallrating_1=%d&", rateMin, rateMax)
        baseUrl += fmt.Sprintf("attackrating_0=%d&attackrating_1=%d&", rateMin, rateMax)
        baseUrl += fmt.Sprintf("midfieldrating_0=%d&midfieldrating_1=%d&", rateMin, rateMax)
        baseUrl += fmt.Sprintf("defenserating_0=%d&defenserating_1=%d&", rateMin, rateMax)
    }

    if national == true {
        baseUrl += "type=1&"
    } else if women == true {
        baseUrl += "type=2&"
    }

    if (stars > 0) {
        if (stars == float64(int64(stars))) {
            baseUrl += fmt.Sprintf("stars=%.0f", stars)
        } else {
            baseUrl += fmt.Sprintf("stars=%.1f", stars)
        }
    }

    returnUrl, _ := url.Parse(baseUrl);
    return returnUrl
}
<|endoftext|>


<commit_before>// screen
package main

import (
	//	"fmt"
	termb "github.com/nsf/termbox-go"
)

func drawfield() error {
	if err := termb.Init(); err != nil {
		return err
	}
	return nil
}
<commit_msg>Preparing for first writing on the screen<commit_after>// screen
package main

import (
	//	"fmt"
	"errors"
	termbox "github.com/nsf/termbox-go"
)

func drawfield(lField <-chan Field, rField <-chan Field) error {
	var lFl, rFl Field

	if err := termbox.Init(); err != nil {
		return err
	}
	defer termbox.Close()

	//	termBuf := termbox.CellBuffer()
	//	termSizW, termSizH := termbox.Size()

	lFl = <-lField
	rFl = <-rField

	if lFl.Length != rFl.Length {
		return errors.New("Can't do mismatched fields yet")
	}

	return nil
}
<|endoftext|>


<commit_before>package setup

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"log"
	"os"
)

func Apply(data []byte) InitData {
	init := InitData{}

	err := yaml.Unmarshal(data, &init)

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

	fmt.Printf("%+v", init)

	return init
}
<commit_msg>Remove printf from apply.go<commit_after>package setup

import (
	"gopkg.in/yaml.v2"
	"log"
	"os"
)

func Apply(data []byte) InitData {
	init := InitData{}

	err := yaml.Unmarshal(data, &init)

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

	return init
}
<|endoftext|>


<commit_before>package minion

import (
	"time"

	"code.google.com/p/go-uuid/uuid"
)

type Minion interface {
	// Get minion identifier
	GetUUID() uuid.UUID

	// Set name of minion
	SetName(name string) error

	// Get name of minion
	GetName() (string, error)

	// Set the time the minion was last seen in seconds since the Epoch
	SetLastseen(s int64) error

	// Get a classifier for a minion
	GetClassifier(key string) (MinionClassifier, error)

	// Classify minion a with given a key and value
	SetClassifier(c MinionClassifier) error

	// Runs periodic functions, e.g. refreshes classifies and lastseen
	Refresh(t *time.Ticker) error

	// Listens for new tasks and processes them
	TaskListener(c chan<- MinionTask) error

	// Runs new tasks as received by the TaskListener
	TaskRunner (c <-chan MinionTask) error

	// Start serving
	Serve() error
}

type MinionTask interface {
	// Gets the command to be executed
	GetCommand() (string, error)

	// Gets the time the task was sent for processing
	GetTimestamp() (int64, error)

	// Processes the task
	Process() error

	// Submits a task to a minion
	Submit(m Minion) error
}
<commit_msg>Submitting new tasks to minions should be done via the client interface<commit_after>package minion

import (
	"time"

	"code.google.com/p/go-uuid/uuid"
)

type Minion interface {
	// Get minion identifier
	GetUUID() uuid.UUID

	// Set name of minion
	SetName(name string) error

	// Get name of minion
	GetName() (string, error)

	// Set the time the minion was last seen in seconds since the Epoch
	SetLastseen(s int64) error

	// Get a classifier for a minion
	GetClassifier(key string) (MinionClassifier, error)

	// Classify minion a with given a key and value
	SetClassifier(c MinionClassifier) error

	// Runs periodic functions, e.g. refreshes classifies and lastseen
	Refresh(t *time.Ticker) error

	// Listens for new tasks and processes them
	TaskListener(c chan<- MinionTask) error

	// Runs new tasks as received by the TaskListener
	TaskRunner (c <-chan MinionTask) error

	// Start serving
	Serve() error
}

type MinionTask interface {
	// Gets the command to be executed
	GetCommand() (string, error)

	// Gets the time the task was sent for processing
	GetTimestamp() (int64, error)

	// Processes the task
	Process() error
}
<|endoftext|>


<commit_before>package shared

import (
	"bytes"
	"encoding/json"
	"fmt"

	log "gopkg.in/inconshreveable/log15.v2"
)

type Jmap map[string]interface{}

func (m Jmap) GetString(key string) (string, error) {
	if val, ok := m[key]; !ok {
		return "", fmt.Errorf("Response was missing `%s`", key)
	} else if val, ok := val.(string); !ok {
		return "", fmt.Errorf("`%s` was not a string", key)
	} else {
		return val, nil
	}
}

func (m Jmap) GetMap(key string) (Jmap, error) {
	if val, ok := m[key]; !ok {
		return nil, fmt.Errorf("Response was missing `%s`", key)
	} else if val, ok := val.(map[string]interface{}); !ok {
		return nil, fmt.Errorf("`%s` was not a map, got %T", key, m[key])
	} else {
		return val, nil
	}
}

func (m Jmap) GetInt(key string) (int, error) {
	if val, ok := m[key]; !ok {
		return -1, fmt.Errorf("Response was missing `%s`", key)
	} else if val, ok := val.(float64); !ok {
		return -1, fmt.Errorf("`%s` was not an int", key)
	} else {
		return int(val), nil
	}
}

func (m Jmap) GetBool(key string) (bool, error) {
	if val, ok := m[key]; !ok {
		return false, fmt.Errorf("Response was missing `%s`", key)
	} else if val, ok := val.(bool); !ok {
		return false, fmt.Errorf("`%s` was not an int", key)
	} else {
		return val, nil
	}
}

func DebugJson(r *bytes.Buffer) {
	pretty := &bytes.Buffer{}
	if err := json.Indent(pretty, r.Bytes(), "\t", "\t"); err != nil {
		Log.Error("error indenting json", log.Ctx{"err": err})
		return
	}

	// Print the JSON without the last "\n"
	str := pretty.String()
	Log.Debug(fmt.Sprintf("\n\t%s", str[0:len(str)-1]))
}
<commit_msg>Remove log15 from shared json<commit_after>package shared

import (
	"bytes"
	"encoding/json"
	"fmt"
)

type Jmap map[string]interface{}

func (m Jmap) GetString(key string) (string, error) {
	if val, ok := m[key]; !ok {
		return "", fmt.Errorf("Response was missing `%s`", key)
	} else if val, ok := val.(string); !ok {
		return "", fmt.Errorf("`%s` was not a string", key)
	} else {
		return val, nil
	}
}

func (m Jmap) GetMap(key string) (Jmap, error) {
	if val, ok := m[key]; !ok {
		return nil, fmt.Errorf("Response was missing `%s`", key)
	} else if val, ok := val.(map[string]interface{}); !ok {
		return nil, fmt.Errorf("`%s` was not a map, got %T", key, m[key])
	} else {
		return val, nil
	}
}

func (m Jmap) GetInt(key string) (int, error) {
	if val, ok := m[key]; !ok {
		return -1, fmt.Errorf("Response was missing `%s`", key)
	} else if val, ok := val.(float64); !ok {
		return -1, fmt.Errorf("`%s` was not an int", key)
	} else {
		return int(val), nil
	}
}

func (m Jmap) GetBool(key string) (bool, error) {
	if val, ok := m[key]; !ok {
		return false, fmt.Errorf("Response was missing `%s`", key)
	} else if val, ok := val.(bool); !ok {
		return false, fmt.Errorf("`%s` was not an int", key)
	} else {
		return val, nil
	}
}

func DebugJson(r *bytes.Buffer) {
	pretty := &bytes.Buffer{}
	if err := json.Indent(pretty, r.Bytes(), "\t", "\t"); err != nil {
		Log.Error("error indenting json", Ctx{"err": err})
		return
	}

	// Print the JSON without the last "\n"
	str := pretty.String()
	Log.Debug(fmt.Sprintf("\n\t%s", str[0:len(str)-1]))
}
<|endoftext|>


<commit_before>package plugins

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestPluginsToMe(t *testing.T) {
	if ToMe("a", "a") == false {
		t.Error("ToMe expected true; got false\n")
	}
}

func TestPluginsNameRE(t *testing.T) {
	n := NameRE.ReplaceAllString("@test:test.com", "$1")
	if n != "test" {
		t.Errorf("NameRE expected 'test'; got %q\n", n)
	}
}

func TestPluginsRemoveName(t *testing.T) {
	expected := "this is for you"
	n := RemoveName("mctest", fmt.Sprintf("mctest: %s", expected))
	if n != expected {
		t.Errorf("Expected %q; got %q\n", expected, n)
	}
}

type testResp struct {
	Name string `json:"test"`
}

func TestHTTPRequestDoJSON(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		_, err := fmt.Fprintln(w, `{"test":"success"}`)
		if err != nil {
			t.Error(err)
		}
	}))
	defer ts.Close()

	var tr = &testResp{}

	req := HTTPRequest{
		ResBody: tr,
		URL:     ts.URL,
	}

	err := req.DoJSON()
	if err != nil {
		t.Error(err)
	}

	if tr.Name != "success" {
		t.Errorf("Expected 'test'; got '%s'\n", tr.Name)
	}
}
<commit_msg>skip DoJSON test on plan9<commit_after>package plugins

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"runtime"
	"testing"
)

func TestPluginsToMe(t *testing.T) {
	if ToMe("a", "a") == false {
		t.Error("ToMe expected true; got false\n")
	}
}

func TestPluginsNameRE(t *testing.T) {
	n := NameRE.ReplaceAllString("@test:test.com", "$1")
	if n != "test" {
		t.Errorf("NameRE expected 'test'; got %q\n", n)
	}
}

func TestPluginsRemoveName(t *testing.T) {
	expected := "this is for you"
	n := RemoveName("mctest", fmt.Sprintf("mctest: %s", expected))
	if n != expected {
		t.Errorf("Expected %q; got %q\n", expected, n)
	}
}

type testResp struct {
	Name string `json:"test"`
}

func TestHTTPRequestDoJSON(t *testing.T) {
	if runtime.GOOS != "plan9" {
		ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			_, err := fmt.Fprintln(w, `{"test":"success"}`)
			if err != nil {
				t.Error(err)
			}
		}))
		defer ts.Close()

		var tr = &testResp{}

		req := HTTPRequest{
			ResBody: tr,
			URL:     ts.URL,
		}

		err := req.DoJSON()
		if err != nil {
			t.Error(err)
		}

		if tr.Name != "success" {
			t.Errorf("Expected 'test'; got '%s'\n", tr.Name)
		}
	}
}
<|endoftext|>


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

// This package implements a basic LISP interpretor for embedding in a go program for scripting.
// This file contains the type predicate primitive functions.

package golisp

func RegisterTypePredicatePrimitives() {
	MakePrimitiveFunction("list?", "1", IsPairImpl)
	MakePrimitiveFunction("pair?", "1", IsPairImpl)
	MakePrimitiveFunction("alist?", "1", IsAlistImpl)
	MakePrimitiveFunction("nil?", "1", NilPImpl)
	MakePrimitiveFunction("null?", "1", NilPImpl)
	MakePrimitiveFunction("notnil?", "1", NotNilPImpl)
	MakePrimitiveFunction("notnull?", "1", NotNilPImpl)
	MakePrimitiveFunction("symbol?", "1", IsSymbolImpl)
	MakePrimitiveFunction("string?", "1", IsStringImpl)
	MakePrimitiveFunction("integer?", "1", IsIntegerImpl)
	MakePrimitiveFunction("number?", "1", IsNumberImpl)
	MakePrimitiveFunction("float?", "1", IsFloatImpl)
	MakePrimitiveFunction("function?", "1", IsFunctionImpl)
	MakePrimitiveFunction("macro?", "1", IsMacroImpl)
	MakePrimitiveFunction("frame?", "1", IsFrameImpl)
	MakePrimitiveFunction("bytearray?", "1", IsByteArrayImpl)
}

func IsPairImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(PairP(Car(args))), nil
}

func IsAlistImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(AlistP(Car(args))), nil
}

func NilPImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(NilP(Car(args))), nil
}

func NotNilPImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(NotNilP(Car(args))), nil
}

func IsSymbolImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(SymbolP(Car(args))), nil
}

func IsStringImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(StringP(Car(args))), nil
}

func IsIntegerImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(IntegerP(Car(args))), nil
}

func IsNumberImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(NumberP(Car(args))), nil
}

func IsFloatImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(FloatP(Car(args))), nil
}

func IsFunctionImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(FunctionP(Car(args))), nil
}

func IsMacroImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(MacroP(Car(args))), nil
}

func IsFrameImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(FrameP(Car(args))), nil
}

func IsByteArrayImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(ObjectP(Car(args)) && ObjectType(Car(args)) == "[]byte"), nil
}
<commit_msg>Add is-port?<commit_after>// Copyright 2014 SteelSeries ApS.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This package implements a basic LISP interpretor for embedding in a go program for scripting.
// This file contains the type predicate primitive functions.

package golisp

func RegisterTypePredicatePrimitives() {
	MakePrimitiveFunction("list?", "1", IsPairImpl)
	MakePrimitiveFunction("pair?", "1", IsPairImpl)
	MakePrimitiveFunction("alist?", "1", IsAlistImpl)
	MakePrimitiveFunction("nil?", "1", NilPImpl)
	MakePrimitiveFunction("null?", "1", NilPImpl)
	MakePrimitiveFunction("notnil?", "1", NotNilPImpl)
	MakePrimitiveFunction("notnull?", "1", NotNilPImpl)
	MakePrimitiveFunction("symbol?", "1", IsSymbolImpl)
	MakePrimitiveFunction("string?", "1", IsStringImpl)
	MakePrimitiveFunction("integer?", "1", IsIntegerImpl)
	MakePrimitiveFunction("number?", "1", IsNumberImpl)
	MakePrimitiveFunction("float?", "1", IsFloatImpl)
	MakePrimitiveFunction("function?", "1", IsFunctionImpl)
	MakePrimitiveFunction("macro?", "1", IsMacroImpl)
	MakePrimitiveFunction("frame?", "1", IsFrameImpl)
	MakePrimitiveFunction("bytearray?", "1", IsByteArrayImpl)
	MakePrimitiveFunction("port?", "1", IsPortImpl)
}

func IsPairImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(PairP(Car(args))), nil
}

func IsAlistImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(AlistP(Car(args))), nil
}

func NilPImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(NilP(Car(args))), nil
}

func NotNilPImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(NotNilP(Car(args))), nil
}

func IsSymbolImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(SymbolP(Car(args))), nil
}

func IsStringImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(StringP(Car(args))), nil
}

func IsIntegerImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(IntegerP(Car(args))), nil
}

func IsNumberImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(NumberP(Car(args))), nil
}

func IsFloatImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(FloatP(Car(args))), nil
}

func IsFunctionImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(FunctionP(Car(args))), nil
}

func IsMacroImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(MacroP(Car(args))), nil
}

func IsFrameImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(FrameP(Car(args))), nil
}

func IsByteArrayImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(ObjectP(Car(args)) && ObjectType(Car(args)) == "[]byte"), nil
}

func IsPortImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return BooleanWithValue(PortP(Car(args))), nil
}
<|endoftext|>


<commit_before>// Copyright © 2016 Aaron Longwell
//
// Use of this source code is governed by an MIT licese.
// Details in the LICENSE file.

package trello

type SearchResult struct {
	Options SearchOptions `json:"options"`
	Actions []*Action     `json:"actions,omitempty"`
	Cards   []*Card       `json:"cards,omitempty"`
	Boards  []*Board      `json:"boards,omitempty"`
	Members []*Member     `json:"members,omitempty"`
}

type SearchOptions struct {
	Terms      []SearchTerm     `json:"terms"`
	Modifiers  []SearchModifier `json:"modifiers,omitempty"`
	ModelTypes []string         `json:"modelTypes,omitempty"`
	Partial    bool             `json:"partial"`
}

type SearchModifier struct {
	Text string `json:"text"`
}

type SearchTerm struct {
	Text    string `json:"text"`
	Negated bool   `json:"negated,omitempty"`
}

func (c *Client) SearchCards(query string, args Arguments) (cards []*Card, err error) {
	args["query"] = query
	args["modelTypes"] = "cards"
	res := SearchResult{}
	err = c.Get("search", args, &res)
	cards = res.Cards
	return
}

func (c *Client) SearchBoards(query string, args Arguments) (boards []*Board, err error) {
	args["query"] = query
	args["modelTypes"] = "boards"
	res := SearchResult{}
	err = c.Get("search", args, &res)
	boards = res.Boards
	for _, board := range boards {
		board.client = c
	}
	return
}

func (c *Client) SearchMembers(query string, args Arguments) (members []*Member, err error) {
	args["query"] = query
	err = c.Get("search/members", args, &members)
	return
}
<commit_msg>Add comments to public members of search (golint)<commit_after>// Copyright © 2016 Aaron Longwell
//
// Use of this source code is governed by an MIT licese.
// Details in the LICENSE file.

package trello

// SearchResult represents a search result as collections of various
// types returned by a search, e.g. Cards or Boards.
type SearchResult struct {
	Options SearchOptions `json:"options"`
	Actions []*Action     `json:"actions,omitempty"`
	Cards   []*Card       `json:"cards,omitempty"`
	Boards  []*Board      `json:"boards,omitempty"`
	Members []*Member     `json:"members,omitempty"`
}

// SearchOptions contains options for search requests.
type SearchOptions struct {
	Terms      []SearchTerm     `json:"terms"`
	Modifiers  []SearchModifier `json:"modifiers,omitempty"`
	ModelTypes []string         `json:"modelTypes,omitempty"`
	Partial    bool             `json:"partial"`
}

// SearchModifier is wrapper for a search string.
type SearchModifier struct {
	Text string `json:"text"`
}

// SearchTerm is a string that may be negated in a search query.
type SearchTerm struct {
	Text    string `json:"text"`
	Negated bool   `json:"negated,omitempty"`
}

// SearchCards takes a query string and Arguments and returns a slice of Cards or an error.
func (c *Client) SearchCards(query string, args Arguments) (cards []*Card, err error) {
	args["query"] = query
	args["modelTypes"] = "cards"
	res := SearchResult{}
	err = c.Get("search", args, &res)
	cards = res.Cards
	return
}

// SearchBoards takes a query string and Arguments and returns a slice of Boards or an error.
func (c *Client) SearchBoards(query string, args Arguments) (boards []*Board, err error) {
	args["query"] = query
	args["modelTypes"] = "boards"
	res := SearchResult{}
	err = c.Get("search", args, &res)
	boards = res.Boards
	for _, board := range boards {
		board.client = c
	}
	return
}

// SearchMembers takes a query string and Arguments and returns a slice of Members or an error.
func (c *Client) SearchMembers(query string, args Arguments) (members []*Member, err error) {
	args["query"] = query
	err = c.Get("search/members", args, &members)
	return
}
<|endoftext|>


<commit_before>/* Search functions */

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

package main

import (
	"encoding/json"
	"fmt"
	"github.com/ctdk/goiardi/client"
	"github.com/ctdk/goiardi/config"
	"github.com/ctdk/goiardi/databag"
	"github.com/ctdk/goiardi/environment"
	"github.com/ctdk/goiardi/indexer"
	"github.com/ctdk/goiardi/node"
	"github.com/ctdk/goiardi/reqctx"
	"github.com/ctdk/goiardi/role"
	"github.com/ctdk/goiardi/search"
	"github.com/ctdk/goiardi/util"
	"github.com/tideland/golib/logger"
	"net/http"
	"net/url"
	"os"
	"regexp"
	"strconv"
	"sync"
)

const ReindexableTypes = 5

var riM *sync.Mutex
var reindexNum = 0
var pid int

func init() {
	pid = os.Getpid()
	riM = new(sync.Mutex)
}

func searchHandler(w http.ResponseWriter, r *http.Request) {
	/* ... and we need search to run the environment tests, so here we
	 * go. */
	w.Header().Set("Content-Type", "application/json")

	searchResponse := make(map[string]interface{})
	pathArray := splitPath(r.URL.Path)
	pathArrayLen := len(pathArray)

	opUser, oerr := reqctx.CtxReqUser(r.Context())
	if oerr != nil {
		jsonErrorReport(w, r, oerr.Error(), oerr.Status())
		return
	}

	// if it's a HEAD response, just send back 200 no matter what, there's
	// no meaningful way to use HEAD with search that I can see
	if r.Method == http.MethodHead {
		if opUser.IsValidator() {
			headResponse(w, r, http.StatusForbidden)
			return
		}
		headDefaultResponse(w, r)
		return
	}

	/* set up query params for searching */
	var (
		paramQuery string
		paramsRows int
		sortOrder  string
		start      int
	)
	r.ParseForm()
	if q, found := r.Form["q"]; found {
		if len(q) < 0 {
			jsonErrorReport(w, r, "No query string specified for search", http.StatusBadRequest)
			return
		}
		paramQuery = q[0]
	} else if pathArrayLen != 1 {
		/* default to "*:*" for a search term */
		paramQuery = "*:*"
	}
	if pr, found := r.Form["rows"]; found {
		if len(pr) > 0 {
			paramsRows, _ = strconv.Atoi(pr[0])
		}
	} else {
		paramsRows = 1000
	}
	sortOrder = "id ASC"
	if s, found := r.Form["sort"]; found {
		if len(s) > 0 {
			if s[0] != "" {
				sortOrder = s[0]
			}
		} else {
			sortOrder = "id ASC"
		}
	}
	if st, found := r.Form["start"]; found {
		if len(st) > 0 {
			start, _ = strconv.Atoi(st[0])
		}
	} else {
		start = 0
	}

	var searcher search.Searcher
	if config.Config.PgSearch {
		searcher = &search.PostgresSearch{}
	} else {
		searcher = &search.TrieSearch{}
	}

	if pathArrayLen == 1 {
		/* base end points */
		switch r.Method {
		case http.MethodGet:
			if opUser.IsValidator() {
				jsonErrorReport(w, r, "You are not allowed to perform this action", http.StatusForbidden)
				return
			}
			searchEndpoints := searcher.GetEndpoints()
			for _, s := range searchEndpoints {
				searchResponse[s] = util.CustomURL(fmt.Sprintf("/search/%s", s))
			}
		default:
			jsonErrorReport(w, r, "Method not allowed", http.StatusMethodNotAllowed)
			return
		}
	} else if pathArrayLen == 2 {
		switch r.Method {
		case http.MethodGet, http.MethodPost:
			if opUser.IsValidator() {
				jsonErrorReport(w, r, "You are not allowed to perform this action", http.StatusForbidden)
				return
			}
			var qerr error
			paramQuery, qerr = url.QueryUnescape(paramQuery)
			if qerr != nil {
				jsonErrorReport(w, r, qerr.Error(), http.StatusBadRequest)
				return
			}
			/* start figuring out what comes in POSTS now,
			 * so the partial search tests don't complain
			 * anymore. */
			var partialData map[string]interface{}
			if r.Method == http.MethodPost {
				var perr error
				partialData, perr = parseObjJSON(r.Body)
				if perr != nil {
					jsonErrorReport(w, r, perr.Error(), http.StatusBadRequest)
					return
				}
			}

			idx := pathArray[1]
			res, err := searcher.Search(idx, paramQuery, paramsRows, sortOrder, start, partialData)

			if err != nil {
				statusCode := http.StatusBadRequest
				re := regexp.MustCompile(`^I don't know how to search for .*? data objects.`)
				if re.MatchString(err.Error()) {
					statusCode = http.StatusNotFound
				}
				jsonErrorReport(w, r, err.Error(), statusCode)
				return
			}

			searchResponse["total"] = len(res)
			searchResponse["start"] = start
			searchResponse["rows"] = res
		default:
			jsonErrorReport(w, r, "Method not allowed", http.StatusMethodNotAllowed)
			return
		}
	} else {
		/* Say what? Bad request. */
		jsonErrorReport(w, r, "Bad request", http.StatusBadRequest)
		return
	}

	enc := json.NewEncoder(w)
	if err := enc.Encode(&searchResponse); err != nil {
		jsonErrorReport(w, r, err.Error(), http.StatusInternalServerError)
	}
}

func reindexHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	reindexResponse := make(map[string]interface{})
	opUser, oerr := reqctx.CtxReqUser(r.Context())
	if oerr != nil {
		jsonErrorReport(w, r, oerr.Error(), oerr.Status())
		return
	}
	switch r.Method {
	case http.MethodPost:
		if !opUser.IsAdmin() {
			jsonErrorReport(w, r, "You are not allowed to perform that action.", http.StatusForbidden)
			return
		}
		go reindexAll()
		reindexResponse["reindex"] = "OK"
	default:
		jsonErrorReport(w, r, "Method not allowed. If you're trying to do something with a data bag named 'reindex', it's not going to work I'm afraid.", http.StatusMethodNotAllowed)
		return
	}
	enc := json.NewEncoder(w)
	if err := enc.Encode(&reindexResponse); err != nil {
		jsonErrorReport(w, r, err.Error(), http.StatusInternalServerError)
	}
}

func reindexAll() {
	// Take the mutex before starting to reindex everything. This way at
	// least reindexing jobs won't pile up on top of each other all trying
	// to execute simultaneously.
	rdex := reindexNum
	reindexNum++
	logger.Infof("Taking mutex for reindex %d ($$ %d)", rdex, pid)
	riM.Lock()
	logger.Infof("mutex acquired %d ($$ %d)", rdex, pid)
	rCh := make(chan struct{}, ReindexableTypes)
	defer func() {
		for u := 0; u < ReindexableTypes; u++ {
			<-rCh
			logger.Debugf("a reindexing goroutine finished")
		}
		logger.Infof("all reindexing goroutines finished, release reindexing mutex for %d ($$ %d)", rdex, pid)
		riM.Unlock()
		logger.Debugf("reindexing mutex for %d ($$ %d) unlocked", rdex, pid)
	}()

	// We clear the index, *then* do the fetch because if
	// something comes in between the time we fetch the
	// objects to reindex and when it gets done, they'll
	// just be added naturally
	logger.Infof("Clearing index for reindexing now")
	indexer.ClearIndex()

	// Send the objects to be reindexed in somewhat more manageable chunks
	clientObjs := make([]indexer.Indexable, 0, 100)
	for _, v := range client.AllClients() {
		clientObjs = append(clientObjs, v)
	}
	logger.Debugf("reindexing clients")
	indexer.ReIndex(clientObjs, rCh)

	nodeObjs := make([]indexer.Indexable, 0, 100)
	for _, v := range node.AllNodes() {
		nodeObjs = append(nodeObjs, v)
	}
	logger.Debugf("reindexing nodes")
	indexer.ReIndex(nodeObjs, rCh)

	roleObjs := make([]indexer.Indexable, 0, 100)
	for _, v := range role.AllRoles() {
		roleObjs = append(roleObjs, v)
	}
	logger.Debugf("reindexing roles")
	indexer.ReIndex(roleObjs, rCh)

	environmentObjs := make([]indexer.Indexable, 0, 100)
	for _, v := range environment.AllEnvironments() {
		environmentObjs = append(environmentObjs, v)
	}
	defaultEnv, _ := environment.Get("_default")
	environmentObjs = append(environmentObjs, defaultEnv)
	logger.Debugf("reindexing environments")
	indexer.ReIndex(environmentObjs, rCh)

	dbagObjs := make([]indexer.Indexable, 0, 100)
	// data bags have to be done separately
	dbags := databag.GetList()
	for _, db := range dbags {
		dbag, err := databag.Get(db)
		if err != nil {
			continue
		}
		dbis := make([]indexer.Indexable, dbag.NumDBItems())
		i := 0
		allDBItems, derr := dbag.AllDBItems()
		if derr != nil {
			logger.Errorf(derr.Error())
			continue
		}
		for _, k := range allDBItems {
			n := k
			dbis[i] = n
			i++
		}
		dbagObjs = append(dbagObjs, dbis...)
	}
	logger.Debugf("Reindexing data bags")
	indexer.ReIndex(dbagObjs, rCh)
	return
}
<commit_msg>fix reindexing with postgres - search index collections for data bags weren't being created<commit_after>/* Search functions */

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

package main

import (
	"encoding/json"
	"fmt"
	"github.com/ctdk/goiardi/client"
	"github.com/ctdk/goiardi/config"
	"github.com/ctdk/goiardi/databag"
	"github.com/ctdk/goiardi/environment"
	"github.com/ctdk/goiardi/indexer"
	"github.com/ctdk/goiardi/node"
	"github.com/ctdk/goiardi/reqctx"
	"github.com/ctdk/goiardi/role"
	"github.com/ctdk/goiardi/search"
	"github.com/ctdk/goiardi/util"
	"github.com/tideland/golib/logger"
	"net/http"
	"net/url"
	"os"
	"regexp"
	"strconv"
	"sync"
)

const ReindexableTypes = 5

var riM *sync.Mutex
var reindexNum = 0
var pid int

func init() {
	pid = os.Getpid()
	riM = new(sync.Mutex)
}

func searchHandler(w http.ResponseWriter, r *http.Request) {
	/* ... and we need search to run the environment tests, so here we
	 * go. */
	w.Header().Set("Content-Type", "application/json")

	searchResponse := make(map[string]interface{})
	pathArray := splitPath(r.URL.Path)
	pathArrayLen := len(pathArray)

	opUser, oerr := reqctx.CtxReqUser(r.Context())
	if oerr != nil {
		jsonErrorReport(w, r, oerr.Error(), oerr.Status())
		return
	}

	// if it's a HEAD response, just send back 200 no matter what, there's
	// no meaningful way to use HEAD with search that I can see
	if r.Method == http.MethodHead {
		if opUser.IsValidator() {
			headResponse(w, r, http.StatusForbidden)
			return
		}
		headDefaultResponse(w, r)
		return
	}

	/* set up query params for searching */
	var (
		paramQuery string
		paramsRows int
		sortOrder  string
		start      int
	)
	r.ParseForm()
	if q, found := r.Form["q"]; found {
		if len(q) < 0 {
			jsonErrorReport(w, r, "No query string specified for search", http.StatusBadRequest)
			return
		}
		paramQuery = q[0]
	} else if pathArrayLen != 1 {
		/* default to "*:*" for a search term */
		paramQuery = "*:*"
	}
	if pr, found := r.Form["rows"]; found {
		if len(pr) > 0 {
			paramsRows, _ = strconv.Atoi(pr[0])
		}
	} else {
		paramsRows = 1000
	}
	sortOrder = "id ASC"
	if s, found := r.Form["sort"]; found {
		if len(s) > 0 {
			if s[0] != "" {
				sortOrder = s[0]
			}
		} else {
			sortOrder = "id ASC"
		}
	}
	if st, found := r.Form["start"]; found {
		if len(st) > 0 {
			start, _ = strconv.Atoi(st[0])
		}
	} else {
		start = 0
	}

	var searcher search.Searcher
	if config.Config.PgSearch {
		searcher = &search.PostgresSearch{}
	} else {
		searcher = &search.TrieSearch{}
	}

	if pathArrayLen == 1 {
		/* base end points */
		switch r.Method {
		case http.MethodGet:
			if opUser.IsValidator() {
				jsonErrorReport(w, r, "You are not allowed to perform this action", http.StatusForbidden)
				return
			}
			searchEndpoints := searcher.GetEndpoints()
			for _, s := range searchEndpoints {
				searchResponse[s] = util.CustomURL(fmt.Sprintf("/search/%s", s))
			}
		default:
			jsonErrorReport(w, r, "Method not allowed", http.StatusMethodNotAllowed)
			return
		}
	} else if pathArrayLen == 2 {
		switch r.Method {
		case http.MethodGet, http.MethodPost:
			if opUser.IsValidator() {
				jsonErrorReport(w, r, "You are not allowed to perform this action", http.StatusForbidden)
				return
			}
			var qerr error
			paramQuery, qerr = url.QueryUnescape(paramQuery)
			if qerr != nil {
				jsonErrorReport(w, r, qerr.Error(), http.StatusBadRequest)
				return
			}
			/* start figuring out what comes in POSTS now,
			 * so the partial search tests don't complain
			 * anymore. */
			var partialData map[string]interface{}
			if r.Method == http.MethodPost {
				var perr error
				partialData, perr = parseObjJSON(r.Body)
				if perr != nil {
					jsonErrorReport(w, r, perr.Error(), http.StatusBadRequest)
					return
				}
			}

			idx := pathArray[1]
			res, err := searcher.Search(idx, paramQuery, paramsRows, sortOrder, start, partialData)

			if err != nil {
				statusCode := http.StatusBadRequest
				re := regexp.MustCompile(`^I don't know how to search for .*? data objects.`)
				if re.MatchString(err.Error()) {
					statusCode = http.StatusNotFound
				}
				jsonErrorReport(w, r, err.Error(), statusCode)
				return
			}

			searchResponse["total"] = len(res)
			searchResponse["start"] = start
			searchResponse["rows"] = res
		default:
			jsonErrorReport(w, r, "Method not allowed", http.StatusMethodNotAllowed)
			return
		}
	} else {
		/* Say what? Bad request. */
		jsonErrorReport(w, r, "Bad request", http.StatusBadRequest)
		return
	}

	enc := json.NewEncoder(w)
	if err := enc.Encode(&searchResponse); err != nil {
		jsonErrorReport(w, r, err.Error(), http.StatusInternalServerError)
	}
}

func reindexHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	reindexResponse := make(map[string]interface{})
	opUser, oerr := reqctx.CtxReqUser(r.Context())
	if oerr != nil {
		jsonErrorReport(w, r, oerr.Error(), oerr.Status())
		return
	}
	switch r.Method {
	case http.MethodPost:
		if !opUser.IsAdmin() {
			jsonErrorReport(w, r, "You are not allowed to perform that action.", http.StatusForbidden)
			return
		}
		go reindexAll()
		reindexResponse["reindex"] = "OK"
	default:
		jsonErrorReport(w, r, "Method not allowed. If you're trying to do something with a data bag named 'reindex', it's not going to work I'm afraid.", http.StatusMethodNotAllowed)
		return
	}
	enc := json.NewEncoder(w)
	if err := enc.Encode(&reindexResponse); err != nil {
		jsonErrorReport(w, r, err.Error(), http.StatusInternalServerError)
	}
}

func reindexAll() {
	// Take the mutex before starting to reindex everything. This way at
	// least reindexing jobs won't pile up on top of each other all trying
	// to execute simultaneously.
	rdex := reindexNum
	reindexNum++
	logger.Infof("Taking mutex for reindex %d ($$ %d)", rdex, pid)
	riM.Lock()
	logger.Infof("mutex acquired %d ($$ %d)", rdex, pid)
	rCh := make(chan struct{}, ReindexableTypes)
	defer func() {
		for u := 0; u < ReindexableTypes; u++ {
			<-rCh
			logger.Debugf("a reindexing goroutine finished")
		}
		logger.Infof("all reindexing goroutines finished, release reindexing mutex for %d ($$ %d)", rdex, pid)
		riM.Unlock()
		logger.Debugf("reindexing mutex for %d ($$ %d) unlocked", rdex, pid)
	}()

	// We clear the index, *then* do the fetch because if
	// something comes in between the time we fetch the
	// objects to reindex and when it gets done, they'll
	// just be added naturally
	logger.Infof("Clearing index for reindexing now")
	indexer.ClearIndex()

	// Send the objects to be reindexed in somewhat more manageable chunks
	clientObjs := make([]indexer.Indexable, 0, 100)
	for _, v := range client.AllClients() {
		clientObjs = append(clientObjs, v)
	}
	logger.Debugf("reindexing clients")
	indexer.ReIndex(clientObjs, rCh)

	nodeObjs := make([]indexer.Indexable, 0, 100)
	for _, v := range node.AllNodes() {
		nodeObjs = append(nodeObjs, v)
	}
	logger.Debugf("reindexing nodes")
	indexer.ReIndex(nodeObjs, rCh)

	roleObjs := make([]indexer.Indexable, 0, 100)
	for _, v := range role.AllRoles() {
		roleObjs = append(roleObjs, v)
	}
	logger.Debugf("reindexing roles")
	indexer.ReIndex(roleObjs, rCh)

	environmentObjs := make([]indexer.Indexable, 0, 100)
	for _, v := range environment.AllEnvironments() {
		environmentObjs = append(environmentObjs, v)
	}
	defaultEnv, _ := environment.Get("_default")
	environmentObjs = append(environmentObjs, defaultEnv)
	logger.Debugf("reindexing environments")
	indexer.ReIndex(environmentObjs, rCh)

	dbagObjs := make([]indexer.Indexable, 0, 100)
	// data bags have to be done separately
	dbags := databag.GetList()
	for _, db := range dbags {
		dbag, err := databag.Get(db)
		if err != nil {
			continue
		}
		// Don't forget to create the collections, because we weren't
		// for the postgres search index. (Somehow a regression snuck
		// in here, but what do you do?
		indexer.CreateNewCollection(dbag.GetName())
		dbis := make([]indexer.Indexable, dbag.NumDBItems())
		i := 0
		allDBItems, derr := dbag.AllDBItems()
		if derr != nil {
			logger.Errorf(derr.Error())
			continue
		}
		for _, k := range allDBItems {
			n := k
			dbis[i] = n
			i++
		}
		dbagObjs = append(dbagObjs, dbis...)
	}
	logger.Debugf("Reindexing data bags")
	indexer.ReIndex(dbagObjs, rCh)
	return
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

// Root node search.
func (p *Position) search(alpha, beta, depth int) (score int) {
	ply := 0

	inCheck := p.isInCheck(p.color)
	cacheFlags := uint8(cacheAlpha)

	// Root move generator makes sure all generated moves are valid.
	gen := NewRootGen(p, depth)
	if depth == 1 {
		gen.generateRootMoves()
	} else {
		gen.rearrangeRootMoves()
	}

	moveCount, bestMove := 0, Move(0)
	for move := gen.NextMove(); move != 0; move = gen.NextMove() {
		position := p.MakeMove(move)
		moveCount++

		// Search depth extension.
		newDepth := depth - 1
		if position.isInCheck(p.color^1) { // Give check.
			newDepth++
		}

		if moveCount == 1 {
			score = -position.searchTree(-beta, -alpha, newDepth)
		} else {
			score = -position.searchTree(-alpha - 1, -alpha, newDepth)
			if score > alpha && score < beta {
				score = -position.searchTree(-beta, -alpha, newDepth)
			}
		}
		position.UndoLastMove()

		if p.game.clock.halt {
			p.game.nodes += moveCount
			//Log("searchRoot: bestMove %s pv[0][0] %s alpha %d\n", bestMove, p.game.pv[0][0], alpha)
			return alpha
		}

		if moveCount == 1 {
			bestMove = move
			p.game.pv[ply] = p.game.pv[ply][:0]
			p.game.saveBest(ply, move)
		}

		if score > alpha {
			alpha = score
			bestMove = move
			cacheFlags = cacheExact
			p.game.saveBest(ply, move)

			if alpha >= beta {
				cacheFlags = cacheBeta
				break
			}
		}
	}

	p.game.nodes += moveCount

	if moveCount == 0 {
		if inCheck {
			alpha = -Checkmate + ply
		} else {
			alpha = 0
		}
	} else if score >= beta && !inCheck {
		p.game.saveGood(depth, bestMove)
	}

	score = alpha
	p.cache(bestMove, score, depth, cacheFlags)

	return
}

// Testing helper method to test root search.
func (p *Position) solve(depth int) Move {
	if depth != 1 {
		NewRootGen(p, 1).generateRootMoves()
	}
	p.search(-Checkmate, Checkmate, depth)
	return p.game.pv[0][0]
}

func (p *Position) Perft(depth int) (total int64) {
	if depth == 0 {
		return 1
	}

	gen := NewGen(p, depth).generateAllMoves()
	for move := gen.NextMove(); move != 0; move = gen.NextMove() {
		if !gen.isValid(move) {
			continue
		}
		position := p.MakeMove(move)
		total += position.Perft(depth - 1)
		position.UndoLastMove()
	}
	return
}
<commit_msg>Minor root search cleanup<commit_after>// Copyright (c) 2013-2014 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

// Root node search.
func (p *Position) search(alpha, beta, depth int) (score int) {
	inCheck := p.isInCheck(p.color)
	cacheFlags := uint8(cacheAlpha)

	// Root move generator makes sure all generated moves are valid.
	gen := NewRootGen(p, depth)
	if depth == 1 {
		gen.generateRootMoves()
	} else {
		gen.rearrangeRootMoves()
	}

	moveCount, bestMove := 0, Move(0)
	for move := gen.NextMove(); move != 0; move = gen.NextMove() {
		position := p.MakeMove(move)
		moveCount++

		// Search depth extension.
		newDepth := depth - 1
		if position.isInCheck(p.color^1) { // Give check.
			newDepth++
		}

		if moveCount == 1 {
			score = -position.searchTree(-beta, -alpha, newDepth)
		} else {
			score = -position.searchTree(-alpha - 1, -alpha, newDepth)
			if score > alpha && score < beta {
				score = -position.searchTree(-beta, -alpha, newDepth)
			}
		}
		position.UndoLastMove()

		if p.game.clock.halt {
			p.game.nodes += moveCount
			//Log("searchRoot: bestMove %s pv[0][0] %s alpha %d\n", bestMove, p.game.pv[0][0], alpha)
			return alpha
		}

		if moveCount == 1 {
			bestMove = move
			p.game.pv[0] = p.game.pv[0][:0]
			p.game.saveBest(0, move)
		}

		if score > alpha {
			alpha = score
			bestMove = move
			cacheFlags = cacheExact
			p.game.saveBest(0, move)

			if alpha >= beta {
				cacheFlags = cacheBeta
				break
			}
		}
	}

	p.game.nodes += moveCount

	if moveCount == 0 {
		if inCheck {
			alpha = -Checkmate
		} else {
			alpha = 0
		}
	} else if score >= beta && !inCheck {
		p.game.saveGood(depth, bestMove)
	}

	score = alpha
	p.cache(bestMove, score, depth, cacheFlags)

	return
}

// Testing helper method to test root search.
func (p *Position) solve(depth int) Move {
	if depth != 1 {
		NewRootGen(p, 1).generateRootMoves()
	}
	p.search(-Checkmate, Checkmate, depth)
	return p.game.pv[0][0]
}

func (p *Position) Perft(depth int) (total int64) {
	if depth == 0 {
		return 1
	}

	gen := NewGen(p, depth).generateAllMoves()
	for move := gen.NextMove(); move != 0; move = gen.NextMove() {
		if !gen.isValid(move) {
			continue
		}
		position := p.MakeMove(move)
		total += position.Perft(depth - 1)
		position.UndoLastMove()
	}
	return
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/WhiteHatCP/seclab-listener/backend"
	"github.com/WhiteHatCP/seclab-listener/server"
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"
)

const (
	maxPacketAge = 10
)

func main() {
	if len(os.Args)%3 != 2 {
		fmt.Fprintf(os.Stderr, "usage: seclab key [dest open closed [..]]\n")
		return
	}
	keypath := os.Args[1]
	s := server.New(keypath, maxPacketAge)

	for i := 2; i+2 < len(os.Args); i += 3 {
		dest := os.Args[i]
		openfile := os.Args[i+1]
		closedfile := os.Args[i+2]
		s.AddBackend(backend.New(dest, openfile, closedfile))
	}

	syscall.Umask(0007)

	socket := "seclab.sock"
	ln, err := net.Listen("unix", socket)
	syscall.Chmod(socket, 0770)
	if err != nil {
		log.Fatal(err)
	}
	defer ln.Close()

	// Make sure the socket closes
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		for _ = range c {
			ln.Close()
		}
	}()

	s.Serve(ln)
}
<commit_msg>Try to remove the unix socket before creating<commit_after>package main

import (
	"fmt"
	"github.com/WhiteHatCP/seclab-listener/backend"
	"github.com/WhiteHatCP/seclab-listener/server"
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"
)

const (
	maxPacketAge = 10
)

func openSock(path string) (net.Listener, error) {
	if err := syscall.Unlink(path); err != nil && err != syscall.EEXIST {
		return nil, err
	}
	ln, err := net.Listen("unix", socket)
	if err != nil {
		return nil, err
	}
	if err := syscall.Chmod(path, 0770); err != nil {
		return nil, err
	}
	return ln, nil
}

func main() {
	if len(os.Args)%3 != 2 {
		fmt.Fprintf(os.Stderr, "usage: seclab key [dest open closed [..]]\n")
		return
	}
	keypath := os.Args[1]
	s := server.New(keypath, maxPacketAge)

	for i := 2; i+2 < len(os.Args); i += 3 {
		dest := os.Args[i]
		openfile := os.Args[i+1]
		closedfile := os.Args[i+2]
		s.AddBackend(backend.New(dest, openfile, closedfile))
	}

	syscall.Umask(0007)

	socket := "seclab.sock"
	ln, err := openSock(socket)
	if err != nil {
		log.Fatal(err)
	}
	defer ln.Close()

	// Make sure the socket closes
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		for _ = range c {
			ln.Close()
		}
	}()

	s.Serve(ln)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"code.google.com/p/go.crypto/openpgp"
	"encoding/base64"
	"flag"
	"fmt"
	"github.com/howeyc/gopass"
	"io/ioutil"
	"log"
	"os"
)

// Commmand line arguments
var verbose = flag.Bool("v", false, "Make the output verbose.")

// create gpg keys with
// $ gpg --gen-key
// ensure you correct paths and passphrase

const mysecretstring = "this is so very secret!"
const prefix = "/Users/peter/"
const secretKeyring = prefix + ".gnupg/secring.gpg"
const publicKeyring = prefix + ".gnupg/pubring.gpg"

func encryptMessage() error {
	fmt.Println("Secret:", mysecretstring)

	// Read in public key
	keyringFileBuffer, _ := os.Open(publicKeyring)
	defer keyringFileBuffer.Close()
	entitylist, err := openpgp.ReadKeyRing(keyringFileBuffer)
	if err != nil {
		return err
	}

	// Encrypt string
	buf := new(bytes.Buffer)
	w, err := openpgp.Encrypt(buf, entitylist, nil, nil, nil)
	if err != nil {
		return err
	}
	_, err = w.Write([]byte(mysecretstring))
	if err != nil {
		return err
	}
	err = w.Close()
	if err != nil {
		return err
	}

	// Encode to base64
	bytesp, err := ioutil.ReadAll(buf)
	if err != nil {
		return err
	}
	encstr := base64.StdEncoding.EncodeToString(bytesp)

	// Output encrypted/encoded string
	if *verbose {
		fmt.Println("Encrypted Secret:", encstr)
	}

	// Here is where I would transfer the encrypted string to someone else
	// but we'll just decrypt it in the same code

	// Init some vars
	var entity2 *openpgp.Entity
	var entitylist2 openpgp.EntityList

	// Open the private key file
	keyringFileBuffer2, err := os.Open(secretKeyring)
	if err != nil {
		return err
	}
	defer keyringFileBuffer2.Close()
	entitylist2, err = openpgp.ReadKeyRing(keyringFileBuffer2)
	if err != nil {
		return err
	}
	entity2 = entitylist2[0]

	// Get the passphrase and read the private key.
	// Have not touched the encrypted string yet
	if *verbose {
		fmt.Println("Decrypting private key using passphrase")
	}
	if !decryptKey(entity2) {
		fmt.Println("Incorrect password. Exiting.")
		return nil
	}
	//for !decryptKey(entity2) {
	//}
	if *verbose {
		fmt.Println("Finished decrypting private key using passphrase")
	}

	// Decode the base64 string
	dec, err := base64.StdEncoding.DecodeString(encstr)
	if err != nil {
		return err
	}

	// Decrypt it with the contents of the private key
	md, err := openpgp.ReadMessage(bytes.NewBuffer(dec), entitylist2, nil, nil)
	if err != nil {
		return err
	}
	bytess, err := ioutil.ReadAll(md.UnverifiedBody)
	if err != nil {
		return err
	}
	decstr := string(bytess)

	// Should be done
	fmt.Println("Decrypted Secret:", decstr)

	return nil
}

func decryptKey(entity *openpgp.Entity) bool {
	// Get the password
	fmt.Printf("Password: ")
	passphrase := gopass.GetPasswd()
	passphrasebyte := []byte(passphrase)

	// Decrypt the key and subkeys
	err := entity.PrivateKey.Decrypt(passphrasebyte)
	if err != nil {
		return false
	}
	for _, subkey := range entity.Subkeys {
		err := subkey.PrivateKey.Decrypt(passphrasebyte)
		if err != nil {
			return false
		}
	}

	return true
}

func main() {
	// Parse command line arguments
	flag.Parse()

	err := encryptMessage()
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Use go-flags instead of flag for argument parsing.<commit_after>package main

import (
	"bytes"
	"code.google.com/p/go.crypto/openpgp"
	"encoding/base64"
	"fmt"
	"github.com/howeyc/gopass"
	"github.com/jessevdk/go-flags"
	"io/ioutil"
	"log"
	"os"
)

// Commmand line arguments
var options struct {
	Verbose bool `short:"v" long:"verbose" description:"make the output verbose"`
}

// create gpg keys with
// $ gpg --gen-key
// ensure you correct paths and passphrase

const mysecretstring = "this is so very secret!"
const prefix = "/Users/peter/"
const secretKeyring = prefix + ".gnupg/secring.gpg"
const publicKeyring = prefix + ".gnupg/pubring.gpg"

func encryptMessage() error {
	fmt.Println("Secret:", mysecretstring)

	// Read in public key
	keyringFileBuffer, _ := os.Open(publicKeyring)
	defer keyringFileBuffer.Close()
	entitylist, err := openpgp.ReadKeyRing(keyringFileBuffer)
	if err != nil {
		return err
	}

	// Encrypt string
	buf := new(bytes.Buffer)
	w, err := openpgp.Encrypt(buf, entitylist, nil, nil, nil)
	if err != nil {
		return err
	}
	_, err = w.Write([]byte(mysecretstring))
	if err != nil {
		return err
	}
	err = w.Close()
	if err != nil {
		return err
	}

	// Encode to base64
	bytesp, err := ioutil.ReadAll(buf)
	if err != nil {
		return err
	}
	encstr := base64.StdEncoding.EncodeToString(bytesp)

	// Output encrypted/encoded string
	if options.Verbose {
		fmt.Println("Encrypted Secret:", encstr)
	}

	// Here is where I would transfer the encrypted string to someone else
	// but we'll just decrypt it in the same code

	// Init some vars
	var entity2 *openpgp.Entity
	var entitylist2 openpgp.EntityList

	// Open the private key file
	keyringFileBuffer2, err := os.Open(secretKeyring)
	if err != nil {
		return err
	}
	defer keyringFileBuffer2.Close()
	entitylist2, err = openpgp.ReadKeyRing(keyringFileBuffer2)
	if err != nil {
		return err
	}
	entity2 = entitylist2[0]

	// Get the passphrase and read the private key.
	// Have not touched the encrypted string yet
	if options.Verbose {
		fmt.Println("Decrypting private key using passphrase")
	}
	if !decryptKey(entity2) {
		fmt.Println("Incorrect password. Exiting.")
		return nil
	}
	//for !decryptKey(entity2) {
	//}
	if options.Verbose {
		fmt.Println("Finished decrypting private key using passphrase")
	}

	// Decode the base64 string
	dec, err := base64.StdEncoding.DecodeString(encstr)
	if err != nil {
		return err
	}

	// Decrypt it with the contents of the private key
	md, err := openpgp.ReadMessage(bytes.NewBuffer(dec), entitylist2, nil, nil)
	if err != nil {
		return err
	}
	bytess, err := ioutil.ReadAll(md.UnverifiedBody)
	if err != nil {
		return err
	}
	decstr := string(bytess)

	// Should be done
	fmt.Println("Decrypted Secret:", decstr)

	return nil
}

func decryptKey(entity *openpgp.Entity) bool {
	// Get the password
	fmt.Printf("Password: ")
	passphrase := gopass.GetPasswd()
	passphrasebyte := []byte(passphrase)

	// Decrypt the key and subkeys
	err := entity.PrivateKey.Decrypt(passphrasebyte)
	if err != nil {
		return false
	}
	for _, subkey := range entity.Subkeys {
		err := subkey.PrivateKey.Decrypt(passphrasebyte)
		if err != nil {
			return false
		}
	}

	return true
}

func main() {
	// Parse command line arguments
	_, err := flags.Parse(&options)
	if err != nil {
		return
	}

	err = encryptMessage()
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package semver

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"strconv"
	"strings"
)

const (
	dot        = "."
	hyphen     = "-"
	plus       = "+"
	delimiters = dot + hyphen + plus
)

type VersionGetter interface {
	Major() uint64
	Minor() uint64
	Patch() uint64
	Prerelease() string
	PrerelaseIdentifiers() []string
	Metadata() string
	MetadataIdentifiers() []string
}

type VersionSetter interface {
	SetPrerelease(...string) error
	SetMetadata(...string) error
	SetMajor(uint64)
	SetMinor(uint64)
	SetPatch(uint64)
}

type VersionGetterSetter interface {
	VersionGetter
	VersionSetter
}

type Version struct {
	major      uint64
	minor      uint64
	patch      uint64
	prerelease *prereleases
	metadata   []string
}

type prereleases struct {
	values  []string
	numbers map[int]uint64
}

func Build(major, minor, patch uint64, extra ...[]string) *Version {
	if len(extra) == 1 {
		ver := &Version{major, minor, patch, nil, nil}
		ver.SetPrerelease(extra[0]...)
		return ver
	}
	if len(extra) > 1 {
		ver := &Version{major, minor, patch, nil, extra[1]}
		ver.SetPrerelease(extra[0]...)
		return ver
	}
	return &Version{major, minor, patch, nil, nil}
}

func New(version string) (*Version, error) {
	var versions []string
	var prereleases []string
	var metadatas []string

	result := new(Version)

	if strings.Contains(version, plus) {
		metadata := strings.Split(version, plus)
		metadatas = strings.Split(metadata[1], dot)

		if err := result.SetMetadata(metadatas...); err != nil {
			return nil, err
		}

		version = metadata[0]
	}

	if strings.Contains(version, hyphen) {
		prerelease := strings.Split(version, hyphen)
		prereleases = strings.Split(prerelease[1], dot)

		if err := result.SetPrerelease(prereleases...); err != nil {
			return nil, err
		}

		version = prerelease[0]
	}

	versions = strings.Split(version, dot)
	if len(versions) != 3 {
		return nil, errors.New("major.minor.patch pattern not found")
	}

	var versionNumbers [3]uint64
	for i, partial := range versions {

		if num, err := strconv.ParseUint(partial, 10, 0); err != nil {
			return nil, errors.New(fmt.Sprint("expected unsigned integer: ", partial))
		} else {
			if hasLeadingZero(partial) {
				return nil, errors.New(fmt.Sprint("leading zeroes in version number: ", partial))
			}
			versionNumbers[i] = num
		}
	}

	result.major = versionNumbers[0]
	result.minor = versionNumbers[1]
	result.patch = versionNumbers[2]

	return result, nil
}

func (v Version) String() string {
	var buffer bytes.Buffer
	w := bufio.NewWriter(&buffer)

	fmt.Fprintf(w, "%d.%d.%d", v.major, v.minor, v.patch)

	if v.prerelease != nil {
		fmt.Fprintf(w, "%v%v", hyphen, v.Prerelease())
	}

	if v.metadata != nil {
		fmt.Fprintf(w, "%v%v", plus, v.Metadata())
	}

	w.Flush()
	return buffer.String()
}

func (v Version) Major() uint64 {
	return v.major
}

func (v *Version) SetMajor(major uint64) {
	v.major = major
}

func (v Version) Minor() uint64 {
	return v.minor
}

func (v *Version) SetMinor(minor uint64) {
	v.minor = minor
}

func (v Version) Patch() uint64 {
	return v.patch
}

func (v *Version) SetPatch(patch uint64) {
	v.patch = patch
}

func (v Version) Prerelease() string {
	return strings.Join(v.prerelease.values, dot)
}

func (v *Version) SetPrerelease(identifiers ...string) error {
	var result []string
	numbers := make(map[int]uint64)

	for i, ident := range identifiers {
		if len(ident) < 1 {
			return errors.New("identifier is empty")
		}

		if num, err := strconv.ParseUint(ident, 10, 0); err == nil {
			if hasLeadingZero(ident) {
				return errors.New(fmt.Sprint("leading zeroes in numerical identifier: ", ident))
			}
			numbers[i] = num
			result = append(result, ident)
		} else {
			if !containsOnly(ident, alphanumeric) {
				return errors.New(fmt.Sprint("not alphanumerical: ", ident))
			}
			result = append(result, ident)
		}
	}
	pre := &prereleases{result, numbers}
	v.prerelease = pre
	return nil
}

func (v Version) Metadata() string {
	return strings.Join(v.metadata, dot)
}

func (v *Version) SetMetadata(identifiers ...string) error {
	var result []string

	for _, ident := range identifiers {
		if len(ident) < 1 {
			return errors.New("identifier is empty")
		}

		if !containsOnly(ident, alphanumeric) {
			return errors.New(fmt.Sprint("not alphanumerical: ", ident))
		}
		result = append(result, ident)
	}

	v.metadata = result
	return nil
}

func (v Version) Satifies(other string) bool {
	return true
}
<commit_msg>Fixed Prerelease hyphen bug.<commit_after>package semver

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"strconv"
	"strings"
)

const (
	dot        = "."
	hyphen     = "-"
	plus       = "+"
	delimiters = dot + hyphen + plus
)

type VersionGetter interface {
	Major() uint64
	Minor() uint64
	Patch() uint64
	Prerelease() string
	PrerelaseIdentifiers() []string
	Metadata() string
	MetadataIdentifiers() []string
}

type VersionSetter interface {
	SetPrerelease(...string) error
	SetMetadata(...string) error
	SetMajor(uint64)
	SetMinor(uint64)
	SetPatch(uint64)
}

type VersionGetterSetter interface {
	VersionGetter
	VersionSetter
}

type Version struct {
	major      uint64
	minor      uint64
	patch      uint64
	prerelease *prereleases
	metadata   []string
}

type prereleases struct {
	values  []string
	numbers map[int]uint64
}

func Build(major, minor, patch uint64, extra ...[]string) *Version {
	if len(extra) == 1 {
		ver := &Version{major, minor, patch, nil, nil}
		ver.SetPrerelease(extra[0]...)
		return ver
	}
	if len(extra) > 1 {
		ver := &Version{major, minor, patch, nil, extra[1]}
		ver.SetPrerelease(extra[0]...)
		return ver
	}
	return &Version{major, minor, patch, nil, nil}
}

func New(version string) (*Version, error) {
	var versions []string
	var prereleases []string
	var metadatas []string

	result := new(Version)

	if strings.Contains(version, plus) {
		metadata := strings.Split(version, plus)
		metadatas = strings.Split(metadata[1], dot)

		if err := result.SetMetadata(metadatas...); err != nil {
			return nil, err
		}

		version = metadata[0]
	}

	if strings.Contains(version, hyphen) {
		prerelease := strings.SplitN(version, hyphen, 2)
		prereleases = strings.Split(prerelease[1], dot)

		if err := result.SetPrerelease(prereleases...); err != nil {
			return nil, err
		}

		version = prerelease[0]
	}

	versions = strings.Split(version, dot)
	if len(versions) != 3 {
		return nil, errors.New("major.minor.patch pattern not found")
	}

	var versionNumbers [3]uint64
	for i, partial := range versions {

		if num, err := strconv.ParseUint(partial, 10, 0); err != nil {
			return nil, errors.New(fmt.Sprint("expected unsigned integer: ", partial))
		} else {
			if hasLeadingZero(partial) {
				return nil, errors.New(fmt.Sprint("leading zeroes in version number: ", partial))
			}
			versionNumbers[i] = num
		}
	}

	result.major = versionNumbers[0]
	result.minor = versionNumbers[1]
	result.patch = versionNumbers[2]

	return result, nil
}

func (v Version) String() string {
	var buffer bytes.Buffer
	w := bufio.NewWriter(&buffer)

	fmt.Fprintf(w, "%d.%d.%d", v.major, v.minor, v.patch)

	if v.prerelease != nil {
		fmt.Fprintf(w, "%v%v", hyphen, v.Prerelease())
	}

	if v.metadata != nil {
		fmt.Fprintf(w, "%v%v", plus, v.Metadata())
	}

	w.Flush()
	return buffer.String()
}

func (v Version) Major() uint64 {
	return v.major
}

func (v *Version) SetMajor(major uint64) {
	v.major = major
}

func (v Version) Minor() uint64 {
	return v.minor
}

func (v *Version) SetMinor(minor uint64) {
	v.minor = minor
}

func (v Version) Patch() uint64 {
	return v.patch
}

func (v *Version) SetPatch(patch uint64) {
	v.patch = patch
}

func (v Version) Prerelease() string {
	return strings.Join(v.prerelease.values, dot)
}

func (v *Version) SetPrerelease(identifiers ...string) error {
	var result []string
	numbers := make(map[int]uint64)

	for i, ident := range identifiers {
		if len(ident) < 1 {
			return errors.New("identifier is empty")
		}

		if num, err := strconv.ParseUint(ident, 10, 0); err == nil {
			if hasLeadingZero(ident) {
				return errors.New(fmt.Sprint("leading zeroes in numerical identifier: ", ident))
			}
			numbers[i] = num
			result = append(result, ident)
		} else {
			if !containsOnly(ident, alphanumeric) {
				return errors.New(fmt.Sprint("not alphanumerical: ", ident))
			}
			result = append(result, ident)
		}
	}
	pre := &prereleases{result, numbers}
	v.prerelease = pre
	return nil
}

func (v Version) Metadata() string {
	return strings.Join(v.metadata, dot)
}

func (v *Version) SetMetadata(identifiers ...string) error {
	var result []string

	for _, ident := range identifiers {
		if len(ident) < 1 {
			return errors.New("identifier is empty")
		}

		if !containsOnly(ident, alphanumeric) {
			return errors.New(fmt.Sprint("not alphanumerical: ", ident))
		}
		result = append(result, ident)
	}

	v.metadata = result
	return nil
}

func (v Version) Satifies(other string) bool {
	return true
}
<|endoftext|>