<commit_before>package admin

import (
	"net/http"
	"strings"

	"github.com/qor/qor"
	"github.com/qor/qor/roles"
)

type Handle func(c *Context)

type Router struct {
	Prefix  string
	gets    map[string]Handle
	posts   map[string]Handle
	deletes map[string]Handle
	puts    map[string]Handle
}

func newRouter() *Router {
	return &Router{
		gets:    map[string]Handle{},
		posts:   map[string]Handle{},
		deletes: map[string]Handle{},
		puts:    map[string]Handle{},
	}
}

// Possible path types
// /admin/orders
// /admin/orders/new
// /admin/orders/123
func (r *Router) parsePath(path string) (res, id string) {
	parts := strings.Split(strings.TrimLeft(path, r.Prefix), "/")
	// fmt.Printf("--> %+v\n", parts)
	for _, part := range parts {
		if part != "" && res == "" {
			res = part
			continue
		}

		if part != "" && id == "" {
			id = part
			break
		}
	}

	return
}

func (r *Router) Get(path string, handle Handle) {
	r.gets[path] = handle
}

func (r *Router) Post(path string, handle Handle) {
	r.posts[path] = handle
}

func (r *Router) Put(path string, handle Handle) {
	r.puts[path] = handle
}

func (r *Router) Delete(path string, handle Handle) {
	r.deletes[path] = handle
}

func (admin *Admin) NewContext(w http.ResponseWriter, r *http.Request) *Context {
	var currentUser *qor.CurrentUser
	context := Context{Context: &qor.Context{Config: admin.Config, Request: r}, Writer: w}
	if admin.auth != nil {
		currentUser = admin.auth.GetCurrentUser(&context)
	}
	context.Roles = roles.MatchedRoles(r, currentUser)
	return &context
}

// TODO: to extend this api
func (admin *Admin) MountTo(prefix string, mux *http.ServeMux) {
	prefix = "/" + strings.Trim(prefix, "/")
	router := admin.router
	router.Prefix = prefix + "/"

	mux.Handle(prefix, admin)        // /:prefix
	mux.Handle(router.Prefix, admin) // /:prefix/:xxx
}

func (admin *Admin) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// 128 MB
	req.ParseMultipartForm(32 << 22)
	if len(req.Form["_method"]) > 0 {
		req.Method = strings.ToUpper(req.Form["_method"][0])
	}

	var (
		router          = admin.router
		context         = admin.NewContext(w, req)
		builtin, custom Handle
	)

	context.ResourceName, context.ResourceID = router.parsePath(req.URL.Path)
	// fmt.Printf("--> %+v\n", req.URL.Path)
	// fmt.Printf("--> %+v\n", context.ResourceName, context.ResourceID)
	if context.ResourceName == "" && context.ResourceID == "" {
		builtin = admin.Dashboard
	} else if context.ResourceID == "new" {
		// /admin/:ressource/new
		switch req.Method {
		case "GET":
			custom = router.gets["/"+context.ResourceName+"/new"]
			builtin = admin.New
		}
	} else if context.ResourceName != "" && context.ResourceID == "" {
		// /admin/:ressource
		switch req.Method {
		case "GET":
			custom = router.gets["/"+context.ResourceName]
			builtin = admin.Index
		case "POST":
			custom = router.posts["/"+context.ResourceName]
			builtin = admin.Create
		case "PUT":
			custom = router.puts["/"+context.ResourceName+"/new"]
			builtin = admin.Create
		}
	} else if context.ResourceName != "" && context.ResourceID != "" {
		// /admin/:ressource/:id
		switch req.Method {
		case "GET":
			custom = router.gets["/"+context.ResourceName+"/:id"]
			builtin = admin.Show
		case "POST":
			custom = router.posts["/"+context.ResourceName+"/:id"]
			builtin = admin.Update
		case "PUT":
			custom = router.puts["/"+context.ResourceName+"/:id"]
			builtin = admin.Update
		case "DELETE":
			custom = router.deletes["/"+context.ResourceName+"/:id"]
			builtin = admin.Delete
		}
	}

	if custom != nil {
		custom(context)
	} else if builtin != nil {
		builtin(context)
	} else {
		http.NotFound(w, req)
	}
}
<commit_msg>Refactor qor router<commit_after>package admin

import (
	"net/http"
	"path"
	"regexp"
	"strings"

	"github.com/qor/qor"
	"github.com/qor/qor/roles"
)

type Handle func(c *Context)
type Handler struct {
	Path   *regexp.Regexp
	Handle Handle
}

type Router struct {
	Prefix  string
	routers map[string][]Handler
}

func newRouter() *Router {
	return &Router{routers: map[string][]Handler{
		"GET":    []Handler{},
		"PUT":    []Handler{},
		"POST":   []Handler{},
		"DELETE": []Handler{},
	}}
}

func (r *Router) Get(path string, handle Handle) {
	r.routers["GET"] = append(r.routers["GET"], Handler{Path: regexp.MustCompile(path), Handle: handle})
}

func (r *Router) Post(path string, handle Handle) {
	r.routers["POST"] = append(r.routers["POST"], Handler{Path: regexp.MustCompile(path), Handle: handle})
}

func (r *Router) Put(path string, handle Handle) {
	r.routers["PUT"] = append(r.routers["PUT"], Handler{Path: regexp.MustCompile(path), Handle: handle})
}

func (r *Router) Delete(path string, handle Handle) {
	r.routers["DELETE"] = append(r.routers["DELETE"], Handler{Path: regexp.MustCompile(path), Handle: handle})
}

func (admin *Admin) NewContext(w http.ResponseWriter, r *http.Request) *Context {
	var currentUser *qor.CurrentUser
	context := Context{Context: &qor.Context{Config: admin.Config, Request: r}, Writer: w}
	if admin.auth != nil {
		currentUser = admin.auth.GetCurrentUser(&context)
	}
	context.Roles = roles.MatchedRoles(r, currentUser)
	return &context
}

func (admin *Admin) MountTo(prefix string, mux *http.ServeMux) {
	prefix = "/" + strings.Trim(prefix, "/")
	router := admin.router
	router.Prefix = prefix

	router.Get("^/$", admin.Dashboard)
	router.Get("^$", admin.Dashboard)
	router.Get("^/[^/]+/new$", admin.New)
	router.Put("^/[^/]+/new$", admin.Create)
	router.Post("^/[^/]+/new$", admin.Create)
	router.Get("^/[^/]+/.*$", admin.Show)
	router.Put("^/[^/]+/.*$", admin.Update)
	router.Post("^/[^/]+/.*$", admin.Update)
	router.Delete("^/[^/]+/.*$", admin.Delete)
	router.Get("^/[^/]+$", admin.Index)

	mux.Handle(prefix, admin)     // /:prefix
	mux.Handle(prefix+"/", admin) // /:prefix/:xxx
}

func (admin *Admin) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// 128 MB
	req.ParseMultipartForm(32 << 22)
	if len(req.Form["_method"]) > 0 {
		req.Method = strings.ToUpper(req.Form["_method"][0])
	}

	var router = admin.router
	var context = admin.NewContext(w, req)

	var pathMatch = regexp.MustCompile(path.Join(router.Prefix, `(\w+)(?:/(\w+))?[^/]*/?$`))
	var matches = pathMatch.FindStringSubmatch(req.URL.Path)
	if len(matches) > 1 {
		context.ResourceName = matches[1]
		if len(matches) > 2 {
			context.ResourceName = matches[2]
		}
	}

	routers := router.routers[strings.ToUpper(req.Method)]
	relativePath := strings.TrimPrefix(req.URL.Path, router.Prefix)
	for _, handler := range routers {
		if handler.Path.MatchString(relativePath) {
			handler.Handle(context)
			return
		}
	}
	http.NotFound(w, req)
}
<|endoftext|>


<commit_before>// Pckage cbc supports cbc encryption
package cbc

// https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_.28CBC.29

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha256"

	"io"

	"github.com/alistanis/goenc/encerrors"
	"github.com/alistanis/goenc/generate"
)

const (
	// NonceSize to use for nonces
	NonceSize = aes.BlockSize
	// MACSize is the output size of HMAC-SHA-256
	MACSize = 32
	// CKeySize - Cipher key size - AES-256
	CKeySize = 32
	// MKeySize - HMAC key size - HMAC-SHA-256
	MKeySize = 32
	// KeySize is the key size for CBC
	KeySize = CKeySize + MKeySize
)

// pad pads input to match the correct size
func pad(in []byte) []byte {
	padding := 16 - (len(in) % 16)
	for i := 0; i < padding; i++ {
		in = append(in, byte(padding))
	}
	return in
}

// unpad removes unnecessary bytes that were added during initial padding
func unpad(in []byte) []byte {
	if len(in) == 0 {
		return nil
	}

	padding := in[len(in)-1]
	if int(padding) > len(in) || padding > aes.BlockSize {
		return nil
	} else if padding == 0 {
		return nil
	}

	for i := len(in) - 1; i > len(in)-int(padding)-1; i-- {
		if in[i] != padding {
			return nil
		}
	}
	return in[:len(in)-int(padding)]
}

// Cipher implements the BlockCipher interface
type Cipher struct{}

// Encrypt implements the BlockCipher interface
func (c *Cipher) Encrypt(key, plaintext []byte) ([]byte, error) {
	return Encrypt(key, plaintext)
}

// Decrypt implements the BlockCipher interface
func (c *Cipher) Decrypt(key, ciphertext []byte) ([]byte, error) {
	return Decrypt(key, ciphertext)
}

// KeySize returns CBC KeySize and implements the BlockCipher interface
func (c *Cipher) KeySize() int {
	return KeySize
}

// New returns a new cbc cipher
func New() *Cipher {
	return &Cipher{}
}

// Key returns a random key as a pointer to an array of bytes specified by KeySize
func Key() (*[KeySize]byte, error) {
	key := new([KeySize]byte)
	_, err := io.ReadFull(rand.Reader, key[:])
	return key, err
}

// Encrypt encrypts plaintext using the given key with CBC encryption
func Encrypt(key, plaintext []byte) ([]byte, error) {
	if len(key) != KeySize {
		return nil, encerrors.ErrInvalidKeyLength
	}

	iv, err := generate.RandBytes(NonceSize)
	if err != nil {
		return nil, err
	}

	pmessage := pad(plaintext)
	ct := make([]byte, len(pmessage))

	// NewCipher only returns an error with an invalid key size,
	// but the key size was checked at the beginning of the function.
	c, _ := aes.NewCipher(key[:CKeySize])
	ctr := cipher.NewCBCEncrypter(c, iv)
	ctr.CryptBlocks(ct, pmessage)

	h := hmac.New(sha256.New, key[CKeySize:])
	ct = append(iv, ct...)
	h.Write(ct)
	ct = h.Sum(ct)
	return ct, nil
}

// Decrypt decrypts ciphertext using the given key
func Decrypt(key, ciphertext []byte) ([]byte, error) {
	if len(key) != KeySize {
		return nil, encerrors.ErrInvalidKeyLength
	}

	// HMAC-SHA-256 returns a MAC that is also a multiple of the
	// block size.
	if (len(ciphertext) % aes.BlockSize) != 0 {
		return nil, encerrors.ErrInvalidMessageLength
	}

	// A ciphertext must have at least an IV block, a ciphertext block,
	// and two blocks of HMAC.
	if len(ciphertext) < (4 * aes.BlockSize) {
		return nil, encerrors.ErrInvalidMessageLength
	}

	macStart := len(ciphertext) - MACSize
	tag := ciphertext[macStart:]
	out := make([]byte, macStart-NonceSize)
	ciphertext = ciphertext[:macStart]

	h := hmac.New(sha256.New, key[CKeySize:])
	h.Write(ciphertext)
	mac := h.Sum(nil)
	if !hmac.Equal(mac, tag) {
		return nil, encerrors.ErrInvalidSum
	}

	// NewCipher only returns an error with an invalid key size,
	// but the key size was checked at the beginning of the function.
	c, _ := aes.NewCipher(key[:CKeySize])
	ctr := cipher.NewCBCDecrypter(c, ciphertext[:NonceSize])
	ctr.CryptBlocks(out, ciphertext[NonceSize:])

	pt := unpad(out)
	if pt == nil {
		return nil, encerrors.ErrInvalidPadding
	}

	return pt, nil
}
<commit_msg>fix misspelling of package in cbc.go<commit_after>// Package cbc supports cbc encryption
package cbc

// https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_.28CBC.29

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha256"

	"io"

	"github.com/alistanis/goenc/encerrors"
	"github.com/alistanis/goenc/generate"
)

const (
	// NonceSize to use for nonces
	NonceSize = aes.BlockSize
	// MACSize is the output size of HMAC-SHA-256
	MACSize = 32
	// CKeySize - Cipher key size - AES-256
	CKeySize = 32
	// MKeySize - HMAC key size - HMAC-SHA-256
	MKeySize = 32
	// KeySize is the key size for CBC
	KeySize = CKeySize + MKeySize
)

// pad pads input to match the correct size
func pad(in []byte) []byte {
	padding := 16 - (len(in) % 16)
	for i := 0; i < padding; i++ {
		in = append(in, byte(padding))
	}
	return in
}

// unpad removes unnecessary bytes that were added during initial padding
func unpad(in []byte) []byte {
	if len(in) == 0 {
		return nil
	}

	padding := in[len(in)-1]
	if int(padding) > len(in) || padding > aes.BlockSize {
		return nil
	} else if padding == 0 {
		return nil
	}

	for i := len(in) - 1; i > len(in)-int(padding)-1; i-- {
		if in[i] != padding {
			return nil
		}
	}
	return in[:len(in)-int(padding)]
}

// Cipher implements the BlockCipher interface
type Cipher struct{}

// Encrypt implements the BlockCipher interface
func (c *Cipher) Encrypt(key, plaintext []byte) ([]byte, error) {
	return Encrypt(key, plaintext)
}

// Decrypt implements the BlockCipher interface
func (c *Cipher) Decrypt(key, ciphertext []byte) ([]byte, error) {
	return Decrypt(key, ciphertext)
}

// KeySize returns CBC KeySize and implements the BlockCipher interface
func (c *Cipher) KeySize() int {
	return KeySize
}

// New returns a new cbc cipher
func New() *Cipher {
	return &Cipher{}
}

// Key returns a random key as a pointer to an array of bytes specified by KeySize
func Key() (*[KeySize]byte, error) {
	key := new([KeySize]byte)
	_, err := io.ReadFull(rand.Reader, key[:])
	return key, err
}

// Encrypt encrypts plaintext using the given key with CBC encryption
func Encrypt(key, plaintext []byte) ([]byte, error) {
	if len(key) != KeySize {
		return nil, encerrors.ErrInvalidKeyLength
	}

	iv, err := generate.RandBytes(NonceSize)
	if err != nil {
		return nil, err
	}

	pmessage := pad(plaintext)
	ct := make([]byte, len(pmessage))

	// NewCipher only returns an error with an invalid key size,
	// but the key size was checked at the beginning of the function.
	c, _ := aes.NewCipher(key[:CKeySize])
	ctr := cipher.NewCBCEncrypter(c, iv)
	ctr.CryptBlocks(ct, pmessage)

	h := hmac.New(sha256.New, key[CKeySize:])
	ct = append(iv, ct...)
	h.Write(ct)
	ct = h.Sum(ct)
	return ct, nil
}

// Decrypt decrypts ciphertext using the given key
func Decrypt(key, ciphertext []byte) ([]byte, error) {
	if len(key) != KeySize {
		return nil, encerrors.ErrInvalidKeyLength
	}

	// HMAC-SHA-256 returns a MAC that is also a multiple of the
	// block size.
	if (len(ciphertext) % aes.BlockSize) != 0 {
		return nil, encerrors.ErrInvalidMessageLength
	}

	// A ciphertext must have at least an IV block, a ciphertext block,
	// and two blocks of HMAC.
	if len(ciphertext) < (4 * aes.BlockSize) {
		return nil, encerrors.ErrInvalidMessageLength
	}

	macStart := len(ciphertext) - MACSize
	tag := ciphertext[macStart:]
	out := make([]byte, macStart-NonceSize)
	ciphertext = ciphertext[:macStart]

	h := hmac.New(sha256.New, key[CKeySize:])
	h.Write(ciphertext)
	mac := h.Sum(nil)
	if !hmac.Equal(mac, tag) {
		return nil, encerrors.ErrInvalidSum
	}

	// NewCipher only returns an error with an invalid key size,
	// but the key size was checked at the beginning of the function.
	c, _ := aes.NewCipher(key[:CKeySize])
	ctr := cipher.NewCBCDecrypter(c, ciphertext[:NonceSize])
	ctr.CryptBlocks(out, ciphertext[NonceSize:])

	pt := unpad(out)
	if pt == nil {
		return nil, encerrors.ErrInvalidPadding
	}

	return pt, nil
}
<|endoftext|>


<commit_before>package ai

import (
	"fmt"
	"io"
	"text/tabwriter"

	"github.com/nelhage/taktician/bitboard"
	"github.com/nelhage/taktician/tak"
)

type Weights struct {
	TopFlat  int
	Standing int
	Capstone int

	Flat     int
	Captured int

	Liberties int

	Groups [8]int
}

var DefaultWeights = Weights{
	TopFlat:  300,
	Standing: 200,
	Capstone: 300,

	Flat:      100,
	Liberties: 25,

	Captured: 25,

	Groups: [8]int{
		0,   // 0
		0,   // 1
		0,   // 2
		100, // 3
		300, // 4
	},
}

func MakeEvaluator(w *Weights) EvaluationFunc {
	return func(m *MinimaxAI, p *tak.Position) int64 {
		return evaluate(w, m, p)
	}
}

var DefaultEvaluate = MakeEvaluator(&DefaultWeights)

func evaluate(w *Weights, m *MinimaxAI, p *tak.Position) int64 {
	if over, winner := p.GameOver(); over {
		var pieces int64
		if winner == tak.White {
			pieces = int64(p.WhiteStones())
		} else {
			pieces = int64(p.BlackStones())
		}
		switch winner {
		case tak.NoColor:
			return 0
		case p.ToMove():
			return maxEval - int64(p.MoveNumber()) + pieces
		default:
			return minEval + int64(p.MoveNumber()) - pieces
		}
	}
	mine, theirs := 0, 0
	me := p.ToMove()
	addw := func(c tak.Color, w int) {
		if c == me {
			mine += w
		} else {
			theirs += w
		}
	}
	analysis := p.Analysis()
	for x := 0; x < p.Size(); x++ {
		for y := 0; y < p.Size(); y++ {
			sq := p.At(x, y)
			if len(sq) == 0 {
				continue
			}
			switch sq[0].Kind() {
			case tak.Standing:
				addw(sq[0].Color(), w.Standing)
			case tak.Flat:
				addw(sq[0].Color(), w.TopFlat)
			case tak.Capstone:
				addw(sq[0].Color(), w.Capstone)
			}

			for i, stone := range sq {
				if i > 0 && i < p.Size() {
					addw(sq[0].Color(), w.Captured)
				}
				if stone.Kind() == tak.Flat {
					addw(stone.Color(), w.Flat)
				}
			}
		}
	}

	addw(tak.White, m.scoreGroups(analysis.WhiteGroups, w))
	addw(tak.Black, m.scoreGroups(analysis.BlackGroups, w))

	wl := bitboard.Popcount(bitboard.Grow(&m.c, ^analysis.Black, analysis.WhiteRoad) &^ analysis.WhiteRoad)
	bl := bitboard.Popcount(bitboard.Grow(&m.c, ^analysis.White, analysis.BlackRoad) &^ analysis.BlackRoad)
	addw(tak.White, w.Liberties*wl)
	addw(tak.Black, w.Liberties*bl)

	return int64(mine - theirs)
}

func (ai *MinimaxAI) scoreGroups(gs []uint64, ws *Weights) int {
	sc := 0
	for _, g := range gs {
		w, h := bitboard.Dimensions(&ai.c, g)

		sc += ws.Groups[w]
		sc += ws.Groups[h]
	}

	return sc
}

func ExplainScore(m *MinimaxAI, out io.Writer, p *tak.Position) {
	tw := tabwriter.NewWriter(out, 4, 8, 1, '\t', 0)
	fmt.Fprintf(tw, "\twhite\tblack\n")
	var scores [2]struct {
		flats    int
		standing int
		caps     int

		stones   int
		captured int
	}
	for x := 0; x < p.Size(); x++ {
		for y := 0; y < p.Size(); y++ {
			sq := p.At(x, y)
			if len(sq) == 0 {
				continue
			}
			switch sq[0].Kind() {
			case tak.Standing:
				if sq[0].Color() == tak.White {
					scores[0].standing++
				} else {
					scores[1].standing++
				}
			case tak.Flat:
				if sq[0].Color() == tak.White {
					scores[0].flats++
				} else {
					scores[1].flats++
				}
			case tak.Capstone:
				if sq[0].Color() == tak.White {
					scores[0].caps++
				} else {
					scores[1].caps++
				}
			}

			for i, stone := range sq {
				if i > 0 && i < p.Size() {
					if sq[0].Color() == tak.White {
						scores[0].captured++
					} else {
						scores[1].captured++
					}
				}
				if stone.Kind() == tak.Flat {
					if sq[0].Color() == tak.White {
						scores[0].stones++
					} else {
						scores[1].stones++
					}
				}
			}
		}
	}
	fmt.Fprintf(tw, "flats\t%d\t%d\n", scores[0].flats, scores[1].flats)
	fmt.Fprintf(tw, "standing\t%d\t%d\n", scores[0].standing, scores[1].standing)
	fmt.Fprintf(tw, "caps\t%d\t%d\n", scores[0].caps, scores[1].caps)
	fmt.Fprintf(tw, "capured\t%d\t%d\n", scores[0].captured, scores[1].captured)
	fmt.Fprintf(tw, "stones\t%d\t%d\n", scores[0].stones, scores[1].stones)

	analysis := p.Analysis()

	wl := bitboard.Popcount(bitboard.Grow(&m.c, ^analysis.Black, analysis.WhiteRoad) &^ analysis.WhiteRoad)
	bl := bitboard.Popcount(bitboard.Grow(&m.c, ^analysis.White, analysis.BlackRoad) &^ analysis.BlackRoad)

	fmt.Fprintf(tw, "liberties\t%d\t%d\n", wl, bl)

	for i, g := range analysis.WhiteGroups {
		w, h := bitboard.Dimensions(&m.c, g)
		fmt.Fprintf(tw, "g%d\t%dx%x\n", i, w, h)
	}
	for i, g := range analysis.BlackGroups {
		w, h := bitboard.Dimensions(&m.c, g)
		fmt.Fprintf(tw, "g%d\t\t%dx%x\n", i, w, h)
	}
	tw.Flush()
}
<commit_msg>take a guess at a 5-group value<commit_after>package ai

import (
	"fmt"
	"io"
	"text/tabwriter"

	"github.com/nelhage/taktician/bitboard"
	"github.com/nelhage/taktician/tak"
)

type Weights struct {
	TopFlat  int
	Standing int
	Capstone int

	Flat     int
	Captured int

	Liberties int

	Groups [8]int
}

var DefaultWeights = Weights{
	TopFlat:  300,
	Standing: 200,
	Capstone: 300,

	Flat:      100,
	Liberties: 25,

	Captured: 25,

	Groups: [8]int{
		0,   // 0
		0,   // 1
		0,   // 2
		100, // 3
		300, // 4
		500, // 5
	},
}

func MakeEvaluator(w *Weights) EvaluationFunc {
	return func(m *MinimaxAI, p *tak.Position) int64 {
		return evaluate(w, m, p)
	}
}

var DefaultEvaluate = MakeEvaluator(&DefaultWeights)

func evaluate(w *Weights, m *MinimaxAI, p *tak.Position) int64 {
	if over, winner := p.GameOver(); over {
		var pieces int64
		if winner == tak.White {
			pieces = int64(p.WhiteStones())
		} else {
			pieces = int64(p.BlackStones())
		}
		switch winner {
		case tak.NoColor:
			return 0
		case p.ToMove():
			return maxEval - int64(p.MoveNumber()) + pieces
		default:
			return minEval + int64(p.MoveNumber()) - pieces
		}
	}
	mine, theirs := 0, 0
	me := p.ToMove()
	addw := func(c tak.Color, w int) {
		if c == me {
			mine += w
		} else {
			theirs += w
		}
	}
	analysis := p.Analysis()
	for x := 0; x < p.Size(); x++ {
		for y := 0; y < p.Size(); y++ {
			sq := p.At(x, y)
			if len(sq) == 0 {
				continue
			}
			switch sq[0].Kind() {
			case tak.Standing:
				addw(sq[0].Color(), w.Standing)
			case tak.Flat:
				addw(sq[0].Color(), w.TopFlat)
			case tak.Capstone:
				addw(sq[0].Color(), w.Capstone)
			}

			for i, stone := range sq {
				if i > 0 && i < p.Size() {
					addw(sq[0].Color(), w.Captured)
				}
				if stone.Kind() == tak.Flat {
					addw(stone.Color(), w.Flat)
				}
			}
		}
	}

	addw(tak.White, m.scoreGroups(analysis.WhiteGroups, w))
	addw(tak.Black, m.scoreGroups(analysis.BlackGroups, w))

	wl := bitboard.Popcount(bitboard.Grow(&m.c, ^analysis.Black, analysis.WhiteRoad) &^ analysis.WhiteRoad)
	bl := bitboard.Popcount(bitboard.Grow(&m.c, ^analysis.White, analysis.BlackRoad) &^ analysis.BlackRoad)
	addw(tak.White, w.Liberties*wl)
	addw(tak.Black, w.Liberties*bl)

	return int64(mine - theirs)
}

func (ai *MinimaxAI) scoreGroups(gs []uint64, ws *Weights) int {
	sc := 0
	for _, g := range gs {
		w, h := bitboard.Dimensions(&ai.c, g)

		sc += ws.Groups[w]
		sc += ws.Groups[h]
	}

	return sc
}

func ExplainScore(m *MinimaxAI, out io.Writer, p *tak.Position) {
	tw := tabwriter.NewWriter(out, 4, 8, 1, '\t', 0)
	fmt.Fprintf(tw, "\twhite\tblack\n")
	var scores [2]struct {
		flats    int
		standing int
		caps     int

		stones   int
		captured int
	}
	for x := 0; x < p.Size(); x++ {
		for y := 0; y < p.Size(); y++ {
			sq := p.At(x, y)
			if len(sq) == 0 {
				continue
			}
			switch sq[0].Kind() {
			case tak.Standing:
				if sq[0].Color() == tak.White {
					scores[0].standing++
				} else {
					scores[1].standing++
				}
			case tak.Flat:
				if sq[0].Color() == tak.White {
					scores[0].flats++
				} else {
					scores[1].flats++
				}
			case tak.Capstone:
				if sq[0].Color() == tak.White {
					scores[0].caps++
				} else {
					scores[1].caps++
				}
			}

			for i, stone := range sq {
				if i > 0 && i < p.Size() {
					if sq[0].Color() == tak.White {
						scores[0].captured++
					} else {
						scores[1].captured++
					}
				}
				if stone.Kind() == tak.Flat {
					if sq[0].Color() == tak.White {
						scores[0].stones++
					} else {
						scores[1].stones++
					}
				}
			}
		}
	}
	fmt.Fprintf(tw, "flats\t%d\t%d\n", scores[0].flats, scores[1].flats)
	fmt.Fprintf(tw, "standing\t%d\t%d\n", scores[0].standing, scores[1].standing)
	fmt.Fprintf(tw, "caps\t%d\t%d\n", scores[0].caps, scores[1].caps)
	fmt.Fprintf(tw, "capured\t%d\t%d\n", scores[0].captured, scores[1].captured)
	fmt.Fprintf(tw, "stones\t%d\t%d\n", scores[0].stones, scores[1].stones)

	analysis := p.Analysis()

	wl := bitboard.Popcount(bitboard.Grow(&m.c, ^analysis.Black, analysis.WhiteRoad) &^ analysis.WhiteRoad)
	bl := bitboard.Popcount(bitboard.Grow(&m.c, ^analysis.White, analysis.BlackRoad) &^ analysis.BlackRoad)

	fmt.Fprintf(tw, "liberties\t%d\t%d\n", wl, bl)

	for i, g := range analysis.WhiteGroups {
		w, h := bitboard.Dimensions(&m.c, g)
		fmt.Fprintf(tw, "g%d\t%dx%x\n", i, w, h)
	}
	for i, g := range analysis.BlackGroups {
		w, h := bitboard.Dimensions(&m.c, g)
		fmt.Fprintf(tw, "g%d\t\t%dx%x\n", i, w, h)
	}
	tw.Flush()
}
<|endoftext|>


<commit_before>package align

import (
	"bufio"
	"io"
	"strings"
	"unicode/utf8"
)

// Commonly used file delimiters or alignment characters
const (
	Comma    = ','
	VertPipe = '|'
	Star     = '*'
	Tab      = '\t'
	Equal    = '='
	GThan    = '>'
	LThan    = '<'
	Hyphen   = '-'
	Plus     = '+'
)

// Various values to be used by consuming programs
const (
	SingleSpace = " "
	DoubleQuote = "\""
	SingleQuote = "'"
)

// Alignable ...
type Alignable interface {
	ColumnCounts() []string
	Export([]string)
}

type columnCount int

// Aligner scans input and writes output
type Aligner struct {
	S            *bufio.Scanner
	W            *bufio.Writer
	del          rune // delimiter
	columnCounts map[columnCount]int
}

// NewAligner creates and initializes a ScanWriter with in and out as its initial Reader and Writer
// and sets del to the desired delimiter to be used for alignment.
// It is meant to read the contents of its io.Reader to determine the length of each field
// and output the results in an aligned format.
func NewAligner(in io.Reader, out io.Writer, delimiter rune) Alignable {
	return &Aligner{
		S:            bufio.NewScanner(in),
		W:            bufio.NewWriter(out),
		del:          delimiter,
		columnCounts: make(map[columnCount]int),
	}
}

// Init accepts the same arguments as NewAligner.  It simply provides another option
// for initializing an Aligner which is already allocated.
func (a *Aligner) Init(in io.Reader, out io.Writer, delimiter rune) {
	a.S = bufio.NewScanner(in)
	a.W = bufio.NewWriter(out)
	a.del = delimiter
	a.columnCounts = make(map[columnCount]int)
}

// ColumnCounts scans the input and determines the maximum length of each field based on
// the longest value for each field in all of the pertaining lines.
// All of the lines of the io.Reader are returned as a string slice.
func (a *Aligner) ColumnCounts() []string {
	var lines []string
	for a.S.Scan() {
		var columnNum columnCount
		var temp int

		line := a.S.Text()

		for i, v := range line {
			temp += utf8.RuneLen(v)
			if v != a.del && i < len(line)-1 {
				continue
			}
			if temp > a.columnCounts[columnNum] {
				a.columnCounts[columnNum] = temp
			}
			columnNum++
			temp = 0
		}
		lines = append(lines, line)
	}

	return lines
}

// Export will pad each field in lines based on the Aligner's column counts
func (a *Aligner) Export(lines []string) {
	for _, line := range lines {
		words := strings.Split(line, string(a.del))

		var columnNum columnCount

		for _, word := range words {
			// leading padding for all fields except for the first
			if columnNum > 0 {
				word = SingleSpace + word
			}
			for len(word) < a.columnCounts[columnNum] {
				word += SingleSpace
			}
			rCount, wordLen := utf8.RuneCountInString(word), len(word)
			if rCount < wordLen {
				for i := 0; i < wordLen-rCount; i++ {
					word += SingleSpace
				}
			}
			columnNum++
			// since columnNum was just incremented, do not add a delimiter to the last field
			if _, ok := a.columnCounts[columnNum]; ok {
				a.W.WriteString(word + string(a.del))
				continue
			}
			a.W.WriteString(word + "\n")
		}
	}
	a.W.Flush()
}
<commit_msg>remove map key check to properly allow for lines with a different number of fields<commit_after>package align

import (
	"bufio"
	"io"
	"strings"
	"unicode/utf8"
)

// Commonly used file delimiters or alignment characters
const (
	Comma    = ','
	VertPipe = '|'
	Star     = '*'
	Tab      = '\t'
	Equal    = '='
	GThan    = '>'
	LThan    = '<'
	Hyphen   = '-'
	Plus     = '+'
)

// Various values to be used by consuming programs
const (
	SingleSpace = " "
	DoubleQuote = "\""
	SingleQuote = "'"
)

// Alignable ...
type Alignable interface {
	ColumnCounts() []string
	Export([]string)
}

type columnCount int

// Aligner scans input and writes output
type Aligner struct {
	S            *bufio.Scanner
	W            *bufio.Writer
	del          rune // delimiter
	columnCounts map[int]int
}

// NewAligner creates and initializes a ScanWriter with in and out as its initial Reader and Writer
// and sets del to the desired delimiter to be used for alignment.
// It is meant to read the contents of its io.Reader to determine the length of each field
// and output the results in an aligned format.
func NewAligner(in io.Reader, out io.Writer, delimiter rune) Alignable {
	return &Aligner{
		S:            bufio.NewScanner(in),
		W:            bufio.NewWriter(out),
		del:          delimiter,
		columnCounts: make(map[int]int),
	}
}

// Init accepts the same arguments as NewAligner.  It simply provides another option
// for initializing an Aligner which is already allocated.
func (a *Aligner) Init(in io.Reader, out io.Writer, delimiter rune) {
	a.S = bufio.NewScanner(in)
	a.W = bufio.NewWriter(out)
	a.del = delimiter
	a.columnCounts = make(map[int]int)
}

// ColumnCounts scans the input and determines the maximum length of each field based on
// the longest value for each field in all of the pertaining lines.
// All of the lines of the io.Reader are returned as a string slice.
func (a *Aligner) ColumnCounts() []string {
	var lines []string
	for a.S.Scan() {
		var columnNum int
		var temp int

		line := a.S.Text()

		for i, v := range line {
			temp += utf8.RuneLen(v)
			if v != a.del && i < len(line)-1 {
				continue
			}
			if temp > a.columnCounts[columnNum] {
				a.columnCounts[columnNum] = temp
			}
			columnNum++
			temp = 0
		}
		lines = append(lines, line)
	}

	return lines
}

// Export will pad each field in lines based on the Aligner's column counts
func (a *Aligner) Export(lines []string) {
	for _, line := range lines {
		words := strings.Split(line, string(a.del))

		var columnNum int

		for _, word := range words {
			// leading padding for all fields except for the first
			if columnNum > 0 {
				word = SingleSpace + word
			}
			for len(word) < a.columnCounts[columnNum] {
				word += SingleSpace
			}
			rCount, wordLen := utf8.RuneCountInString(word), len(word)
			if rCount < wordLen {
				for i := 0; i < wordLen-rCount; i++ {
					word += SingleSpace
				}
			}
			columnNum++

			// Do not add a delimiter to the last field
			// This also properly aligns the output even if there are lines with a different number of fields
			if columnNum == len(words) {
				a.W.WriteString(word + "\n")
				continue
			}
			a.W.WriteString(word + string(a.del))

		}
	}
	a.W.Flush()
}
<|endoftext|>


<commit_before>package align

import (
	"bufio"
	"io"
	"strings"
	"unicode/utf8"
)

// Commonly used file delimiters or alignment characters
const (
	Comma    = ','
	VertPipe = '|'
	Star     = '*'
	Tab      = '\t'
	Equal    = '='
	GThan    = '>'
	LThan    = '<'
	Hyphen   = '-'
	Plus     = '+'
)

// Various values to be used by consuming programs
const (
	SingleSpace = " "
	DoubleQuote = "\""
	SingleQuote = "'"
)

// Alignable ...
type Alignable interface {
	ColumnCounts() []string
	Export([]string)
}

type columnCount int

// Aligner scans input and writes output
type Aligner struct {
	S            *bufio.Scanner
	W            *bufio.Writer
	del          rune // delimiter
	columnCounts map[columnCount]int
}

// NewAligner creates and initializes a ScanWriter with in and out as its initial Reader and Writer
// and sets del to the desired delimiter to be used for alignment.
// It is meant to read the contents of its io.Reader to determine the length of each field
// and output the results in an aligned format.
func NewAligner(in io.Reader, out io.Writer, delimiter rune) Alignable {
	return &Aligner{
		S:            bufio.NewScanner(in),
		W:            bufio.NewWriter(out),
		del:          delimiter,
		columnCounts: make(map[columnCount]int),
	}
}

// ColumnCounts scans the input and determines the maximum length of each field based on
// the longest value for each field in all of the pertaining lines.
// All of the lines of the io.Reader are returned as a string slice.
func (a *Aligner) ColumnCounts() []string {
	var lines []string
	for a.S.Scan() {
		var columnNum columnCount
		var temp int

		line := a.S.Text()

		for i, v := range line {
			temp += utf8.RuneLen(v)
			if v != a.del && i < len(line)-1 {
				continue
			}
			if temp > a.columnCounts[columnNum] {
				a.columnCounts[columnNum] = temp
			}
			columnNum++
			temp = 0
		}
		lines = append(lines, line)
	}

	return lines
}

// Export will pad each field in lines based on the Aligner's column counts
func (a *Aligner) Export(lines []string) {
	for _, line := range lines {
		words := strings.Split(line, string(a.del))

		var columnNum columnCount

		for i, word := range words {
			// leading padding for all fields except for the first
			if i > 0 {
				word = SingleSpace + word
			}
			for len(word) < a.columnCounts[columnNum] {
				word += SingleSpace
			}
			rCount, wordLen := utf8.RuneCountInString(word), len(word)
			if rCount < wordLen {
				for i := 0; i < wordLen-rCount; i++ {
					word += SingleSpace
				}
			}
			columnNum++
			// since columnNum was just incremented, do not add a delimiter to the last field
			if _, ok := a.columnCounts[columnNum]; ok {
				a.W.WriteString(word + string(a.del))
				continue
			}
			a.W.WriteString(word)
		}
		a.W.WriteByte('\n')
	}
	a.W.Flush()
}
<commit_msg>refactor last column to append the newline to 'word' instead of a separate call to WriteByte()<commit_after>package align

import (
	"bufio"
	"io"
	"strings"
	"unicode/utf8"
)

// Commonly used file delimiters or alignment characters
const (
	Comma    = ','
	VertPipe = '|'
	Star     = '*'
	Tab      = '\t'
	Equal    = '='
	GThan    = '>'
	LThan    = '<'
	Hyphen   = '-'
	Plus     = '+'
)

// Various values to be used by consuming programs
const (
	SingleSpace = " "
	DoubleQuote = "\""
	SingleQuote = "'"
)

// Alignable ...
type Alignable interface {
	ColumnCounts() []string
	Export([]string)
}

type columnCount int

// Aligner scans input and writes output
type Aligner struct {
	S            *bufio.Scanner
	W            *bufio.Writer
	del          rune // delimiter
	columnCounts map[columnCount]int
}

// NewAligner creates and initializes a ScanWriter with in and out as its initial Reader and Writer
// and sets del to the desired delimiter to be used for alignment.
// It is meant to read the contents of its io.Reader to determine the length of each field
// and output the results in an aligned format.
func NewAligner(in io.Reader, out io.Writer, delimiter rune) Alignable {
	return &Aligner{
		S:            bufio.NewScanner(in),
		W:            bufio.NewWriter(out),
		del:          delimiter,
		columnCounts: make(map[columnCount]int),
	}
}

// ColumnCounts scans the input and determines the maximum length of each field based on
// the longest value for each field in all of the pertaining lines.
// All of the lines of the io.Reader are returned as a string slice.
func (a *Aligner) ColumnCounts() []string {
	var lines []string
	for a.S.Scan() {
		var columnNum columnCount
		var temp int

		line := a.S.Text()

		for i, v := range line {
			temp += utf8.RuneLen(v)
			if v != a.del && i < len(line)-1 {
				continue
			}
			if temp > a.columnCounts[columnNum] {
				a.columnCounts[columnNum] = temp
			}
			columnNum++
			temp = 0
		}
		lines = append(lines, line)
	}

	return lines
}

// Export will pad each field in lines based on the Aligner's column counts
func (a *Aligner) Export(lines []string) {
	for _, line := range lines {
		words := strings.Split(line, string(a.del))

		var columnNum columnCount

		for i, word := range words {
			// leading padding for all fields except for the first
			if i > 0 {
				word = SingleSpace + word
			}
			for len(word) < a.columnCounts[columnNum] {
				word += SingleSpace
			}
			rCount, wordLen := utf8.RuneCountInString(word), len(word)
			if rCount < wordLen {
				for i := 0; i < wordLen-rCount; i++ {
					word += SingleSpace
				}
			}
			columnNum++
			// since columnNum was just incremented, do not add a delimiter to the last field
			if _, ok := a.columnCounts[columnNum]; ok {
				a.W.WriteString(word + string(a.del))
				continue
			}
			a.W.WriteString(word + "\n")
		}
	}
	a.W.Flush()
}
<|endoftext|>


<commit_before>package netdb

import (
	"io/ioutil"
	"strconv"
	"strings"
)

type Protoent struct {
	Name    string
	Aliases []string
	Number  int
}

type Servent struct {
	Name     string
	Aliases  []string
	Port     int
	Protocol string
}

var Protocols []Protoent
var Services []Servent

func init() {
	// Load protocols
	data, err := ioutil.ReadFile("/etc/protocols")
	if err != nil {
		panic(err)
	}

	for _, line := range strings.Split(string(data), "\n") {
		line = strings.TrimSpace(line)
		split := strings.SplitN(line, "#", 2)
		fields := strings.Fields(split[0])
		if len(fields) < 2 {
			continue
		}

		num, err := strconv.ParseInt(fields[1], 10, 32)
		if err != nil {
			panic(err)
		}

		Protocols = append(Protocols, Protoent{
			Name:    fields[0],
			Aliases: fields[2:],
			Number:  int(num),
		})
	}

	// Load services
	data, err = ioutil.ReadFile("/etc/services")
	if err != nil {
		panic(err)
	}

	for _, line := range strings.Split(string(data), "\n") {
		line = strings.TrimSpace(line)
		split := strings.SplitN(line, "#", 2)
		fields := strings.Fields(split[0])
		if len(fields) < 2 {
			continue
		}

		name := fields[0]
		portproto := strings.SplitN(fields[1], "/", 2)
		port, err := strconv.ParseInt(portproto[0], 10, 32)
		if err != nil {
			panic(err)
		}

		proto := portproto[1]
		aliases := fields[2:]

		Services = append(Services, Servent{
			Name:     name,
			Aliases:  aliases,
			Port:     int(port),
			Protocol: proto,
		})
	}
}

func (this Protoent) Equal(other Protoent) bool {
	return this.Number == other.Number
}

func GetProtoByNumber(num int) (Protoent, bool) {
	for _, protoent := range Protocols {
		if protoent.Number == num {
			return protoent, true
		}
	}
	return Protoent{}, false
}

func GetProtoByName(name string) (Protoent, bool) {
	for _, protoent := range Protocols {
		if protoent.Name == name {
			return protoent, true
		}

		for _, alias := range protoent.Aliases {
			if alias == name {
				return protoent, true
			}
		}
	}

	return Protoent{}, false
}

func GetServByName(name, protocol string) (Servent, bool) {
	for _, servent := range Services {
		if servent.Protocol != protocol && protocol != "" {
			continue
		}

		if servent.Name == name {
			return servent, true
		}

		for _, alias := range servent.Aliases {
			if alias == name {
				return servent, true
			}
		}
	}

	return Servent{}, false
}

func GetServByPort(port int, protocol string) (Servent, bool) {
	for _, servent := range Services {
		if servent.Port == port && (servent.Protocol == protocol || protocol == "") {
			return servent, true
		}
	}

	return Servent{}, false
}
<commit_msg>add documentation<commit_after>// Package netdb provides a Go interface for the protoent and servent
// structures as defined in netdb.h
//
// A pure Go implementation is used by parsing /etc/protocols and
// /etc/services
package netdb

import (
	"io/ioutil"
	"strconv"
	"strings"
)

type Protoent struct {
	Name    string
	Aliases []string
	Number  int
}

type Servent struct {
	Name     string
	Aliases  []string
	Port     int
	Protocol string
}

// These variables get populated from /etc/protocols and /etc/services
// respectively.
var (
	Protocols []Protoent
	Services []Servent
)

func init() {
	// Load protocols
	data, err := ioutil.ReadFile("/etc/protocols")
	if err != nil {
		panic(err)
	}

	for _, line := range strings.Split(string(data), "\n") {
		line = strings.TrimSpace(line)
		split := strings.SplitN(line, "#", 2)
		fields := strings.Fields(split[0])
		if len(fields) < 2 {
			continue
		}

		num, err := strconv.ParseInt(fields[1], 10, 32)
		if err != nil {
			panic(err)
		}

		Protocols = append(Protocols, Protoent{
			Name:    fields[0],
			Aliases: fields[2:],
			Number:  int(num),
		})
	}

	// Load services
	data, err = ioutil.ReadFile("/etc/services")
	if err != nil {
		panic(err)
	}

	for _, line := range strings.Split(string(data), "\n") {
		line = strings.TrimSpace(line)
		split := strings.SplitN(line, "#", 2)
		fields := strings.Fields(split[0])
		if len(fields) < 2 {
			continue
		}

		name := fields[0]
		portproto := strings.SplitN(fields[1], "/", 2)
		port, err := strconv.ParseInt(portproto[0], 10, 32)
		if err != nil {
			panic(err)
		}

		proto := portproto[1]
		aliases := fields[2:]

		Services = append(Services, Servent{
			Name:     name,
			Aliases:  aliases,
			Port:     int(port),
			Protocol: proto,
		})
	}
}

// Equal checks if two Protoents are the same, which is the case if
// their protocol numbers are identical.
func (this Protoent) Equal(other Protoent) bool {
	return this.Number == other.Number
}

// GetProtoByNumber returns the Protoent for the correspondent
// protocol number.
func GetProtoByNumber(num int) (protoent Protoent, ok bool) {
	for _, protoent := range Protocols {
		if protoent.Number == num {
			return protoent, true
		}
	}
	return Protoent{}, false
}

// GetProtoByName returns the Protoent whose name or any of its
// aliases matches the argument.
func GetProtoByName(name string) (protoent Protoent, ok bool) {
	for _, protoent := range Protocols {
		if protoent.Name == name {
			return protoent, true
		}

		for _, alias := range protoent.Aliases {
			if alias == name {
				return protoent, true
			}
		}
	}

	return Protoent{}, false
}

// GetServByName returns the Servent for a given service name and
// protocol name. If the protocol name is empty, the first service
// matching the service name is returned.
func GetServByName(name, protocol string) (servent Servent, ok bool) {
	for _, servent := range Services {
		if servent.Protocol != protocol && protocol != "" {
			continue
		}

		if servent.Name == name {
			return servent, true
		}

		for _, alias := range servent.Aliases {
			if alias == name {
				return servent, true
			}
		}
	}

	return Servent{}, false
}

// GetServByPort returns the Servent for a given port number and
// protocol name. If the protocol name is empty, the first service
// matching the port number is returned.
func GetServByPort(port int, protocol string) (Servent, bool) {
	for _, servent := range Services {
		if servent.Port == port && (servent.Protocol == protocol || protocol == "") {
			return servent, true
		}
	}

	return Servent{}, false
}
<|endoftext|>


<commit_before>package gron

import (
	"fmt"
	"reflect"
	"sort"
	"strings"
	"sync"
	"testing"
	"time"
)

// Most cron tests are expected to trigger after 1 second.
// We fail tests after OneSecond: 1.01 seconds.
const OneSecond = 1*time.Second + 10*time.Millisecond

func TestMultipleSchedules(t *testing.T) {

	wg := &sync.WaitGroup{}
	wg.Add(3)
	cron := New()
	cron.AddFunc(Every(1*time.Second), func() { wg.Done() })
	cron.AddFunc(Every(1*time.Second), func() { wg.Done() })
	cron.AddFunc(Every(1*time.Second), func() { wg.Done() })

	cron.Start()
	defer cron.Stop()

	select {
	case <-wait(wg):
	case <-time.After(OneSecond):
		t.FailNow()
	}

}

func wait(wg *sync.WaitGroup) <-chan bool {
	done := make(chan bool)

	go func() {
		wg.Wait()
		done <- true
	}()
	return done
}

// add a job, start a cron, expect it runs
func TestAddBeforeRun(t *testing.T) {
	done := make(chan struct{})
	cron := New()
	cron.AddFunc(Every(1*time.Second), func() { done <- struct{}{} })
	cron.Start()
	defer cron.Stop()

	select {
	case <-done:
	case <-time.After(OneSecond):
		t.FailNow()
	}
}

// start a cron, add a job, expect it runs
func TestAddWhileRun(t *testing.T) {

	done := make(chan struct{})
	cron := New()
	cron.Start()
	defer cron.Stop()

	cron.AddFunc(Every(1*time.Second), func() { done <- struct{}{} })

	select {
	case <-done:
	case <-time.After(OneSecond):
		t.FailNow()
	}
}

// Test that invoking stop() before start() silently returns,
// without blocking the stop channel
func TestStopWithoutStart(t *testing.T) {
	cron := New()
	cron.Stop()
}

// Test that entries are chronologically sorted
func TestByTimeSort(t *testing.T) {
	tests := []struct {
		entries string
		want    string
	}{
		// simple cases
		{"10:05, 10:04, 10:03", "10:03, 10:04, 10:05"},
		{"10:05, 10:04, 10:03", "10:03, 10:04, 10:05"},

		// hours dominate
		{"7:00, 8:00, 9:00", "7:00, 8:00, 9:00"},
		{"9:00, 8:00, 7:00", "7:00, 8:00, 9:00"},
		{"9:00, 8:49, 8:09", "8:09, 8:49, 9:00"},

		// seconds dominate
		{"00:00:01, 00:00:03, 00:00:30", "00:00:01, 00:00:03, 00:00:30"},
		{"00:00:03, 00:00:01, 00:00:30", "00:00:01, 00:00:03, 00:00:30"},
		{"00:05:10, 00:04:20, 00:03:30", "00:03:30, 00:04:20, 00:05:10"},

		// days dominate
		{
			"Wed Jun 8 9:05 2016, Tue Jun 7 8:04 2016, Wed Jun 8 9:01 2016",
			"Tue Jun 7 8:04 2016, Wed Jun 8 9:01 2016, Wed Jun 8 9:05 2016",
		},

		// months dominate
		{
			"Sun Jun 4 9:05 2016, Sun Feb 7 8:04 2016, Sun May 8 9:01 2016",
			"Sun Feb 7 8:04 2016, Sun May 8 9:01 2016, Sun Jun 4 9:05 2016",
		},

		// zero hours sort as intended
		{"00:00, 00:00, 00:10", "00:00, 00:00, 00:10"},

		// zero minutes sort as intended
		{"00:00:00, 00:00:00, 00:00:10", "00:00:00, 00:00:00, 00:00:10"},

		// zero times (uninitialised time) should push to back of queue.
		{
			"2016-01-01 00:00, 2016-01-01 00:00, 0001-01-01 00:00",
			"2016-01-01 00:00, 2016-01-01 00:00, 0001-01-01 00:00",
		},
		{
			"2016-01-01 00:01, 2016-01-01 00:00, 0001-01-01 00:00",
			"2016-01-01 00:00, 2016-01-01 00:01, 0001-01-01 00:00",
		},
		{
			"0001-01-01 00:00, 2016-01-01 00:01, 2016-01-01 00:00",
			"2016-01-01 00:00, 2016-01-01 00:01, 0001-01-01 00:00",
		},
		{
			"2016-01-01 00:01, 0001-01-01 00:00, 2016-01-01 00:00",
			"2016-01-01 00:00, 2016-01-01 00:01, 0001-01-01 00:00",
		},
		{
			"0001-01-01 00:00, 0001-01-01 00:00, 2016-01-01 00:00",
			"2016-01-01 00:00, 0001-01-01 00:00, 0001-01-01 00:00",
		},
	}

	for i, test := range tests {

		got := mockEntries(getTimes(test.entries))
		sort.Sort(byTime(got))

		want := mockEntries(getTimes(test.want))

		if !reflect.DeepEqual(got, want) {
			t.Errorf("entries[%d] out of order: \n%v (want)\n%v (got)", i, toS(want), toS(got))
		}
	}
}

func mockEntries(nexts []time.Time) []*Entry {
	var entries []*Entry

	for _, n := range nexts {
		entries = append(entries, &Entry{Next: n})
	}
	return entries
}

// getTimes splits comma-separated time.
func getTimes(s string) []time.Time {

	ts := strings.Split(s, ",")
	ret := make([]time.Time, len(ts))

	for i, t := range ts {
		ret[i] = getTime(strings.Trim(t, " "))
	}
	return ret
}

// wrapper to stringify time instant t
type toS []*Entry

func (entries toS) String() string {
	var ret string
	for _, e := range entries {
		ret += fmt.Sprintf("[%v] ", e.Next)
	}
	return ret
}
<commit_msg>add comments to better explain<commit_after>package gron

import (
	"fmt"
	"reflect"
	"sort"
	"strings"
	"sync"
	"testing"
	"time"
)

// Most test jobs scheduled to run at second 1.
// Test expects to fail after OneSecond: 1.01 seconds.
const OneSecond = 1*time.Second + 10*time.Millisecond

// Test that after first entry has run, subsequent entries are checked and run
// if possessed same schedule as first entry.
func TestConcurrentSchedules(t *testing.T) {

	wg := &sync.WaitGroup{}
	wg.Add(3)
	cron := New()

	cron.AddFunc(Every(5*time.Minute), func() {})
	cron.AddFunc(Every(1*time.Second), func() { wg.Done() })
	cron.AddFunc(Every(1*time.Second), func() { wg.Done() })
	cron.AddFunc(Every(1*time.Second), func() { wg.Done() })

	cron.Start()
	defer cron.Stop()

	select {
	case <-wait(wg):
	case <-time.After(OneSecond):
		t.FailNow()
	}

}

// wait is a helper function that returns a signal upon WaitGroup instant wg
// receives all feedback.
func wait(wg *sync.WaitGroup) <-chan bool {
	done := make(chan bool)

	go func() {
		wg.Wait()
		done <- true
	}()
	return done
}

// add a job, start a cron, expect it runs
func TestAddBeforeRun(t *testing.T) {
	done := make(chan struct{})
	cron := New()
	cron.AddFunc(Every(1*time.Second), func() { done <- struct{}{} })
	cron.Start()
	defer cron.Stop()

	select {
	case <-done:
	case <-time.After(OneSecond):
		t.FailNow()
	}
}

// start a cron, add a job, expect it runs
func TestAddWhileRun(t *testing.T) {

	done := make(chan struct{})
	cron := New()
	cron.Start()
	defer cron.Stop()

	cron.AddFunc(Every(1*time.Second), func() { done <- struct{}{} })

	select {
	case <-done:
	case <-time.After(OneSecond):
		t.FailNow()
	}
}

// Test that invoking stop() before start() silently returns,
// without blocking the stop channel
func TestStopWithoutStart(t *testing.T) {
	cron := New()
	cron.Stop()
}

// Test that entries are chronologically sorted
func TestByTimeSort(t *testing.T) {
	tests := []struct {
		entries string
		want    string
	}{
		// simple cases
		{"10:05, 10:04, 10:03", "10:03, 10:04, 10:05"},
		{"10:05, 10:04, 10:03", "10:03, 10:04, 10:05"},

		// hours dominate
		{"7:00, 8:00, 9:00", "7:00, 8:00, 9:00"},
		{"9:00, 8:00, 7:00", "7:00, 8:00, 9:00"},
		{"9:00, 8:49, 8:09", "8:09, 8:49, 9:00"},

		// seconds dominate
		{"00:00:01, 00:00:03, 00:00:30", "00:00:01, 00:00:03, 00:00:30"},
		{"00:00:03, 00:00:01, 00:00:30", "00:00:01, 00:00:03, 00:00:30"},
		{"00:05:10, 00:04:20, 00:03:30", "00:03:30, 00:04:20, 00:05:10"},

		// days dominate
		{
			"Wed Jun 8 9:05 2016, Tue Jun 7 8:04 2016, Wed Jun 8 9:01 2016",
			"Tue Jun 7 8:04 2016, Wed Jun 8 9:01 2016, Wed Jun 8 9:05 2016",
		},

		// months dominate
		{
			"Sun Jun 4 9:05 2016, Sun Feb 7 8:04 2016, Sun May 8 9:01 2016",
			"Sun Feb 7 8:04 2016, Sun May 8 9:01 2016, Sun Jun 4 9:05 2016",
		},

		// zero hours sort as intended
		{"00:00, 00:00, 00:10", "00:00, 00:00, 00:10"},

		// zero minutes sort as intended
		{"00:00:00, 00:00:00, 00:00:10", "00:00:00, 00:00:00, 00:00:10"},

		// zero times (uninitialised time) should push to back of queue.
		{
			"2016-01-01 00:00, 2016-01-01 00:00, 0001-01-01 00:00",
			"2016-01-01 00:00, 2016-01-01 00:00, 0001-01-01 00:00",
		},
		{
			"2016-01-01 00:01, 2016-01-01 00:00, 0001-01-01 00:00",
			"2016-01-01 00:00, 2016-01-01 00:01, 0001-01-01 00:00",
		},
		{
			"0001-01-01 00:00, 2016-01-01 00:01, 2016-01-01 00:00",
			"2016-01-01 00:00, 2016-01-01 00:01, 0001-01-01 00:00",
		},
		{
			"2016-01-01 00:01, 0001-01-01 00:00, 2016-01-01 00:00",
			"2016-01-01 00:00, 2016-01-01 00:01, 0001-01-01 00:00",
		},
		{
			"0001-01-01 00:00, 0001-01-01 00:00, 2016-01-01 00:00",
			"2016-01-01 00:00, 0001-01-01 00:00, 0001-01-01 00:00",
		},
	}

	for i, test := range tests {

		got := mockEntries(getTimes(test.entries))
		sort.Sort(byTime(got))

		want := mockEntries(getTimes(test.want))

		if !reflect.DeepEqual(got, want) {
			t.Errorf("entries[%d] out of order: \n%v (want)\n%v (got)", i, toS(want), toS(got))
		}
	}
}

func mockEntries(nexts []time.Time) []*Entry {
	var entries []*Entry

	for _, n := range nexts {
		entries = append(entries, &Entry{Next: n})
	}
	return entries
}

// getTimes splits comma-separated time.
func getTimes(s string) []time.Time {

	ts := strings.Split(s, ",")
	ret := make([]time.Time, len(ts))

	for i, t := range ts {
		ret[i] = getTime(strings.Trim(t, " "))
	}
	return ret
}

// wrapper to stringify time instant t
type toS []*Entry

func (entries toS) String() string {
	var ret string
	for _, e := range entries {
		ret += fmt.Sprintf("[%v] ", e.Next)
	}
	return ret
}
<|endoftext|>


<commit_before>package annot

import (
	"fmt"
	"regexp"
	"strings"
)

var (
	// KV format:
	//   key1[:val1] key2[:val2] ...
	// Example:
	//   param:name type:[]int attr:"hello world"
	kv_re     *regexp.Regexp = regexp.MustCompile(`^([A-z][0-9A-z_]*)(:(("[^"\\]*(?:\\.[^"\\]*)*")|([^\s:"]+)))?\s+`)
	escape_re *regexp.Regexp = regexp.MustCompile(`\\.`)
)

func parseKV(src string) func() (string, string, error) {
	remain := append([]byte(strings.TrimSpace(src)), ' ')
	return func() (string, string, error) {
		// drained
		if len(remain) == 0 {
			return "", "", nil
		}

		m := kv_re.FindSubmatch(remain)
		if m == nil {
			return "", "", fmt.Errorf("Illegal kv format near: %q", string(remain))
		}

		l := len(m[0])
		k := m[1]
		v := m[3]

		// if it is quoted. Unquote it, see: https://golang.org/ref/spec#Rune_literals
		if len(m[4]) != 0 {
			v = escape_re.ReplaceAllFunc(v[1:len(v)-1], func(x []byte) []byte {
				switch c := x[1]; c {
				default:
					return []byte{c}
				case 'a':
					return []byte{'\a'}
				case 'b':
					return []byte{'\b'}
				case 'f':
					return []byte{'\f'}
				case 'n':
					return []byte{'\n'}
				case 'r':
					return []byte{'\r'}
				case 't':
					return []byte{'\t'}
				case 'v':
					return []byte{'\v'}
				}
			})
		}

		remain = remain[l:]
		return string(k), string(v), nil
	}
}
<commit_msg>Rename<commit_after>package annot

import (
	"fmt"
	"regexp"
	"strings"
)

var (
	// Annotation format:
	//   primaryKey[:primaryVal] key[:val] ...
	// Example:
	//   param:name type:[]int attr:"hello world"
	annot_re  *regexp.Regexp = regexp.MustCompile(`^([A-z][0-9A-z_]*)(:(("[^"\\]*(?:\\.[^"\\]*)*")|([^\s:"]+)))?\s+`)
	escape_re *regexp.Regexp = regexp.MustCompile(`\\.`)
)

func parseAnnot(src string) func() (string, string, error) {
	remain := append([]byte(strings.TrimSpace(src)), ' ')
	return func() (string, string, error) {
		// drained
		if len(remain) == 0 {
			return "", "", nil
		}

		m := annot_re.FindSubmatch(remain)
		if m == nil {
			return "", "", fmt.Errorf("Illegal kv format near: %q", string(remain))
		}

		l := len(m[0])
		k := m[1]
		v := m[3]

		// if it is quoted. Unquote it, see: https://golang.org/ref/spec#Rune_literals
		if len(m[4]) != 0 {
			v = escape_re.ReplaceAllFunc(v[1:len(v)-1], func(x []byte) []byte {
				switch c := x[1]; c {
				default:
					return []byte{c}
				case 'a':
					return []byte{'\a'}
				case 'b':
					return []byte{'\b'}
				case 'f':
					return []byte{'\f'}
				case 'n':
					return []byte{'\n'}
				case 'r':
					return []byte{'\r'}
				case 't':
					return []byte{'\t'}
				case 'v':
					return []byte{'\v'}
				}
			})
		}

		remain = remain[l:]
		return string(k), string(v), nil
	}
}
<|endoftext|>


<commit_before>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 ogletest

import (
	"testing"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

type fakeAnyOfMatcher struct {
	desc string
	res  MatchResult
	err  string
}

func (m *fakeAnyOfMatcher) Matches(c interface{}) (MatchResult, string) {
	return m.res, m.err
}

func (m *fakeAnyOfMatcher) Description() string {
	return m.desc
}

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func TestAnyOfCallsWrapped(t *testing.T) {
	t.Fail()
}

func TestEmptySet(t *testing.T) {
	matcher := AnyOf()

	res, err := matcher.Matches(0)
	expectedRes := MATCH_FALSE
	expectedErr := ""

	if res != expectedRes {
		t.Errorf("Expected %v, got %v", expectedRes, res)
	}

	if err != expectedErr {
		t.Errorf("Expected %v, got %v", expectedErr, err)
	}
}

func TestOneTrue(t *testing.T) {
	matcher := AnyOf(
		&fakeAnyOfMatcher{"", MATCH_UNDEFINED, "foo"},
		17,
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
		&fakeAnyOfMatcher{"", MATCH_TRUE, ""},
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
	)

	res, err := matcher.Matches(0)
	expectedRes := MATCH_TRUE
	expectedErr := ""

	if res != expectedRes {
		t.Errorf("Expected %v, got %v", expectedRes, res)
	}

	if err != expectedErr {
		t.Errorf("Expected %v, got %v", expectedErr, err)
	}
}

func TestOneEqual(t *testing.T) {
	matcher := AnyOf(
		&fakeAnyOfMatcher{"", MATCH_UNDEFINED, "foo"},
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
		13,
		"taco",
		19,
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
	)

	res, err := matcher.Matches("taco")
	expectedRes := MATCH_TRUE
	expectedErr := ""

	if res != expectedRes {
		t.Errorf("Expected %v, got %v", expectedRes, res)
	}

	if err != expectedErr {
		t.Errorf("Expected %v, got %v", expectedErr, err)
	}
}

func TestOneUndefined(t *testing.T) {
	matcher := AnyOf(
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
		17,
		&fakeAnyOfMatcher{"", MATCH_UNDEFINED, "taco"},
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
	)

	res, err := matcher.Matches(0)
	expectedRes := MATCH_UNDEFINED
	expectedErr := "taco"

	if res != expectedRes {
		t.Errorf("Expected %v, got %v", expectedRes, res)
	}

	if err != expectedErr {
		t.Errorf("Expected %v, got %v", expectedErr, err)
	}
}

func TestAllFalseAndNotEqual(t *testing.T) {
	matcher := AnyOf(
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
		17,
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
		19,
	)

	res, err := matcher.Matches(0)
	expectedRes := MATCH_FALSE
	expectedErr := ""

	if res != expectedRes {
		t.Errorf("Expected %v, got %v", expectedRes, res)
	}

	if err != expectedErr {
		t.Errorf("Expected %v, got %v", expectedErr, err)
	}
}

func TestDescriptionForEmptySet(t *testing.T) {
	matcher := AnyOf()
	desc := matcher.Description()
	expected := "or()"

	if desc != expected {
		t.Errorf("Expected %v, got %v", expected, desc)
	}
}

func TestDescriptionForNonEmptySet(t *testing.T) {
}
<commit_msg>TestDescriptionForNonEmptySet<commit_after>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 ogletest

import (
	"testing"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

type fakeAnyOfMatcher struct {
	desc string
	res  MatchResult
	err  string
}

func (m *fakeAnyOfMatcher) Matches(c interface{}) (MatchResult, string) {
	return m.res, m.err
}

func (m *fakeAnyOfMatcher) Description() string {
	return m.desc
}

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func TestAnyOfCallsWrapped(t *testing.T) {
	t.Fail()
}

func TestEmptySet(t *testing.T) {
	matcher := AnyOf()

	res, err := matcher.Matches(0)
	expectedRes := MATCH_FALSE
	expectedErr := ""

	if res != expectedRes {
		t.Errorf("Expected %v, got %v", expectedRes, res)
	}

	if err != expectedErr {
		t.Errorf("Expected %v, got %v", expectedErr, err)
	}
}

func TestOneTrue(t *testing.T) {
	matcher := AnyOf(
		&fakeAnyOfMatcher{"", MATCH_UNDEFINED, "foo"},
		17,
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
		&fakeAnyOfMatcher{"", MATCH_TRUE, ""},
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
	)

	res, err := matcher.Matches(0)
	expectedRes := MATCH_TRUE
	expectedErr := ""

	if res != expectedRes {
		t.Errorf("Expected %v, got %v", expectedRes, res)
	}

	if err != expectedErr {
		t.Errorf("Expected %v, got %v", expectedErr, err)
	}
}

func TestOneEqual(t *testing.T) {
	matcher := AnyOf(
		&fakeAnyOfMatcher{"", MATCH_UNDEFINED, "foo"},
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
		13,
		"taco",
		19,
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
	)

	res, err := matcher.Matches("taco")
	expectedRes := MATCH_TRUE
	expectedErr := ""

	if res != expectedRes {
		t.Errorf("Expected %v, got %v", expectedRes, res)
	}

	if err != expectedErr {
		t.Errorf("Expected %v, got %v", expectedErr, err)
	}
}

func TestOneUndefined(t *testing.T) {
	matcher := AnyOf(
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
		17,
		&fakeAnyOfMatcher{"", MATCH_UNDEFINED, "taco"},
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
	)

	res, err := matcher.Matches(0)
	expectedRes := MATCH_UNDEFINED
	expectedErr := "taco"

	if res != expectedRes {
		t.Errorf("Expected %v, got %v", expectedRes, res)
	}

	if err != expectedErr {
		t.Errorf("Expected %v, got %v", expectedErr, err)
	}
}

func TestAllFalseAndNotEqual(t *testing.T) {
	matcher := AnyOf(
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
		17,
		&fakeAnyOfMatcher{"", MATCH_FALSE, "foo"},
		19,
	)

	res, err := matcher.Matches(0)
	expectedRes := MATCH_FALSE
	expectedErr := ""

	if res != expectedRes {
		t.Errorf("Expected %v, got %v", expectedRes, res)
	}

	if err != expectedErr {
		t.Errorf("Expected %v, got %v", expectedErr, err)
	}
}

func TestDescriptionForEmptySet(t *testing.T) {
	matcher := AnyOf()
	desc := matcher.Description()
	expected := "or()"

	if desc != expected {
		t.Errorf("Expected %v, got %v", expected, desc)
	}
}

func TestDescriptionForNonEmptySet(t *testing.T) {
	matcher := AnyOf(
		&fakeAnyOfMatcher{"taco", MATCH_TRUE, ""},
		"burrito",
		&fakeAnyOfMatcher{"enchilada", MATCH_TRUE, ""},
	)

	desc := matcher.Description()
	expected := "or(taco, burrito, enchilada)"

	if desc != expected {
		t.Errorf("Expected %v, got %v", expected, desc)
	}
}
<|endoftext|>


<commit_before>package mapreduce

import (
	"testing"

	"github.com/mitchellh/goamz/aws"
	"github.com/mitchellh/goamz/s3"
	"github.com/pachyderm/pfs/lib/btrfs"
)

func TestS3(t *testing.T) {
	auth, err := aws.EnvAuth()
	log.Printf("auth: %#v", auth)
	if err != nil {
		log.Print(err)
		return
	}
	client := s3.New(auth, aws.USWest)

	bucketName, err := getBucket(job.Input)
	if err != nil {
		log.Print(err)
		return
	}
	bucket := client.Bucket("pachyderm-data")
	inFile, err = bucket.GetReader("chess/file000000000")
	if err != nil {
		log.Print(err)
		return
	}
	defer inFile.Close()
}
<commit_msg>Makes mapreduce_test compile.<commit_after>package mapreduce

import (
	"log"
	"testing"

	"github.com/mitchellh/goamz/aws"
	"github.com/mitchellh/goamz/s3"
)

func TestS3(t *testing.T) {
	auth, err := aws.EnvAuth()
	log.Printf("auth: %#v", auth)
	if err != nil {
		log.Print(err)
		return
	}
	client := s3.New(auth, aws.USWest)
	bucket := client.Bucket("pachyderm-data")
	inFile, err := bucket.GetReader("chess/file000000000")
	if err != nil {
		log.Print(err)
		return
	}
	inFile.Close()
}
<|endoftext|>


<commit_before>package cli

import (
	"os"

	auditFile "github.com/hashicorp/vault/builtin/audit/file"

	credAppId "github.com/hashicorp/vault/builtin/credential/app-id"
	credGitHub "github.com/hashicorp/vault/builtin/credential/github"
	credUserpass "github.com/hashicorp/vault/builtin/credential/userpass"

	"github.com/hashicorp/vault/builtin/logical/aws"
	"github.com/hashicorp/vault/builtin/logical/consul"
	"github.com/hashicorp/vault/builtin/logical/postgresql"
	"github.com/hashicorp/vault/builtin/logical/transit"

	"github.com/hashicorp/vault/audit"
	tokenDisk "github.com/hashicorp/vault/builtin/token/disk"
	"github.com/hashicorp/vault/command"
	"github.com/hashicorp/vault/logical"
	"github.com/mitchellh/cli"
)

// Commands returns the mapping of CLI commands for Vault. The meta
// parameter lets you set meta options for all commands.
func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory {
	if metaPtr == nil {
		metaPtr = new(command.Meta)
	}

	meta := *metaPtr
	if meta.Ui == nil {
		meta.Ui = &cli.BasicUi{
			Writer:      os.Stdout,
			ErrorWriter: os.Stderr,
		}
	}

	return map[string]cli.CommandFactory{
		"init": func() (cli.Command, error) {
			return &command.InitCommand{
				Meta: meta,
			}, nil
		},

		"server": func() (cli.Command, error) {
			return &command.ServerCommand{
				Meta: meta,
				AuditBackends: map[string]audit.Factory{
					"file": auditFile.Factory,
				},
				CredentialBackends: map[string]logical.Factory{
					"app-id":   credAppId.Factory,
					"github":   credGitHub.Factory,
					"userpass": credUserpass.Factory,
				},
				LogicalBackends: map[string]logical.Factory{
					"aws":        aws.Factory,
					"consul":     consul.Factory,
					"postgresql": postgresql.Factory,
					"transit":    transit.Factory,
				},
			}, nil
		},

		"help": func() (cli.Command, error) {
			return &command.HelpCommand{
				Meta: meta,
			}, nil
		},

		"auth": func() (cli.Command, error) {
			return &command.AuthCommand{
				Meta: meta,
				Handlers: map[string]command.AuthHandler{
					"github":   &credGitHub.CLIHandler{},
					"userpass": &credUserpass.CLIHandler{},
				},
			}, nil
		},

		"auth-enable": func() (cli.Command, error) {
			return &command.AuthEnableCommand{
				Meta: meta,
			}, nil
		},

		"auth-disable": func() (cli.Command, error) {
			return &command.AuthDisableCommand{
				Meta: meta,
			}, nil
		},

		"audit-list": func() (cli.Command, error) {
			return &command.AuditListCommand{
				Meta: meta,
			}, nil
		},

		"audit-disable": func() (cli.Command, error) {
			return &command.AuditDisableCommand{
				Meta: meta,
			}, nil
		},

		"audit-enable": func() (cli.Command, error) {
			return &command.AuditEnableCommand{
				Meta: meta,
			}, nil
		},

		"policies": func() (cli.Command, error) {
			return &command.PolicyListCommand{
				Meta: meta,
			}, nil
		},

		"policy-delete": func() (cli.Command, error) {
			return &command.PolicyDeleteCommand{
				Meta: meta,
			}, nil
		},

		"policy-write": func() (cli.Command, error) {
			return &command.PolicyWriteCommand{
				Meta: meta,
			}, nil
		},

		"read": func() (cli.Command, error) {
			return &command.ReadCommand{
				Meta: meta,
			}, nil
		},

		"write": func() (cli.Command, error) {
			return &command.WriteCommand{
				Meta: meta,
			}, nil
		},

		"delete": func() (cli.Command, error) {
			return &command.DeleteCommand{
				Meta: meta,
			}, nil
		},

		"renew": func() (cli.Command, error) {
			return &command.RenewCommand{
				Meta: meta,
			}, nil
		},

		"revoke": func() (cli.Command, error) {
			return &command.RevokeCommand{
				Meta: meta,
			}, nil
		},

		"seal": func() (cli.Command, error) {
			return &command.SealCommand{
				Meta: meta,
			}, nil
		},

		"seal-status": func() (cli.Command, error) {
			return &command.SealStatusCommand{
				Meta: meta,
			}, nil
		},

		"unseal": func() (cli.Command, error) {
			return &command.UnsealCommand{
				Meta: meta,
			}, nil
		},

		"mount": func() (cli.Command, error) {
			return &command.MountCommand{
				Meta: meta,
			}, nil
		},

		"mounts": func() (cli.Command, error) {
			return &command.MountsCommand{
				Meta: meta,
			}, nil
		},

		"remount": func() (cli.Command, error) {
			return &command.RemountCommand{
				Meta: meta,
			}, nil
		},

		"unmount": func() (cli.Command, error) {
			return &command.UnmountCommand{
				Meta: meta,
			}, nil
		},

		"token-create": func() (cli.Command, error) {
			return &command.TokenCreateCommand{
				Meta: meta,
			}, nil
		},

		"token-revoke": func() (cli.Command, error) {
			return &command.TokenRevokeCommand{
				Meta: meta,
			}, nil
		},

		"version": func() (cli.Command, error) {
			ver := Version
			rel := VersionPrerelease
			if GitDescribe != "" {
				ver = GitDescribe
			}
			if GitDescribe == "" && rel == "" {
				rel = "dev"
			}

			return &command.VersionCommand{
				Revision:          GitCommit,
				Version:           ver,
				VersionPrerelease: rel,
				Ui:                meta.Ui,
			}, nil
		},

		// The commands below are hidden from the help output
		"token-disk": func() (cli.Command, error) {
			return &tokenDisk.Command{}, nil
		},
	}
}
<commit_msg>cli: add token-renew<commit_after>package cli

import (
	"os"

	auditFile "github.com/hashicorp/vault/builtin/audit/file"

	credAppId "github.com/hashicorp/vault/builtin/credential/app-id"
	credGitHub "github.com/hashicorp/vault/builtin/credential/github"
	credUserpass "github.com/hashicorp/vault/builtin/credential/userpass"

	"github.com/hashicorp/vault/builtin/logical/aws"
	"github.com/hashicorp/vault/builtin/logical/consul"
	"github.com/hashicorp/vault/builtin/logical/postgresql"
	"github.com/hashicorp/vault/builtin/logical/transit"

	"github.com/hashicorp/vault/audit"
	tokenDisk "github.com/hashicorp/vault/builtin/token/disk"
	"github.com/hashicorp/vault/command"
	"github.com/hashicorp/vault/logical"
	"github.com/mitchellh/cli"
)

// Commands returns the mapping of CLI commands for Vault. The meta
// parameter lets you set meta options for all commands.
func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory {
	if metaPtr == nil {
		metaPtr = new(command.Meta)
	}

	meta := *metaPtr
	if meta.Ui == nil {
		meta.Ui = &cli.BasicUi{
			Writer:      os.Stdout,
			ErrorWriter: os.Stderr,
		}
	}

	return map[string]cli.CommandFactory{
		"init": func() (cli.Command, error) {
			return &command.InitCommand{
				Meta: meta,
			}, nil
		},

		"server": func() (cli.Command, error) {
			return &command.ServerCommand{
				Meta: meta,
				AuditBackends: map[string]audit.Factory{
					"file": auditFile.Factory,
				},
				CredentialBackends: map[string]logical.Factory{
					"app-id":   credAppId.Factory,
					"github":   credGitHub.Factory,
					"userpass": credUserpass.Factory,
				},
				LogicalBackends: map[string]logical.Factory{
					"aws":        aws.Factory,
					"consul":     consul.Factory,
					"postgresql": postgresql.Factory,
					"transit":    transit.Factory,
				},
			}, nil
		},

		"help": func() (cli.Command, error) {
			return &command.HelpCommand{
				Meta: meta,
			}, nil
		},

		"auth": func() (cli.Command, error) {
			return &command.AuthCommand{
				Meta: meta,
				Handlers: map[string]command.AuthHandler{
					"github":   &credGitHub.CLIHandler{},
					"userpass": &credUserpass.CLIHandler{},
				},
			}, nil
		},

		"auth-enable": func() (cli.Command, error) {
			return &command.AuthEnableCommand{
				Meta: meta,
			}, nil
		},

		"auth-disable": func() (cli.Command, error) {
			return &command.AuthDisableCommand{
				Meta: meta,
			}, nil
		},

		"audit-list": func() (cli.Command, error) {
			return &command.AuditListCommand{
				Meta: meta,
			}, nil
		},

		"audit-disable": func() (cli.Command, error) {
			return &command.AuditDisableCommand{
				Meta: meta,
			}, nil
		},

		"audit-enable": func() (cli.Command, error) {
			return &command.AuditEnableCommand{
				Meta: meta,
			}, nil
		},

		"policies": func() (cli.Command, error) {
			return &command.PolicyListCommand{
				Meta: meta,
			}, nil
		},

		"policy-delete": func() (cli.Command, error) {
			return &command.PolicyDeleteCommand{
				Meta: meta,
			}, nil
		},

		"policy-write": func() (cli.Command, error) {
			return &command.PolicyWriteCommand{
				Meta: meta,
			}, nil
		},

		"read": func() (cli.Command, error) {
			return &command.ReadCommand{
				Meta: meta,
			}, nil
		},

		"write": func() (cli.Command, error) {
			return &command.WriteCommand{
				Meta: meta,
			}, nil
		},

		"delete": func() (cli.Command, error) {
			return &command.DeleteCommand{
				Meta: meta,
			}, nil
		},

		"renew": func() (cli.Command, error) {
			return &command.RenewCommand{
				Meta: meta,
			}, nil
		},

		"revoke": func() (cli.Command, error) {
			return &command.RevokeCommand{
				Meta: meta,
			}, nil
		},

		"seal": func() (cli.Command, error) {
			return &command.SealCommand{
				Meta: meta,
			}, nil
		},

		"seal-status": func() (cli.Command, error) {
			return &command.SealStatusCommand{
				Meta: meta,
			}, nil
		},

		"unseal": func() (cli.Command, error) {
			return &command.UnsealCommand{
				Meta: meta,
			}, nil
		},

		"mount": func() (cli.Command, error) {
			return &command.MountCommand{
				Meta: meta,
			}, nil
		},

		"mounts": func() (cli.Command, error) {
			return &command.MountsCommand{
				Meta: meta,
			}, nil
		},

		"remount": func() (cli.Command, error) {
			return &command.RemountCommand{
				Meta: meta,
			}, nil
		},

		"unmount": func() (cli.Command, error) {
			return &command.UnmountCommand{
				Meta: meta,
			}, nil
		},

		"token-create": func() (cli.Command, error) {
			return &command.TokenCreateCommand{
				Meta: meta,
			}, nil
		},

		"token-renew": func() (cli.Command, error) {
			return &command.TokenRenewCommand{
				Meta: meta,
			}, nil
		},

		"token-revoke": func() (cli.Command, error) {
			return &command.TokenRevokeCommand{
				Meta: meta,
			}, nil
		},

		"version": func() (cli.Command, error) {
			ver := Version
			rel := VersionPrerelease
			if GitDescribe != "" {
				ver = GitDescribe
			}
			if GitDescribe == "" && rel == "" {
				rel = "dev"
			}

			return &command.VersionCommand{
				Revision:          GitCommit,
				Version:           ver,
				VersionPrerelease: rel,
				Ui:                meta.Ui,
			}, nil
		},

		// The commands below are hidden from the help output
		"token-disk": func() (cli.Command, error) {
			return &tokenDisk.Command{}, nil
		},
	}
}
<|endoftext|>


<commit_before>package client

import (
	"context"

	"github.com/moby/buildkit/client/buildid"
	gateway "github.com/moby/buildkit/frontend/gateway/client"
	"github.com/moby/buildkit/frontend/gateway/grpcclient"
	gatewayapi "github.com/moby/buildkit/frontend/gateway/pb"
	"github.com/moby/buildkit/session"
	"github.com/moby/buildkit/util/apicaps"
	"github.com/pkg/errors"
	"google.golang.org/grpc"
)

func (c *Client) Build(ctx context.Context, opt SolveOpt, product string, buildFunc gateway.BuildFunc, statusChan chan *SolveStatus) (*SolveResponse, error) {
	defer func() {
		if statusChan != nil {
			close(statusChan)
		}
	}()

	if opt.Frontend != "" {
		return nil, errors.New("invalid SolveOpt, Build interface cannot use Frontend")
	}

	if product == "" {
		product = apicaps.ExportedProduct
	}

	feOpts := opt.FrontendAttrs
	opt.FrontendAttrs = nil

	workers, err := c.ListWorkers(ctx)
	if err != nil {
		return nil, errors.Wrap(err, "listing workers for Build")
	}
	var gworkers []gateway.WorkerInfo
	for _, w := range workers {
		gworkers = append(gworkers, gateway.WorkerInfo{
			ID:        w.ID,
			Labels:    w.Labels,
			Platforms: w.Platforms,
		})
	}

	cb := func(ref string, s *session.Session) error {
		g, err := grpcclient.New(ctx, feOpts, s.ID(), product, c.gatewayClientForBuild(ref), gworkers)
		if err != nil {
			return err
		}

		if err := g.Run(ctx, buildFunc); err != nil {
			return errors.Wrap(err, "failed to run Build function")
		}
		return nil
	}

	return c.solve(ctx, nil, cb, opt, statusChan)
}

func (c *Client) gatewayClientForBuild(buildid string) gatewayapi.LLBBridgeClient {
	g := gatewayapi.NewLLBBridgeClient(c.conn)
	return &gatewayClientForBuild{g, buildid}
}

type gatewayClientForBuild struct {
	gateway gatewayapi.LLBBridgeClient
	buildID string
}

func (g *gatewayClientForBuild) ResolveImageConfig(ctx context.Context, in *gatewayapi.ResolveImageConfigRequest, opts ...grpc.CallOption) (*gatewayapi.ResolveImageConfigResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.ResolveImageConfig(ctx, in, opts...)
}

func (g *gatewayClientForBuild) Solve(ctx context.Context, in *gatewayapi.SolveRequest, opts ...grpc.CallOption) (*gatewayapi.SolveResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.Solve(ctx, in, opts...)
}

func (g *gatewayClientForBuild) ReadFile(ctx context.Context, in *gatewayapi.ReadFileRequest, opts ...grpc.CallOption) (*gatewayapi.ReadFileResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.ReadFile(ctx, in, opts...)
}

func (g *gatewayClientForBuild) ReadDir(ctx context.Context, in *gatewayapi.ReadDirRequest, opts ...grpc.CallOption) (*gatewayapi.ReadDirResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.ReadDir(ctx, in, opts...)
}

func (g *gatewayClientForBuild) StatFile(ctx context.Context, in *gatewayapi.StatFileRequest, opts ...grpc.CallOption) (*gatewayapi.StatFileResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.StatFile(ctx, in, opts...)
}

func (g *gatewayClientForBuild) Ping(ctx context.Context, in *gatewayapi.PingRequest, opts ...grpc.CallOption) (*gatewayapi.PongResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.Ping(ctx, in, opts...)
}

func (g *gatewayClientForBuild) Return(ctx context.Context, in *gatewayapi.ReturnRequest, opts ...grpc.CallOption) (*gatewayapi.ReturnResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.Return(ctx, in, opts...)
}

func (g *gatewayClientForBuild) Inputs(ctx context.Context, in *gatewayapi.InputsRequest, opts ...grpc.CallOption) (*gatewayapi.InputsResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.Inputs(ctx, in, opts...)
}

func (g *gatewayClientForBuild) NewContainer(ctx context.Context, in *gatewayapi.NewContainerRequest, opts ...grpc.CallOption) (*gatewayapi.NewContainerResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.NewContainer(ctx, in, opts...)
}

func (g *gatewayClientForBuild) ReleaseContainer(ctx context.Context, in *gatewayapi.ReleaseContainerRequest, opts ...grpc.CallOption) (*gatewayapi.ReleaseContainerResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.ReleaseContainer(ctx, in, opts...)
}

func (g *gatewayClientForBuild) ExecProcess(ctx context.Context, opts ...grpc.CallOption) (gatewayapi.LLBBridge_ExecProcessClient, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.ExecProcess(ctx, opts...)
}
<commit_msg>add cap support check to gatewayClientForBuild<commit_after>package client

import (
	"context"

	"github.com/moby/buildkit/client/buildid"
	gateway "github.com/moby/buildkit/frontend/gateway/client"
	"github.com/moby/buildkit/frontend/gateway/grpcclient"
	gatewayapi "github.com/moby/buildkit/frontend/gateway/pb"
	"github.com/moby/buildkit/session"
	"github.com/moby/buildkit/util/apicaps"
	"github.com/pkg/errors"
	"google.golang.org/grpc"
)

func (c *Client) Build(ctx context.Context, opt SolveOpt, product string, buildFunc gateway.BuildFunc, statusChan chan *SolveStatus) (*SolveResponse, error) {
	defer func() {
		if statusChan != nil {
			close(statusChan)
		}
	}()

	if opt.Frontend != "" {
		return nil, errors.New("invalid SolveOpt, Build interface cannot use Frontend")
	}

	if product == "" {
		product = apicaps.ExportedProduct
	}

	feOpts := opt.FrontendAttrs
	opt.FrontendAttrs = nil

	workers, err := c.ListWorkers(ctx)
	if err != nil {
		return nil, errors.Wrap(err, "listing workers for Build")
	}
	var gworkers []gateway.WorkerInfo
	for _, w := range workers {
		gworkers = append(gworkers, gateway.WorkerInfo{
			ID:        w.ID,
			Labels:    w.Labels,
			Platforms: w.Platforms,
		})
	}

	cb := func(ref string, s *session.Session) error {
		gwClient := c.gatewayClientForBuild(ref)
		g, err := grpcclient.New(ctx, feOpts, s.ID(), product, gwClient, gworkers)
		if err != nil {
			return err
		}

		if c, ok := g.(gateway.Client); ok {
			gwClient.caps = c.BuildOpts().Caps
		}

		if err := g.Run(ctx, buildFunc); err != nil {
			return errors.Wrap(err, "failed to run Build function")
		}
		return nil
	}

	return c.solve(ctx, nil, cb, opt, statusChan)
}

func (c *Client) gatewayClientForBuild(buildid string) *gatewayClientForBuild {
	g := gatewayapi.NewLLBBridgeClient(c.conn)
	return &gatewayClientForBuild{
		gateway: g,
		buildID: buildid,
	}
}

type gatewayClientForBuild struct {
	gateway gatewayapi.LLBBridgeClient
	buildID string
	caps    apicaps.CapSet
}

func (g *gatewayClientForBuild) ResolveImageConfig(ctx context.Context, in *gatewayapi.ResolveImageConfigRequest, opts ...grpc.CallOption) (*gatewayapi.ResolveImageConfigResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.ResolveImageConfig(ctx, in, opts...)
}

func (g *gatewayClientForBuild) Solve(ctx context.Context, in *gatewayapi.SolveRequest, opts ...grpc.CallOption) (*gatewayapi.SolveResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.Solve(ctx, in, opts...)
}

func (g *gatewayClientForBuild) ReadFile(ctx context.Context, in *gatewayapi.ReadFileRequest, opts ...grpc.CallOption) (*gatewayapi.ReadFileResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.ReadFile(ctx, in, opts...)
}

func (g *gatewayClientForBuild) ReadDir(ctx context.Context, in *gatewayapi.ReadDirRequest, opts ...grpc.CallOption) (*gatewayapi.ReadDirResponse, error) {
	if err := g.caps.Supports(gatewayapi.CapReadDir); err != nil {
		return nil, err
	}
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.ReadDir(ctx, in, opts...)
}

func (g *gatewayClientForBuild) StatFile(ctx context.Context, in *gatewayapi.StatFileRequest, opts ...grpc.CallOption) (*gatewayapi.StatFileResponse, error) {
	if err := g.caps.Supports(gatewayapi.CapStatFile); err != nil {
		return nil, err
	}
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.StatFile(ctx, in, opts...)
}

func (g *gatewayClientForBuild) Ping(ctx context.Context, in *gatewayapi.PingRequest, opts ...grpc.CallOption) (*gatewayapi.PongResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.Ping(ctx, in, opts...)
}

func (g *gatewayClientForBuild) Return(ctx context.Context, in *gatewayapi.ReturnRequest, opts ...grpc.CallOption) (*gatewayapi.ReturnResponse, error) {
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.Return(ctx, in, opts...)
}

func (g *gatewayClientForBuild) Inputs(ctx context.Context, in *gatewayapi.InputsRequest, opts ...grpc.CallOption) (*gatewayapi.InputsResponse, error) {
	if err := g.caps.Supports(gatewayapi.CapFrontendInputs); err != nil {
		return nil, err
	}
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.Inputs(ctx, in, opts...)
}

func (g *gatewayClientForBuild) NewContainer(ctx context.Context, in *gatewayapi.NewContainerRequest, opts ...grpc.CallOption) (*gatewayapi.NewContainerResponse, error) {
	if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil {
		return nil, err
	}
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.NewContainer(ctx, in, opts...)
}

func (g *gatewayClientForBuild) ReleaseContainer(ctx context.Context, in *gatewayapi.ReleaseContainerRequest, opts ...grpc.CallOption) (*gatewayapi.ReleaseContainerResponse, error) {
	if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil {
		return nil, err
	}
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.ReleaseContainer(ctx, in, opts...)
}

func (g *gatewayClientForBuild) ExecProcess(ctx context.Context, opts ...grpc.CallOption) (gatewayapi.LLBBridge_ExecProcessClient, error) {
	if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil {
		return nil, err
	}
	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
	return g.gateway.ExecProcess(ctx, opts...)
}
<|endoftext|>


<commit_before>package fs

import (
	"errors"
	"io"
)

// ReadReadAtCloser is the interface that groups the basic Read,
// ReadAt, and Close methods.
type ReadReadAtCloser interface {
	io.ReadCloser
	io.ReaderAt
}

// ReadStream defines the interface for streaming file reads. This is
// usually implemented by *os.File, but there might be other
// implementations for testing.
type ReadStream interface {
	// This object must not be used once it is
	// closed. Implementations should return an error in that
	// case, or panic if that isn't possible.
	ReadReadAtCloser

	// TODO: Once streaming is used everywhere, figure out which
	// of these functions we still need.

	// Offset returns the current offset of the ReadStream, like
	// what would be returned by a call to Seek(0, io.SeekCurrent).
	Offset() int64
	ByteCount() int64
}

type readReadAtCloserStream struct {
	ReadReadAtCloser
	offset    int64
	byteCount int64
}

func (r *readReadAtCloserStream) Read(p []byte) (n int, err error) {
	n, err = r.ReadReadAtCloser.Read(p)
	r.offset += int64(n)
	return n, err
}

func (r readReadAtCloserStream) Offset() int64 {
	return r.offset
}

func (r readReadAtCloserStream) ByteCount() int64 {
	return r.byteCount
}

// ReadReadAtCloserToStream makes and returns a ReadStream out of the
// given ReadReadAtCloser and byte count.
func ReadReadAtCloserToStream(readReadAtCloser ReadReadAtCloser, byteCount int64) ReadStream {
	return &readReadAtCloserStream{readReadAtCloser, 0, byteCount}
}

// WriteStream defines the interface for streaming file writes. This
// is usually implemented by *os.File, but there might be other
// implementations for testing.
type WriteStream interface {
	io.Writer
	io.Closer
}

// FS is the interface used by the par1 and par2 packages to the
// filesystem. Most code uses DefaultFS, but tests may use other
// implementations.
type FS interface {
	// GetReadStream returns a ReadStream to read the file at the
	// given path.
	//
	// Only one ReadStream may be open per (normalized)
	// path. Implementations should return an error in case
	// GetReadStream is called on a path with an open ReadStream.
	//
	// Implementations must guarantee that exactly one of the
	// returned ReadStream and error is non-nil.
	GetReadStream(path string) (ReadStream, error)
	// FindWithPrefixAndSuffix should behave like calling
	// filepath.Glob with prefix + "*" + suffix.
	FindWithPrefixAndSuffix(prefix, suffix string) ([]string, error)
	// GetFileReadSeekCloser returns a WriteStream to write to the
	// file at the given path.
	//
	// Implementations must guarantee that exactly one of the
	// returned WriteStream and error is non-nil.
	GetWriteStream(path string) (WriteStream, error)
}

// CloseCloser is a utility function that closes the given closer, and
// if *err is nil, sets it to the close error.
func CloseCloser(closer io.Closer, err *error) {
	closeErr := closer.Close()
	if *err == nil {
		*err = closeErr
	}
}

// readStrict checks that len(buf) != 0, calls r.Read(buf), and checks
// that the return value isn't 0, nil.
func readStrict(r io.Reader, buf []byte) (n int, err error) {
	if len(buf) == 0 {
		return 0, errors.New("len(buf) == 0 unexpectedly in readStrict")
	}
	n, err = r.Read(buf)
	if n == 0 && err == nil {
		return n, errors.New("r.Read() returned 0, nil")
	}
	return n, err
}

// ReadFull is like io.ReadFull, except that it:
//
//   - requires len(buf) to be non-zero,
//   - calls readStrict instead,
//   - doesn't drop the error even if the buffer is completely filled,
//     except when the error is EOF.
func ReadFull(r io.Reader, buf []byte) (n int, err error) {
	if len(buf) == 0 {
		return 0, errors.New("len(buf) == 0 unexpectedly in ReadFull")
	}
	for n < len(buf) && err == nil {
		var nn int
		nn, err = readStrict(r, buf[n:])
		n += nn
	}
	if n < len(buf) {
		// Loop termination condition guarantees err != nil.
		if err == io.EOF {
			err = io.ErrUnexpectedEOF
		}
		return n, err
	}
	// Now we know that n >= len(buf) (really n == len(buf)), so
	// we just have to examine err.
	if err == io.EOF {
		err = nil
	}
	return n, err
}

// ReadFullEOF is ReadFull with one more check:
//
//   - if the buffer is completely filled, checks that the next read from
//     the reader triggers an EOF.
func ReadFullEOF(r io.Reader, buf []byte) (n int, err error) {
	n, err = ReadFull(r, buf)
	if err != nil {
		return n, err
	}

	// Now we know that we filled up buf with no error (or EOF),
	// so now we just make sure that we're actually at EOF.
	var singleByte [1]byte
	_, err = readStrict(r, singleByte[:])
	if err == io.EOF {
		err = nil
	}
	return n, err
}

func ReadRemaining(readStream ReadStream) (data []byte, err error) {
	bytesRemaining := readStream.ByteCount() - readStream.Offset()
	if int64(int(bytesRemaining)) != bytesRemaining {
		return nil, errors.New("file too big to read into memory")
	}
	data = make([]byte, bytesRemaining)
	if len(data) > 0 {
		_, err = ReadFullEOF(readStream, data)
		if err != nil {
			return nil, err
		}
	}
	return data, nil
}

// ReadAndClose reads all the data in the given io.ReadCloser into a
// buffer and returns it, closing it in all cases.
//
// If err == nil, the returned buffer will never be nil, even if it
// has length 0.
//
// TODO: Make this function unnecessary.
func ReadAndClose(readStream ReadStream) (data []byte, err error) {
	defer CloseCloser(readStream, &err)
	return ReadRemaining(readStream)
}

// WriteAndClose write all the data in the given buffer to the given
// WriteStream, closing it in all cases.
//
// TODO: Make this function unnecessary.
func WriteAndClose(writeStream WriteStream, p []byte) (err error) {
	defer CloseCloser(writeStream, &err)
	_, err = writeStream.Write(p)
	return err
}
<commit_msg>Fix golint<commit_after>package fs

import (
	"errors"
	"io"
)

// ReadReadAtCloser is the interface that groups the basic Read,
// ReadAt, and Close methods.
type ReadReadAtCloser interface {
	io.ReadCloser
	io.ReaderAt
}

// ReadStream defines the interface for streaming file reads. This is
// usually implemented by *os.File, but there might be other
// implementations for testing.
type ReadStream interface {
	// This object must not be used once it is
	// closed. Implementations should return an error in that
	// case, or panic if that isn't possible.
	ReadReadAtCloser

	// TODO: Once streaming is used everywhere, figure out which
	// of these functions we still need.

	// Offset returns the current offset of the ReadStream, like
	// what would be returned by a call to Seek(0, io.SeekCurrent).
	Offset() int64
	ByteCount() int64
}

type readReadAtCloserStream struct {
	ReadReadAtCloser
	offset    int64
	byteCount int64
}

func (r *readReadAtCloserStream) Read(p []byte) (n int, err error) {
	n, err = r.ReadReadAtCloser.Read(p)
	r.offset += int64(n)
	return n, err
}

func (r readReadAtCloserStream) Offset() int64 {
	return r.offset
}

func (r readReadAtCloserStream) ByteCount() int64 {
	return r.byteCount
}

// ReadReadAtCloserToStream makes and returns a ReadStream out of the
// given ReadReadAtCloser and byte count.
func ReadReadAtCloserToStream(readReadAtCloser ReadReadAtCloser, byteCount int64) ReadStream {
	return &readReadAtCloserStream{readReadAtCloser, 0, byteCount}
}

// WriteStream defines the interface for streaming file writes. This
// is usually implemented by *os.File, but there might be other
// implementations for testing.
type WriteStream interface {
	io.Writer
	io.Closer
}

// FS is the interface used by the par1 and par2 packages to the
// filesystem. Most code uses DefaultFS, but tests may use other
// implementations.
type FS interface {
	// GetReadStream returns a ReadStream to read the file at the
	// given path.
	//
	// Only one ReadStream may be open per (normalized)
	// path. Implementations should return an error in case
	// GetReadStream is called on a path with an open ReadStream.
	//
	// Implementations must guarantee that exactly one of the
	// returned ReadStream and error is non-nil.
	GetReadStream(path string) (ReadStream, error)
	// FindWithPrefixAndSuffix should behave like calling
	// filepath.Glob with prefix + "*" + suffix.
	FindWithPrefixAndSuffix(prefix, suffix string) ([]string, error)
	// GetFileReadSeekCloser returns a WriteStream to write to the
	// file at the given path.
	//
	// Implementations must guarantee that exactly one of the
	// returned WriteStream and error is non-nil.
	GetWriteStream(path string) (WriteStream, error)
}

// CloseCloser is a utility function that closes the given closer, and
// if *err is nil, sets it to the close error.
func CloseCloser(closer io.Closer, err *error) {
	closeErr := closer.Close()
	if *err == nil {
		*err = closeErr
	}
}

// readStrict checks that len(buf) != 0, calls r.Read(buf), and checks
// that the return value isn't 0, nil.
func readStrict(r io.Reader, buf []byte) (n int, err error) {
	if len(buf) == 0 {
		return 0, errors.New("len(buf) == 0 unexpectedly in readStrict")
	}
	n, err = r.Read(buf)
	if n == 0 && err == nil {
		return n, errors.New("r.Read() returned 0, nil")
	}
	return n, err
}

// ReadFull is like io.ReadFull, except that it:
//
//   - requires len(buf) to be non-zero,
//   - calls readStrict instead,
//   - doesn't drop the error even if the buffer is completely filled,
//     except when the error is EOF.
func ReadFull(r io.Reader, buf []byte) (n int, err error) {
	if len(buf) == 0 {
		return 0, errors.New("len(buf) == 0 unexpectedly in ReadFull")
	}
	for n < len(buf) && err == nil {
		var nn int
		nn, err = readStrict(r, buf[n:])
		n += nn
	}
	if n < len(buf) {
		// Loop termination condition guarantees err != nil.
		if err == io.EOF {
			err = io.ErrUnexpectedEOF
		}
		return n, err
	}
	// Now we know that n >= len(buf) (really n == len(buf)), so
	// we just have to examine err.
	if err == io.EOF {
		err = nil
	}
	return n, err
}

// ReadFullEOF is ReadFull with one more check:
//
//   - if the buffer is completely filled, checks that the next read from
//     the reader triggers an EOF.
func ReadFullEOF(r io.Reader, buf []byte) (n int, err error) {
	n, err = ReadFull(r, buf)
	if err != nil {
		return n, err
	}

	// Now we know that we filled up buf with no error (or EOF),
	// so now we just make sure that we're actually at EOF.
	var singleByte [1]byte
	_, err = readStrict(r, singleByte[:])
	if err == io.EOF {
		err = nil
	}
	return n, err
}

// ReadRemaining TODO: fill in.
func ReadRemaining(readStream ReadStream) (data []byte, err error) {
	bytesRemaining := readStream.ByteCount() - readStream.Offset()
	if int64(int(bytesRemaining)) != bytesRemaining {
		return nil, errors.New("file too big to read into memory")
	}
	data = make([]byte, bytesRemaining)
	if len(data) > 0 {
		_, err = ReadFullEOF(readStream, data)
		if err != nil {
			return nil, err
		}
	}
	return data, nil
}

// ReadAndClose reads all the data in the given io.ReadCloser into a
// buffer and returns it, closing it in all cases.
//
// If err == nil, the returned buffer will never be nil, even if it
// has length 0.
//
// TODO: Make this function unnecessary.
func ReadAndClose(readStream ReadStream) (data []byte, err error) {
	defer CloseCloser(readStream, &err)
	return ReadRemaining(readStream)
}

// WriteAndClose write all the data in the given buffer to the given
// WriteStream, closing it in all cases.
//
// TODO: Make this function unnecessary.
func WriteAndClose(writeStream WriteStream, p []byte) (err error) {
	defer CloseCloser(writeStream, &err)
	_, err = writeStream.Write(p)
	return err
}
<|endoftext|>