<commit_before>package runtime

import (
    "fmt"
    "strings"
    "github.com/cloudson/gitql/parser"
    "github.com/libgit2/git2go"
    "github.com/crackcomm/go-clitable"
)

const (
    WALK_COMMITS = 1
    WALK_TREES = 2
    WALK_REFERENCES = 3
    WALK_REMOTES = 4
)

const (
    REFERENCE_TYPE_BRANCH = "branch"
    REFERENCE_TYPE_REMOTE = "remote"
    REFERENCE_TYPE_TAG = "tag"
)

var repo *git.Repository
var builder *GitBuilder
var boolRegister bool

type tableRow map[string]interface{}

type GitBuilder struct {
    tables map[string]string
    possibleTables map[string][]string
    repo *git.Repository
    currentWalkType uint8
    currentCommit *git.Commit
    currentReference *git.Reference
    currentRemote *git.Remote
    walk *git.RevWalk

}

type RuntimeError struct {
    code uint8
    message string
}

type RuntimeVisitor struct {

}

// =========================== Runtime
func Run(n *parser.NodeProgram) {
    builder = GetGitBuilder(n.Path)
    visitor := new(RuntimeVisitor)
    err := visitor.Visit(n)
    if err != nil {
        panic(err)
    }
    switch findWalkType(n) {
        case WALK_COMMITS:
            walkCommits(n, visitor)
            break
        case WALK_TREES:
            walkTrees(n, visitor)
            break
        case WALK_REFERENCES:
            walkReferences(n, visitor)
        case WALK_REMOTES:
            walkRemotes(n, visitor)
    }
}

func findWalkType(n *parser.NodeProgram) uint8 {
    s := n.Child.(*parser.NodeSelect)

    switch s.Tables[0] {
        case "commits" :
            builder.currentWalkType = WALK_COMMITS
        case "trees" :
            builder.currentWalkType = WALK_TREES
        case "refs":
            builder.currentWalkType = WALK_REFERENCES
        case "remotes":
            builder.currentWalkType = WALK_REMOTES
    }

    return builder.currentWalkType
}

func walkCommits(n *parser.NodeProgram, visitor *RuntimeVisitor) {
    builder.walk, _ = repo.Walk()
    builder.walk.PushHead()
    builder.walk.Sorting(git.SortTime)

    s := n.Child.(*parser.NodeSelect)
    where := s.Where

    counter := 1
    fields := s.Fields
    if s.WildCard {
        fields = builder.possibleTables[s.Tables[0]]
    }
    rows := make([]tableRow, s.Limit)
    fn := func (object *git.Commit) bool {
        builder.setCommit(object)
        boolRegister = true
        visitor.VisitExpr(where)
        if boolRegister {
            newRow := make(tableRow)
            for _, f := range fields {
                newRow[f] = metadataCommit(f, object)
            }
            rows = append(rows, newRow)

            counter = counter + 1
        }
        if counter > s.Limit {
            return false
        }
        return true
    }

    err := builder.walk.Iterate(fn)
    if err != nil {
        fmt.Printf(err.Error())
    }
    rowsSliced := rows[len(rows) - counter + 1:]
    rowsSliced = orderTable(rowsSliced, s.Order)
    printTable(rowsSliced, fields)

}

func printTable(rows []tableRow, fields []string) {
    table := clitable.New(fields)
    for _, r := range rows {
        table.AddRow(r)
    }
    table.Print()
}

func orderTable(rows []tableRow, order *parser.NodeOrder)([]tableRow){
    if order == nil {
        return rows
    }
    // We will use parser.NodeGreater.Assertion(A, B) to know if
    // A > B and then switch their positions.
    // Unfortunaly, we will use bubble sort, that is O(n²)
    // @todo change to quick or other better sort.
    var orderer parser.NodeExpr
    if order.Asc {
        orderer = new(parser.NodeGreater)
    } else {
        orderer = new(parser.NodeSmaller)
    }

    field := order.Field
    for i, row := range rows {
        for j, rowWalk := range rows {
            if orderer.Assertion(fmt.Sprintf("%v", rowWalk[field]), fmt.Sprintf("%v",row[field])) {
                aux := rows[j]
                rows[j] = rows[i]
                rows[i] = aux
            }
        }
    }

    return rows
}

func walkTrees(n *parser.NodeProgram, visitor *RuntimeVisitor) {
    // not yet!
}

func walkReferences(n *parser.NodeProgram, visitor *RuntimeVisitor) {
    s := n.Child.(*parser.NodeSelect)
    where := s.Where

    // @TODO make PR with Repository.WalkReference()
    iterator, err := builder.repo.NewReferenceIterator()
    if err != nil {
        panic(err)
    }
    counter := 1
    fields := s.Fields
    if s.WildCard {
        fields = builder.possibleTables[s.Tables[0]]
    }
    rows := make([]tableRow, s.Limit)
    for object, inTheEnd := iterator.Next(); inTheEnd == nil; object, inTheEnd = iterator.Next() {

        builder.setReference(object)
        boolRegister = true
        visitor.VisitExpr(where)
        if boolRegister {
            fields := s.Fields
            if s.WildCard {
                fields = builder.possibleTables[s.Tables[0]]
            }
            newRow := make(tableRow)
            for _, f := range fields {
                newRow[f] = metadataReference(f, object)
            }
            rows = append(rows, newRow)
            counter = counter + 1
            if counter > s.Limit {
                break
            }
        }
    }
    printTable(rows, fields)
}

func walkRemotes(n *parser.NodeProgram, visitor *RuntimeVisitor) {
    s := n.Child.(*parser.NodeSelect)
    where := s.Where

    remoteNames, err := builder.repo.ListRemotes()
    if err != nil {
        panic(err)
    }

    counter := 1

    fields := s.Fields
    if s.WildCard {
        fields = builder.possibleTables[s.Tables[0]]
    }
    rows := make([]tableRow, s.Limit)
    for _, remoteName := range remoteNames {
        object, errRemote := builder.repo.LoadRemote(remoteName)
        if errRemote != nil {
            panic(errRemote)
        }

        builder.setRemote(object)
        boolRegister = true
        visitor.VisitExpr(where)
        if boolRegister {
            newRow := make(map[string]interface{})
            for _, f := range fields {
                newRow[f] = metadataRemote(f, object)
            }
            rows = append(rows, newRow)

            counter = counter + 1
            if counter > s.Limit {
                break
            }
        }
    }
    printTable(rows, fields)
}

func metadata(identifier string) string {
    switch builder.currentWalkType {
        case WALK_COMMITS:
            return metadataCommit(identifier, builder.currentCommit)
        case WALK_REFERENCES:
            return metadataReference(identifier, builder.currentReference)
        case WALK_REMOTES:
            return metadataRemote(identifier, builder.currentRemote)
    }

    panic("GOD!")
}

func metadataTree(identifier string, object *git.TreeEntry) string {
    return "" // not yet implemented!
}

func metadataReference(identifier string, object *git.Reference) string {
    key := ""
    for key, _ = range builder.tables {
        break
    }
    table := key
    err := builder.UseFieldFromTable(identifier, table)
    if err != nil {
        panic(err)
    }
    switch identifier {
        case "name":
            return object.Shorthand()
        case "full_name" :
            return object.Name()
        case "hash" :
            target := object.Target()
            if target == nil {
                return "NULL"
            }
            return target.String()
        case "type":
            if object.IsBranch() {
                return REFERENCE_TYPE_BRANCH
            }

            if object.IsRemote() {
                return REFERENCE_TYPE_REMOTE
            }

            if object.IsTag() {
                return REFERENCE_TYPE_TAG
            }
    }

    panic(fmt.Sprintf("Field %s not implemented yet", identifier))
}

func metadataCommit(identifier string, object *git.Commit) string {
    key := ""
    for key, _ = range builder.tables {
        break
    }
    table := key
    err := builder.UseFieldFromTable(identifier, table)
    if err != nil {
        panic(err)
    }
    switch identifier {
        case "hash" :
            return object.Id().String()
        case "author":
            return object.Author().Name
        case "author_email":
            return object.Author().Email
        case "committer":
            return object.Committer().Name
        case "committer_email":
            return object.Committer().Email
        case "date":
            return object.Committer().When.Format(parser.Time_YMDHIS)
        case "full_message":
            return object.Message()
        case "message":
            // return first line of a commit message
            message := object.Message()
            r := []rune("\n")
            idx := strings.IndexRune(message, r[0])
            if idx != -1 {
                message = message[0:idx]
            }
            return message

    }

    panic(fmt.Sprintf("Field %s not implemented yet", identifier))
}

func metadataRemote(identifier string, object *git.Remote) string {
    key := ""
    for key, _ = range builder.tables {
        break
    }
    table := key
    err := builder.UseFieldFromTable(identifier, table)
    if err != nil {
        panic(err)
    }
    switch identifier {
       case "name":
            return object.Name()
       case "url":
            return object.Url()
       case "push_url":
            return object.PushUrl()
       case "owner":
            repo := object.Owner()
            r := &repo
            return r.Path()
    }

    panic(fmt.Sprintf("Field %s not implemented yet", identifier))
}

// =========================== Error

func (e *RuntimeError) Error() string{
    return e.message
}

func throwRuntimeError(message string, code uint8) (*RuntimeError) {
    e := new(RuntimeError)
    e.message = message
    e.code = code

    return e
}

// =================== GitBuilder

func GetGitBuilder(path *string) (*GitBuilder) {

    gb := new(GitBuilder)
    gb.tables = make(map[string]string)
    possibleTables := map[string][]string {
        "commits": {
            "hash",
            "date",
            "author",
            "author_email",
            "committer",
            "committer_email",
            "message",
            "full_message",
        },
        "trees": {
            "hash",
            "name",
            "id",
            "type",
            "filemode",
        },
        "refs": {
            "name",
            "full_name",
            "type",
            "hash",
        },
        "remotes": {
            "name",
            "url",
            "push_url",
            "owner",
        },
    }
    gb.possibleTables = possibleTables

    openRepository(path)

    gb.repo = repo

    return gb
}

func openRepository(path *string) {
    _repo, err := git.OpenRepository(*path)
    if err != nil {
        panic(err)
    }
    repo = _repo
}

func (g *GitBuilder) setCommit(object *git.Commit) {
    g.currentCommit = object
}

func (g *GitBuilder) setReference(object *git.Reference) {
    g.currentReference = object
}

func (g *GitBuilder) setRemote(object *git.Remote) {
    g.currentRemote = object
}

func (g *GitBuilder) WithTable(tableName string, alias string) error {
    err := g.isValidTable(tableName)
    if err != nil {
        return err
    }

    if g.possibleTables[tableName] == nil {
        return throwRuntimeError(fmt.Sprintf("Table '%s' not found", tableName), 0)
    }

    if alias == "" {
        alias = tableName
    }

    g.tables[alias] = tableName

    return nil
}

func (g *GitBuilder) isValidTable(tableName string) error {
    if g.possibleTables[tableName] == nil {
        return throwRuntimeError(fmt.Sprintf("Table '%s' not found", tableName), 0)
    }

    return nil
}

func (g *GitBuilder) UseFieldFromTable(field string, tableName string) error {
    if field == "*" {
        return nil
    }

    err := g.isValidTable(tableName)
    if err != nil {
        return err
    }

    table := g.possibleTables[tableName]
    for _, t := range table {
        if t == field {
            return nil
        }
    }

    return throwRuntimeError(fmt.Sprintf("Table '%s' has not field '%s'", tableName, field), 0)
}<commit_msg>Refactor whatever<commit_after>package runtime

import (
    "fmt"
    "strings"
    "github.com/cloudson/gitql/parser"
    "github.com/libgit2/git2go"
    "github.com/crackcomm/go-clitable"
)

const (
    WALK_COMMITS = 1
    WALK_TREES = 2
    WALK_REFERENCES = 3
    WALK_REMOTES = 4
)

const (
    REFERENCE_TYPE_BRANCH = "branch"
    REFERENCE_TYPE_REMOTE = "remote"
    REFERENCE_TYPE_TAG = "tag"
)

var repo *git.Repository
var builder *GitBuilder
var boolRegister bool

type tableRow map[string]interface{}

type GitBuilder struct {
    tables map[string]string
    possibleTables map[string][]string
    repo *git.Repository
    currentWalkType uint8
    currentCommit *git.Commit
    currentReference *git.Reference
    currentRemote *git.Remote
    walk *git.RevWalk

}

type RuntimeError struct {
    code uint8
    message string
}

type RuntimeVisitor struct {

}

// =========================== Runtime
func Run(n *parser.NodeProgram) {
    builder = GetGitBuilder(n.Path)
    visitor := new(RuntimeVisitor)
    err := visitor.Visit(n)
    if err != nil {
        panic(err)
    }
    switch findWalkType(n) {
        case WALK_COMMITS:
            walkCommits(n, visitor)
            break
        case WALK_TREES:
            walkTrees(n, visitor)
            break
        case WALK_REFERENCES:
            walkReferences(n, visitor)
            break
        case WALK_REMOTES:
            walkRemotes(n, visitor)
            break;
    }
}

func findWalkType(n *parser.NodeProgram) uint8 {
    s := n.Child.(*parser.NodeSelect)

    switch s.Tables[0] {
        case "commits" :
            builder.currentWalkType = WALK_COMMITS
        case "trees" :
            builder.currentWalkType = WALK_TREES
        case "refs":
            builder.currentWalkType = WALK_REFERENCES
        case "remotes":
            builder.currentWalkType = WALK_REMOTES
    }

    return builder.currentWalkType
}

func walkCommits(n *parser.NodeProgram, visitor *RuntimeVisitor) {
    builder.walk, _ = repo.Walk()
    builder.walk.PushHead()
    builder.walk.Sorting(git.SortTime)

    s := n.Child.(*parser.NodeSelect)
    where := s.Where

    counter := 1
    fields := s.Fields
    if s.WildCard {
        fields = builder.possibleTables[s.Tables[0]]
    }
    rows := make([]tableRow, s.Limit)
    fn := func (object *git.Commit) bool {
        builder.setCommit(object)
        boolRegister = true
        visitor.VisitExpr(where)
        if boolRegister {
            newRow := make(tableRow)
            for _, f := range fields {
                newRow[f] = metadataCommit(f, object)
            }
            rows = append(rows, newRow)

            counter = counter + 1
        }
        if counter > s.Limit {
            return false
        }
        return true
    }

    err := builder.walk.Iterate(fn)
    if err != nil {
        fmt.Printf(err.Error())
    }
    rowsSliced := rows[len(rows) - counter + 1:]
    rowsSliced = orderTable(rowsSliced, s.Order)
    printTable(rowsSliced, fields)

}

func walkReferences(n *parser.NodeProgram, visitor *RuntimeVisitor) {
    s := n.Child.(*parser.NodeSelect)
    where := s.Where

    // @TODO make PR with Repository.WalkReference()
    iterator, err := builder.repo.NewReferenceIterator()
    if err != nil {
        panic(err)
    }
    counter := 1
    fields := s.Fields
    if s.WildCard {
        fields = builder.possibleTables[s.Tables[0]]
    }
    rows := make([]tableRow, s.Limit)
    for object, inTheEnd := iterator.Next(); inTheEnd == nil; object, inTheEnd = iterator.Next() {

        builder.setReference(object)
        boolRegister = true
        visitor.VisitExpr(where)
        if boolRegister {
            fields := s.Fields
            if s.WildCard {
                fields = builder.possibleTables[s.Tables[0]]
            }
            newRow := make(tableRow)
            for _, f := range fields {
                newRow[f] = metadataReference(f, object)
            }
            rows = append(rows, newRow)
            counter = counter + 1
            if counter > s.Limit {
                break
            }
        }
    }
    rowsSliced := rows[len(rows) - counter + 1:]
    rowsSliced = orderTable(rowsSliced, s.Order)
    printTable(rowsSliced, fields)
}

func walkRemotes(n *parser.NodeProgram, visitor *RuntimeVisitor) {
    s := n.Child.(*parser.NodeSelect)
    where := s.Where

    remoteNames, err := builder.repo.ListRemotes()
    if err != nil {
        panic(err)
    }

    counter := 1

    fields := s.Fields
    if s.WildCard {
        fields = builder.possibleTables[s.Tables[0]]
    }
    rows := make([]tableRow, s.Limit)
    for _, remoteName := range remoteNames {
        object, errRemote := builder.repo.LoadRemote(remoteName)
        if errRemote != nil {
            panic(errRemote)
        }

        builder.setRemote(object)
        boolRegister = true
        visitor.VisitExpr(where)
        if boolRegister {
            newRow := make(map[string]interface{})
            for _, f := range fields {
                newRow[f] = metadataRemote(f, object)
            }
            rows = append(rows, newRow)

            counter = counter + 1
            if counter > s.Limit {
                break
            }
        }
    }
    rowsSliced := rows[len(rows) - counter + 1:]
    rowsSliced = orderTable(rowsSliced, s.Order)
    printTable(rowsSliced, fields)
}

func walkTrees(n *parser.NodeProgram, visitor *RuntimeVisitor) {

}

func printTable(rows []tableRow, fields []string) {
    table := clitable.New(fields)
    for _, r := range rows {
        table.AddRow(r)
    }
    table.Print()
}

func orderTable(rows []tableRow, order *parser.NodeOrder)([]tableRow){
    if order == nil {
        return rows
    }
    // We will use parser.NodeGreater.Assertion(A, B) to know if
    // A > B and then switch their positions.
    // Unfortunaly, we will use bubble sort, that is O(n²)
    // @todo change to quick or other better sort.
    var orderer parser.NodeExpr
    if order.Asc {
        orderer = new(parser.NodeGreater)
    } else {
        orderer = new(parser.NodeSmaller)
    }

    field := order.Field
    for i, row := range rows {
        for j, rowWalk := range rows {
            if orderer.Assertion(fmt.Sprintf("%v", rowWalk[field]), fmt.Sprintf("%v",row[field])) {
                aux := rows[j]
                rows[j] = rows[i]
                rows[i] = aux
            }
        }
    }

    return rows
}

func metadata(identifier string) string {
    switch builder.currentWalkType {
        case WALK_COMMITS:
            return metadataCommit(identifier, builder.currentCommit)
        case WALK_REFERENCES:
            return metadataReference(identifier, builder.currentReference)
        case WALK_REMOTES:
            return metadataRemote(identifier, builder.currentRemote)
    }

    panic("GOD!")
}

func metadataTree(identifier string, object *git.TreeEntry) string {
    return "" // not yet implemented!
}

func metadataReference(identifier string, object *git.Reference) string {
    key := ""
    for key, _ = range builder.tables {
        break
    }
    table := key
    err := builder.UseFieldFromTable(identifier, table)
    if err != nil {
        panic(err)
    }
    switch identifier {
        case "name":
            return object.Shorthand()
        case "full_name" :
            return object.Name()
        case "hash" :
            target := object.Target()
            if target == nil {
                return "NULL"
            }
            return target.String()
        case "type":
            if object.IsBranch() {
                return REFERENCE_TYPE_BRANCH
            }

            if object.IsRemote() {
                return REFERENCE_TYPE_REMOTE
            }

            if object.IsTag() {
                return REFERENCE_TYPE_TAG
            }
    }

    panic(fmt.Sprintf("Field %s not implemented yet", identifier))
}

func metadataCommit(identifier string, object *git.Commit) string {
    key := ""
    for key, _ = range builder.tables {
        break
    }
    table := key
    err := builder.UseFieldFromTable(identifier, table)
    if err != nil {
        panic(err)
    }
    switch identifier {
        case "hash" :
            return object.Id().String()
        case "author":
            return object.Author().Name
        case "author_email":
            return object.Author().Email
        case "committer":
            return object.Committer().Name
        case "committer_email":
            return object.Committer().Email
        case "date":
            return object.Committer().When.Format(parser.Time_YMDHIS)
        case "full_message":
            return object.Message()
        case "message":
            // return first line of a commit message
            message := object.Message()
            r := []rune("\n")
            idx := strings.IndexRune(message, r[0])
            if idx != -1 {
                message = message[0:idx]
            }
            return message

    }

    panic(fmt.Sprintf("Field %s not implemented yet", identifier))
}

func metadataRemote(identifier string, object *git.Remote) string {
    key := ""
    for key, _ = range builder.tables {
        break
    }
    table := key
    err := builder.UseFieldFromTable(identifier, table)
    if err != nil {
        panic(err)
    }
    switch identifier {
       case "name":
            return object.Name()
       case "url":
            return object.Url()
       case "push_url":
            return object.PushUrl()
       case "owner":
            repo := object.Owner()
            r := &repo
            return r.Path()
    }

    panic(fmt.Sprintf("Field %s not implemented yet", identifier))
}

// =========================== Error

func (e *RuntimeError) Error() string{
    return e.message
}

func throwRuntimeError(message string, code uint8) (*RuntimeError) {
    e := new(RuntimeError)
    e.message = message
    e.code = code

    return e
}

// =================== GitBuilder

func GetGitBuilder(path *string) (*GitBuilder) {

    gb := new(GitBuilder)
    gb.tables = make(map[string]string)
    possibleTables := map[string][]string {
        "commits": {
            "hash",
            "date",
            "author",
            "author_email",
            "committer",
            "committer_email",
            "message",
            "full_message",
        },
        "trees": {
            "hash",
            "name",
            "id",
            "type",
            "filemode",
        },
        "refs": {
            "name",
            "full_name",
            "type",
            "hash",
        },
        "remotes": {
            "name",
            "url",
            "push_url",
            "owner",
        },
    }
    gb.possibleTables = possibleTables

    openRepository(path)

    gb.repo = repo

    return gb
}

func openRepository(path *string) {
    _repo, err := git.OpenRepository(*path)
    if err != nil {
        panic(err)
    }
    repo = _repo
}

func (g *GitBuilder) setCommit(object *git.Commit) {
    g.currentCommit = object
}

func (g *GitBuilder) setReference(object *git.Reference) {
    g.currentReference = object
}

func (g *GitBuilder) setRemote(object *git.Remote) {
    g.currentRemote = object
}

func (g *GitBuilder) WithTable(tableName string, alias string) error {
    err := g.isValidTable(tableName)
    if err != nil {
        return err
    }

    if g.possibleTables[tableName] == nil {
        return throwRuntimeError(fmt.Sprintf("Table '%s' not found", tableName), 0)
    }

    if alias == "" {
        alias = tableName
    }

    g.tables[alias] = tableName

    return nil
}

func (g *GitBuilder) isValidTable(tableName string) error {
    if g.possibleTables[tableName] == nil {
        return throwRuntimeError(fmt.Sprintf("Table '%s' not found", tableName), 0)
    }

    return nil
}

func (g *GitBuilder) UseFieldFromTable(field string, tableName string) error {
    if field == "*" {
        return nil
    }

    err := g.isValidTable(tableName)
    if err != nil {
        return err
    }

    table := g.possibleTables[tableName]
    for _, t := range table {
        if t == field {
            return nil
        }
    }

    return throwRuntimeError(fmt.Sprintf("Table '%s' has not field '%s'", tableName, field), 0)
}<|endoftext|>


<commit_before>package vm

import "github.com/joushou/gocnc/gcode"
import "math"
import "fmt"

// Retrieves position from top of stack
func (vm *Machine) curPos() Position {
	return vm.Positions[len(vm.Positions)-1]
}

// Appends a position to the stack
func (vm *Machine) move(newX, newY, newZ float64) {
	if math.IsNaN(newX) || math.IsNaN(newY) || math.IsNaN(newZ) {
		panic("Internal failure: Move attempted with NaN value")
	}
	pos := Position{vm.State, newX, newY, newZ}
	vm.Positions = append(vm.Positions, pos)
}

// Calculates the absolute position of the given statement, including optional I, J, K parameters
func (vm *Machine) calcPos(stmt gcode.Block) (newX, newY, newZ, newI, newJ, newK float64) {
	pos := vm.curPos()
	var err error

	if newX, err = stmt.GetWord('X'); err != nil {
		newX = pos.X
	} else {
		if vm.Imperial {
			newX *= 25.4
		}
		if !vm.AbsoluteMove {
			newX += pos.X
		}
	}

	if newY, err = stmt.GetWord('Y'); err != nil {
		newY = pos.Y
	} else {
		if vm.Imperial {
			newY *= 25.4
		}
		if !vm.AbsoluteMove {
			newY += pos.Y
		}
	}

	if newZ, err = stmt.GetWord('Z'); err != nil {
		newZ = pos.Z
	} else {
		if vm.Imperial {
			newZ *= 25.4
		}
		if !vm.AbsoluteMove {
			newZ += pos.Z
		}
	}

	newI = stmt.GetWordDefault('I', 0.0)
	newJ = stmt.GetWordDefault('J', 0.0)
	newK = stmt.GetWordDefault('K', 0.0)

	if vm.Imperial {
		newI *= 25.4
		newJ *= 25.4
		newK *= 25.4
	}

	if !vm.AbsoluteArc {
		newI += pos.X
		newJ += pos.Y
		newK += pos.Z
	}

	return newX, newY, newZ, newI, newJ, newK
}

// Calculates an approximate arc from the provided statement
func (vm *Machine) arc(endX, endY, endZ, endI, endJ, endK, P float64) {
	var (
		startPos                       Position = vm.curPos()
		s1, s2, s3, e1, e2, e3, c1, c2 float64
		add                            func(x, y, z float64)
		clockwise                      bool = (vm.State.MoveMode == MoveModeCWArc)
	)
	// Hacky Hacky
	P--

	oldState := vm.State.MoveMode
	vm.State.MoveMode = MoveModeLinear

	//  Flip coordinate system for working in other planes
	switch vm.MovePlane {
	case PlaneXY:
		s1, s2, s3, e1, e2, e3, c1, c2 = startPos.X, startPos.Y, startPos.Z, endX, endY, endZ, endI, endJ
		add = func(x, y, z float64) {
			vm.move(x, y, z)
		}
	case PlaneXZ:
		s1, s2, s3, e1, e2, e3, c1, c2 = startPos.Z, startPos.X, startPos.Y, endZ, endX, endY, endK, endI
		add = func(x, y, z float64) {
			vm.move(y, z, x)
		}
	case PlaneYZ:
		s1, s2, s3, e1, e2, e3, c1, c2 = startPos.Y, startPos.Z, startPos.X, endY, endZ, endX, endJ, endK
		add = func(x, y, z float64) {
			vm.move(z, x, y)
		}
	}

	radius1 := math.Sqrt(math.Pow(c1-s1, 2) + math.Pow(c2-s2, 2))
	radius2 := math.Sqrt(math.Pow(c1-e1, 2) + math.Pow(c2-e2, 2))
	if radius1 == 0 || radius2 == 0 {
		panic("Invalid arc statement")
	}

	deviation := math.Abs((radius2-radius1)/radius1) * 100
	rDiff := math.Abs(radius2 - radius1)

	if (rDiff > 0.005 && deviation > 0.1) || rDiff > 0.5 {
		panic(fmt.Sprintf("Radius deviation of %f percent and %f mm", deviation, rDiff))
	}

	theta1 := math.Atan2((s2 - c2), (s1 - c1))
	theta2 := math.Atan2((e2 - c2), (e1 - c1))

	angleDiff := theta2 - theta1
	if angleDiff < 0 && !clockwise {
		angleDiff += 2 * math.Pi
	} else if angleDiff > 0 && clockwise {
		angleDiff -= 2 * math.Pi
	}

	if clockwise {
		angleDiff -= P * 2 * math.Pi
	} else {
		angleDiff += P * 2 * math.Pi
	}

	steps := 1

	if vm.MaxArcDeviation < radius1 {
		steps = int(math.Ceil(math.Abs(angleDiff / (2 * math.Acos(1-vm.MaxArcDeviation/radius1)))))
	}

	// Enforce a minimum line length
	arcLen := math.Abs(angleDiff) * math.Sqrt(math.Pow(radius1, 2)+math.Pow((e3-s3)/angleDiff, 2))
	steps2 := int(arcLen / vm.MinArcLineLength)

	if steps > steps2 {
		steps = steps2
	}

	angle := 0.0

	if steps > 0 {
		for i := 0; i <= steps; i++ {
			angle = theta1 + angleDiff/float64(steps)*float64(i)
			a1, a2 := c1+radius1*math.Cos(angle), c2+radius1*math.Sin(angle)
			a3 := s3 + (e3-s3)/float64(steps)*float64(i)
			add(a1, a2, a3)
		}
	}

	add(e1, e2, e3)

	vm.State.MoveMode = oldState
}
<commit_msg>Cleanup<commit_after>package vm

import "github.com/joushou/gocnc/gcode"
import "math"
import "fmt"

// Retrieves position from top of stack
func (vm *Machine) curPos() Position {
	return vm.Positions[len(vm.Positions)-1]
}

// Appends a position to the stack
func (vm *Machine) move(x, y, z float64) {
	if math.IsNaN(x) || math.IsNaN(y) || math.IsNaN(z) {
		panic("Internal failure: Move attempted with NaN value")
	}
	pos := Position{vm.State, x, y, z}
	vm.Positions = append(vm.Positions, pos)
}

// Calculates the absolute position of the given statement, including optional I, J, K parameters
func (vm *Machine) calcPos(stmt gcode.Block) (newX, newY, newZ, newI, newJ, newK float64) {
	pos := vm.curPos()
	var err error

	if newX, err = stmt.GetWord('X'); err != nil {
		newX = pos.X
	} else {
		if vm.Imperial {
			newX *= 25.4
		}
		if !vm.AbsoluteMove {
			newX += pos.X
		}
	}

	if newY, err = stmt.GetWord('Y'); err != nil {
		newY = pos.Y
	} else {
		if vm.Imperial {
			newY *= 25.4
		}
		if !vm.AbsoluteMove {
			newY += pos.Y
		}
	}

	if newZ, err = stmt.GetWord('Z'); err != nil {
		newZ = pos.Z
	} else {
		if vm.Imperial {
			newZ *= 25.4
		}
		if !vm.AbsoluteMove {
			newZ += pos.Z
		}
	}

	newI = stmt.GetWordDefault('I', 0.0)
	newJ = stmt.GetWordDefault('J', 0.0)
	newK = stmt.GetWordDefault('K', 0.0)

	if vm.Imperial {
		newI *= 25.4
		newJ *= 25.4
		newK *= 25.4
	}

	if !vm.AbsoluteArc {
		newI += pos.X
		newJ += pos.Y
		newK += pos.Z
	}

	return newX, newY, newZ, newI, newJ, newK
}

// Calculates an approximate arc from the provided statement
func (vm *Machine) arc(x, y, z, i, j, k, rotations float64) {
	var (
		sp                             Position = vm.curPos()
		s1, s2, s3, e1, e2, e3, c1, c2 float64
		add                            func(x, y, z float64)
		clockwise                      bool = (vm.State.MoveMode == MoveModeCWArc)
	)

	if math.IsNaN(x) || math.IsNaN(y) || math.IsNaN(z) ||
		math.IsNaN(i) || math.IsNaN(j) || math.IsNaN(k) {
		panic("Internal failure: Arc attempted with NaN value")
	}

	if rotations < 1 {
		panic("Arc rotations < 1")
	}

	// Ensure that we work on linear moves
	oldState := vm.State.MoveMode
	vm.State.MoveMode = MoveModeLinear
	defer func() {
		vm.State.MoveMode = oldState
	}()

	//  Flip coordinate system for working in other planes
	switch vm.MovePlane {
	case PlaneXY:
		s1, s2, s3, e1, e2, e3, c1, c2 = sp.X, sp.Y, sp.Z, x, y, z, i, j
		add = func(x, y, z float64) {
			vm.move(x, y, z)
		}
	case PlaneXZ:
		s1, s2, s3, e1, e2, e3, c1, c2 = sp.Z, sp.X, sp.Y, z, x, y, k, i
		add = func(x, y, z float64) {
			vm.move(y, z, x)
		}
	case PlaneYZ:
		s1, s2, s3, e1, e2, e3, c1, c2 = sp.Y, sp.Z, sp.X, y, z, x, j, k
		add = func(x, y, z float64) {
			vm.move(z, x, y)
		}
	}

	// Perform arc verification
	radius1 := math.Sqrt(math.Pow(c1-s1, 2) + math.Pow(c2-s2, 2))
	radius2 := math.Sqrt(math.Pow(c1-e1, 2) + math.Pow(c2-e2, 2))
	if radius1 == 0 || radius2 == 0 {
		panic("Invalid arc statement")
	}

	deviation := math.Abs((radius2-radius1)/radius1) * 100
	rDiff := math.Abs(radius2 - radius1)

	if (rDiff > 0.005 && deviation > 0.1) || rDiff > 0.5 {
		panic(fmt.Sprintf("Radius deviation of %f percent and %f mm", deviation, rDiff))
	}

	// Some preparatory math
	theta1 := math.Atan2((s2 - c2), (s1 - c1))
	theta2 := math.Atan2((e2 - c2), (e1 - c1))

	angleDiff := theta2 - theta1
	if angleDiff < 0 && !clockwise {
		angleDiff += 2 * math.Pi
	} else if angleDiff > 0 && clockwise {
		angleDiff -= 2 * math.Pi
	}

	// Rotations are provided as "up to circle count", but we need it as "additional circle count"
	rotations--
	if clockwise {
		angleDiff -= rotations * 2 * math.Pi
	} else {
		angleDiff += rotations * 2 * math.Pi
	}

	steps := 1

	// Enforce a maximum arc deviation
	if vm.MaxArcDeviation < radius1 {
		steps = int(math.Ceil(math.Abs(angleDiff / (2 * math.Acos(1-vm.MaxArcDeviation/radius1)))))
	}

	// Enforce a minimum line length
	arcLen := math.Abs(angleDiff) * math.Sqrt(math.Pow(radius1, 2)+math.Pow((e3-s3)/angleDiff, 2))
	steps2 := int(arcLen / vm.MinArcLineLength)

	if steps > steps2 {
		steps = steps2
	}

	angle := 0.0

	// Execute arc approximation
	if steps > 0 {
		for i := 0; i <= steps; i++ {
			angle = theta1 + angleDiff/float64(steps)*float64(i)
			a1, a2 := c1+radius1*math.Cos(angle), c2+radius1*math.Sin(angle)
			a3 := s3 + (e3-s3)/float64(steps)*float64(i)
			add(a1, a2, a3)
		}
	}

	add(e1, e2, e3)
}
<|endoftext|>


<commit_before>package command

import (
	"flag"
	"fmt"
	"net/http"
	"strings"

	"github.com/TailorDev/msw/issue"
	"github.com/mitchellh/cli"
)

// ValidateCommand is a Command that validates a YAML file.
type ValidateCommand struct {
	UI cli.Ui
}

// Run runs the code of the comand.
func (c *ValidateCommand) Run(args []string) int {
	cmdFlags := flag.NewFlagSet("validate", flag.ContinueOnError)
	cmdFlags.Usage = func() { c.UI.Output(c.Help()) }
	if err := cmdFlags.Parse(args); err != nil {
		return 1
	}

	args = cmdFlags.Args()
	if len(args) != 1 {
		cmdFlags.Usage()
		return 1
	}

	i, err := issue.Parse(args[0])
	if err != nil {
		c.UI.Error(fmt.Sprintf("%s", err))
		return 1
	}

	if i.WelcomeText == "" {
		c.UI.Output("Welcome text is empty")
	}

	done := make(chan bool)
	wait := 0
	nbLinks := 0
	for _, category := range i.Categories {
		if len(category.Links) == 0 {
			c.UI.Output(fmt.Sprintf("No link found for category '%s'", category.Title))
			continue
		}
		nbLinks = nbLinks + len(category.Links)

		for idx, link := range category.Links {
			if link.Name == "" {
				c.UI.Output(fmt.Sprintf(
					"No name given for link #%d in category '%s'",
					idx+1,
					category.Title,
				))
			}
			if link.URL == "" {
				c.UI.Output(fmt.Sprintf(
					"No URL given for link #%d in category '%s'",
					idx+1,
					category.Title,
				))
			} else {
				wait++
				go testLinkURL(link.URL, c.UI, done)
			}
			if link.Abstract == "" {
				c.UI.Output(fmt.Sprintf(
					"No abstract given for link #%d in category '%s'",
					idx+1,
					category.Title,
				))
			}
		}
	}

	for i := 0; i < wait; i++ {
		<-done
	}

	if nbLinks > issue.MaxLinks {
		c.UI.Output(fmt.Sprintf("An issue should not have more than %d links, found: %d", issue.MaxLinks, nbLinks))
	}

	c.UI.Output("Everything looks good 👍")

	return 0
}

// Help returns the description of the command.
func (*ValidateCommand) Help() string {
	helpText := `
Usage: msw validate FILENAME

  This command checks whether a filename contains a valid issue.

`
	return strings.TrimSpace(helpText)
}

// Synopsis returns the short description of the command.
func (*ValidateCommand) Synopsis() string {
	return "check that an issue is valid"
}

func testLinkURL(url string, ui cli.Ui, done chan bool) {
	resp, err := http.Head(url)
	if err != nil {
		ui.Error(fmt.Sprintf("Error while trying to perform a HEAD request: %s", err))
	} else {
		defer resp.Body.Close()

		if resp.StatusCode != 200 {
			ui.Output(fmt.Sprintf("Could not reach URL = '%s'", url))
		}
	}

	done <- true
}
<commit_msg>Change channel to pass error messages<commit_after>package command

import (
	"flag"
	"fmt"
	"net/http"
	"strings"

	"github.com/TailorDev/msw/issue"
	"github.com/mitchellh/cli"
)

// ValidateCommand is a Command that validates a YAML file.
type ValidateCommand struct {
	UI cli.Ui
}

// Run runs the code of the comand.
func (c *ValidateCommand) Run(args []string) int {
	cmdFlags := flag.NewFlagSet("validate", flag.ContinueOnError)
	cmdFlags.Usage = func() { c.UI.Output(c.Help()) }
	if err := cmdFlags.Parse(args); err != nil {
		return 1
	}

	args = cmdFlags.Args()
	if len(args) != 1 {
		cmdFlags.Usage()
		return 1
	}

	i, err := issue.Parse(args[0])
	if err != nil {
		c.UI.Error(fmt.Sprintf("%s", err))
		return 1
	}

	errors := []string{}

	if i.WelcomeText == "" {
		errors = append(errors, "Welcome text is empty")
	}

	done := make(chan string)
	wait := 0
	nbLinks := 0
	for _, category := range i.Categories {
		if len(category.Links) == 0 {
			errors = append(errors, fmt.Sprintf("No link found for category '%s'", category.Title))
			continue
		}
		nbLinks = nbLinks + len(category.Links)

		for idx, link := range category.Links {
			if link.Name == "" {
				errors = append(errors, fmt.Sprintf(
					"No name given for link #%d in category '%s'",
					idx+1,
					category.Title,
				))
			}
			if link.URL == "" {
				errors = append(errors, fmt.Sprintf(
					"No URL given for link #%d in category '%s'",
					idx+1,
					category.Title,
				))
			} else {
				wait++
				go testLinkURL(link.URL, done)
			}
			if link.Abstract == "" {
				errors = append(errors, fmt.Sprintf(
					"No abstract given for link #%d in category '%s'",
					idx+1,
					category.Title,
				))
			}
		}
	}

	for i := 0; i < wait; i++ {
		if e := <-done; e != "" {
			errors = append(errors, e)
		}
	}

	if nbLinks > issue.MaxLinks {
		errors = append(errors, fmt.Sprintf(
			"An issue should not have more than %d links, found: %d",
			issue.MaxLinks,
			nbLinks,
		))
	}

	if len(errors) == 0 {
		c.UI.Output("Everything looks good 👍")
		return 1
	}

	for _, e := range errors {
		c.UI.Output(e)
	}

	return 0
}

// Help returns the description of the command.
func (*ValidateCommand) Help() string {
	helpText := `
Usage: msw validate FILENAME

  This command checks whether a filename contains a valid issue.

`
	return strings.TrimSpace(helpText)
}

// Synopsis returns the short description of the command.
func (*ValidateCommand) Synopsis() string {
	return "check that an issue is valid"
}

func testLinkURL(url string, done chan string) {
	resp, err := http.Head(url)
	if err != nil {
		done <- fmt.Sprintf("Error while trying to perform a HEAD request: %s", err)
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		done <- fmt.Sprintf("Could not reach URL = '%s'", url)
		return
	}

	done <- ""
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Pagoda Box Inc
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not distributed with this file, You can obtain one
// at http://mozilla.org/MPL/2.0/.
//

package commands

//
import (
	"fmt"
	"net/url"
	"os"

	"github.com/spf13/cobra"

	"github.com/pagodabox/nanobox-cli/config"
	"github.com/pagodabox/nanobox-cli/util"
	// "github.com/pagodabox/nanobox-golang-stylish"
)

//
var consoleCmd = &cobra.Command{
	Use:   "console",
	Short: "Opens an interactive terminal from inside your app on the nanobox VM",
	Long: `
Description:
  Opens an interactive terminal from inside your app on the nanobox VM`,

	PreRun: vmIsRunning,
	Run:    nanoConsole,
}

// nanoConsole
func nanoConsole(ccmd *cobra.Command, args []string) {
	fmt.Printf(`
+> Opening nanobox console:

                                 **
                              ********
                           ***************
                        *********************
                          *****************
                        ::    *********    ::
                           ::    ***    ::
                         ++   :::   :::   ++
                            ++   :::   ++
                               ++   ++
                                  +

 ------------------------------------------------------------------
 + You are in a virtual machine (vm)
 + Your local source code has been mounted into the vm, and changes
   in either the vm or local will be mirrored.
 + If you run a server, access it at >> %s
 ------------------------------------------------------------------
`, config.Nanofile.Domain)

	//
	v := url.Values{}

	//
	switch {

	// if no args are passed run console as normal
	case len(args) == 0:
		break

		// if 1 args is passed it's assumed to be a container to console directly into
		// since console doesn't take any additional arguments (like exec)
	case len(args) == 1:
		v.Add("container", args[0])

		// if more than 1 args is passed fail and exit...
	case len(args) > 1:
		fmt.Printf("Expecting 0 or 1 arguments. Exiting...\n")
		os.Exit(1)
	}

	// add a check here to regex the fTunnel to make sure the format makes sense

	docker := &util.Docker{Params: v.Encode()}
	docker.Run()
}
<commit_msg>adding nanobox label to the console welcome text<commit_after>// Copyright (c) 2015 Pagoda Box Inc
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not distributed with this file, You can obtain one
// at http://mozilla.org/MPL/2.0/.
//

package commands

//
import (
	"fmt"
	"net/url"
	"os"

	"github.com/spf13/cobra"

	"github.com/pagodabox/nanobox-cli/config"
	"github.com/pagodabox/nanobox-cli/util"
	// "github.com/pagodabox/nanobox-golang-stylish"
)

//
var consoleCmd = &cobra.Command{
	Use:   "console",
	Short: "Opens an interactive terminal from inside your app on the nanobox VM",
	Long: `
Description:
  Opens an interactive terminal from inside your app on the nanobox VM`,

	PreRun: vmIsRunning,
	Run:    nanoConsole,
}

// nanoConsole
func nanoConsole(ccmd *cobra.Command, args []string) {
	fmt.Printf(`
+> Opening nanobox console:

                                 **
                              ********
                           ***************
                        *********************
                          *****************
                        ::    *********    ::
                           ::    ***    ::
                         ++   :::   :::   ++
                            ++   :::   ++
                               ++   ++
                                  +

                  _  _ ____ _  _ ____ ___  ____ _  _
                  |\ | |__| |\ | |  | |__) |  |  \/
                  | \| |  | | \| |__| |__) |__| _/\_

 ------------------------------------------------------------------
 + You are in a virtual machine (vm)
 + Your local source code has been mounted into the vm, and changes
   in either the vm or local will be mirrored.
 + If you run a server, access it at >> %s
 ------------------------------------------------------------------

`, config.Nanofile.Domain)

	//
	v := url.Values{}

	//
	switch {

	// if no args are passed run console as normal
	case len(args) == 0:
		break

		// if 1 args is passed it's assumed to be a container to console directly into
		// since console doesn't take any additional arguments (like exec)
	case len(args) == 1:
		v.Add("container", args[0])

		// if more than 1 args is passed fail and exit...
	case len(args) > 1:
		fmt.Printf("Expecting 0 or 1 arguments. Exiting...\n")
		os.Exit(1)
	}

	// add a check here to regex the fTunnel to make sure the format makes sense

	docker := &util.Docker{Params: v.Encode()}
	docker.Run()
}
<|endoftext|>


<commit_before>package waku

import (
	"errors"
	"fmt"
	"io"
	"math"
	"reflect"
	"strconv"
	"strings"

	"github.com/ethereum/go-ethereum/rlp"
)

var defaultMinPoW = math.Float64bits(0.001)

type statusOptionKey int64

// statusOptions defines additional information shared between peers
// during the handshake.
// There might be more options provided then fields in statusOptions
// and they should be ignored during deserialization to stay forward compatible.
// In the case of RLP, options should be serialized to an array of tuples
// where the first item is a field name and the second is a RLP-serialized value.
type statusOptions struct {
	PoWRequirement       *uint64     `rlp:"key=0"` // RLP does not support float64 natively
	BloomFilter          []byte      `rlp:"key=1"`
	LightNodeEnabled     *bool       `rlp:"key=2"`
	ConfirmationsEnabled *bool       `rlp:"key=3"`
	RateLimits           *RateLimits `rlp:"key=4"`
	TopicInterest        []TopicType `rlp:"key=5"`

	idxFieldKey map[int]statusOptionKey
	keyFieldIdx map[statusOptionKey]int
}

// WithDefaults adds the default values for a given peer.
// This are not the host default values, but the default values that ought to
// be used when receiving from an update from a peer.
func (o statusOptions) WithDefaults() statusOptions {
	if o.PoWRequirement == nil {
		o.PoWRequirement = &defaultMinPoW
	}

	if o.LightNodeEnabled == nil {
		lightNodeEnabled := false
		o.LightNodeEnabled = &lightNodeEnabled
	}

	if o.ConfirmationsEnabled == nil {
		confirmationsEnabled := false
		o.ConfirmationsEnabled = &confirmationsEnabled
	}

	if o.RateLimits == nil {
		o.RateLimits = &RateLimits{}
	}

	if o.BloomFilter == nil {
		o.BloomFilter = MakeFullNodeBloom()
	}

	return o
}

//var idxFieldKey = make(map[int]statusOptionKey)
//var keyFieldIdx = map[statusOptionKey]int{}

func (o *statusOptions) parseStatusOptionKeys() error {
	kfi := make(map[statusOptionKey]int)
	ifk := make(map[int]statusOptionKey)

	v := reflect.ValueOf(o)

	for i := 0; i < v.NumField(); i++ {
		// skip unexported fields
		if !v.Field(i).CanInterface() {
			continue
		}
		rlpTag := v.Type().Field(i).Tag.Get("rlp")
		// skip fields without rlp field tag
		if rlpTag == "" {
			continue
		}

		keys := strings.Split(rlpTag, "=")
		// skip rlp tags that cannot be split by "="
		// TODO Do we want to throw an error here if the length is not exactly 2?
		if len(keys) < 2 {
			continue
		}

		// parse keys[1] as an int
		rkey, err := strconv.ParseInt(keys[1], 10, 64)
		if err != nil {
			return err
		}

		// typecast rkey to be of statusOptionKey type
		key := statusOptionKey(rkey)
		kfi[key] = i
		ifk[i] = key
	}

	o.keyFieldIdx = kfi
	o.idxFieldKey = ifk

	return nil
}

func (o statusOptions) PoWRequirementF() *float64 {
	if o.PoWRequirement == nil {
		return nil
	}
	result := math.Float64frombits(*o.PoWRequirement)
	return &result
}

func (o *statusOptions) SetPoWRequirementFromF(val float64) {
	requirement := math.Float64bits(val)
	o.PoWRequirement = &requirement
}

func (o statusOptions) EncodeRLP(w io.Writer) error {
	v := reflect.ValueOf(o)
	var optionsList []interface{}
	for i := 0; i < v.NumField(); i++ {
		field := v.Field(i)
		if !field.IsNil() {
			value := field.Interface()
			key, ok := o.idxFieldKey[i]
			if !ok {
				continue
			}
			if value != nil {
				optionsList = append(optionsList, []interface{}{key, value})
			}
		}
	}
	return rlp.Encode(w, optionsList)
}

func (o *statusOptions) DecodeRLP(s *rlp.Stream) error {
	_, err := s.List()
	if err != nil {
		return fmt.Errorf("expected an outer list: %v", err)
	}

	o.parseStatusOptionKeys()

	v := reflect.ValueOf(o)

loop:
	for {
		_, err := s.List()
		switch err {
		case nil:
			// continue to decode a key
		case rlp.EOL:
			break loop
		default:
			return fmt.Errorf("expected an inner list: %v", err)
		}
		var key statusOptionKey
		if err := s.Decode(&key); err != nil {
			return fmt.Errorf("invalid key: %v", err)
		}
		// Skip processing if a key does not exist.
		// It might happen when there is a new peer
		// which supports a new option with
		// a higher index.
		idx, ok := o.keyFieldIdx[key]
		if !ok {
			// Read the rest of the list items and dump them.
			_, err := s.Raw()
			if err != nil {
				return fmt.Errorf("failed to read the value of key %d: %v", key, err)
			}
			continue
		}
		if err := s.Decode(v.Elem().Field(idx).Addr().Interface()); err != nil {
			return fmt.Errorf("failed to decode an option %d: %v", key, err)
		}
		if err := s.ListEnd(); err != nil {
			return err
		}
	}

	return s.ListEnd()
}

func (o statusOptions) Validate() error {
	if len(o.TopicInterest) > 1000 {
		return errors.New("topic interest is limited by 1000 items")
	}
	return nil
}
<commit_msg>Added handling of parseStatuOptionKeys() error<commit_after>package waku

import (
	"errors"
	"fmt"
	"io"
	"math"
	"reflect"
	"strconv"
	"strings"

	"github.com/ethereum/go-ethereum/rlp"
)

var defaultMinPoW = math.Float64bits(0.001)

type statusOptionKey int64

// statusOptions defines additional information shared between peers
// during the handshake.
// There might be more options provided then fields in statusOptions
// and they should be ignored during deserialization to stay forward compatible.
// In the case of RLP, options should be serialized to an array of tuples
// where the first item is a field name and the second is a RLP-serialized value.
type statusOptions struct {
	PoWRequirement       *uint64     `rlp:"key=0"` // RLP does not support float64 natively
	BloomFilter          []byte      `rlp:"key=1"`
	LightNodeEnabled     *bool       `rlp:"key=2"`
	ConfirmationsEnabled *bool       `rlp:"key=3"`
	RateLimits           *RateLimits `rlp:"key=4"`
	TopicInterest        []TopicType `rlp:"key=5"`

	idxFieldKey map[int]statusOptionKey
	keyFieldIdx map[statusOptionKey]int
}

// WithDefaults adds the default values for a given peer.
// This are not the host default values, but the default values that ought to
// be used when receiving from an update from a peer.
func (o statusOptions) WithDefaults() statusOptions {
	if o.PoWRequirement == nil {
		o.PoWRequirement = &defaultMinPoW
	}

	if o.LightNodeEnabled == nil {
		lightNodeEnabled := false
		o.LightNodeEnabled = &lightNodeEnabled
	}

	if o.ConfirmationsEnabled == nil {
		confirmationsEnabled := false
		o.ConfirmationsEnabled = &confirmationsEnabled
	}

	if o.RateLimits == nil {
		o.RateLimits = &RateLimits{}
	}

	if o.BloomFilter == nil {
		o.BloomFilter = MakeFullNodeBloom()
	}

	return o
}

//var idxFieldKey = make(map[int]statusOptionKey)
//var keyFieldIdx = map[statusOptionKey]int{}

func (o *statusOptions) parseStatusOptionKeys() error {
	kfi := make(map[statusOptionKey]int)
	ifk := make(map[int]statusOptionKey)

	v := reflect.ValueOf(o)

	for i := 0; i < v.NumField(); i++ {
		// skip unexported fields
		if !v.Field(i).CanInterface() {
			continue
		}
		rlpTag := v.Type().Field(i).Tag.Get("rlp")
		// skip fields without rlp field tag
		if rlpTag == "" {
			continue
		}

		keys := strings.Split(rlpTag, "=")
		// skip rlp tags that cannot be split by "="
		// TODO Do we want to throw an error here if the length is not exactly 2?
		if len(keys) < 2 {
			continue
		}

		// parse keys[1] as an int
		rkey, err := strconv.ParseInt(keys[1], 10, 64)
		if err != nil {
			return err
		}

		// typecast rkey to be of statusOptionKey type
		key := statusOptionKey(rkey)
		kfi[key] = i
		ifk[i] = key
	}

	o.keyFieldIdx = kfi
	o.idxFieldKey = ifk

	return nil
}

func (o statusOptions) PoWRequirementF() *float64 {
	if o.PoWRequirement == nil {
		return nil
	}
	result := math.Float64frombits(*o.PoWRequirement)
	return &result
}

func (o *statusOptions) SetPoWRequirementFromF(val float64) {
	requirement := math.Float64bits(val)
	o.PoWRequirement = &requirement
}

func (o statusOptions) EncodeRLP(w io.Writer) error {
	v := reflect.ValueOf(o)
	var optionsList []interface{}
	for i := 0; i < v.NumField(); i++ {
		field := v.Field(i)
		if !field.IsNil() {
			value := field.Interface()
			key, ok := o.idxFieldKey[i]
			if !ok {
				continue
			}
			if value != nil {
				optionsList = append(optionsList, []interface{}{key, value})
			}
		}
	}
	return rlp.Encode(w, optionsList)
}

func (o *statusOptions) DecodeRLP(s *rlp.Stream) error {
	_, err := s.List()
	if err != nil {
		return fmt.Errorf("expected an outer list: %v", err)
	}

	err = o.parseStatusOptionKeys()
	if err != nil {
		return err
	}

	v := reflect.ValueOf(o)

loop:
	for {
		_, err := s.List()
		switch err {
		case nil:
			// continue to decode a key
		case rlp.EOL:
			break loop
		default:
			return fmt.Errorf("expected an inner list: %v", err)
		}
		var key statusOptionKey
		if err := s.Decode(&key); err != nil {
			return fmt.Errorf("invalid key: %v", err)
		}
		// Skip processing if a key does not exist.
		// It might happen when there is a new peer
		// which supports a new option with
		// a higher index.
		idx, ok := o.keyFieldIdx[key]
		if !ok {
			// Read the rest of the list items and dump them.
			_, err := s.Raw()
			if err != nil {
				return fmt.Errorf("failed to read the value of key %d: %v", key, err)
			}
			continue
		}
		if err := s.Decode(v.Elem().Field(idx).Addr().Interface()); err != nil {
			return fmt.Errorf("failed to decode an option %d: %v", key, err)
		}
		if err := s.ListEnd(); err != nil {
			return err
		}
	}

	return s.ListEnd()
}

func (o statusOptions) Validate() error {
	if len(o.TopicInterest) > 1000 {
		return errors.New("topic interest is limited by 1000 items")
	}
	return nil
}
<|endoftext|>


<commit_before>package commands

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/url"
	"regexp"
	"strings"

	"github.com/daidokoro/qaz/bucket"
	"github.com/daidokoro/qaz/utils"
)

// TODO: Come up with a better way to do this
// fetchContent - checks the source type, url/s3/file and calls the corresponding function
func fetchContent(source string) (string, error) {

	src, err := url.Parse(source)
	if err != nil {
		return "", err
	}

	switch src.Scheme {
	case "http", "https":
		log.Debug(fmt.Sprintln("Source Type: [http] Detected, Fetching Source: ", source))
		resp, err := utils.Get(source)
		if err != nil {
			return "", err
		}
		return resp, nil
	case "s3":
		log.Debug(fmt.Sprintln("Source Type: [s3] Detected, Fetching Source: ", source))
		sess, err := manager.GetSess(run.profile)
		utils.HandleError(err)

		resp, err := bucket.S3Read(source, sess)
		if err != nil {
			return "", err
		}
		return resp, nil
	case "lambda":
		log.Debug(fmt.Sprintln("Source Type: [lambda] Detected, Fetching Source: ", source))
		lambdaSrc := strings.Split(strings.Replace(source, "lambda:", "", -1), "@")

		var raw interface{}
		if err := json.Unmarshal([]byte(lambdaSrc[0]), &raw); err != nil {
			return "", err
		}

		event, err := json.Marshal(raw)
		if err != nil {
			return "", err
		}

		reg, err := regexp.Compile("[^A-Za-z0-9_-]+")
		if err != nil {
			return "", err
		}

		lambdaName := reg.ReplaceAllString(lambdaSrc[1], "")

		f := awsLambda{
			name:    lambdaName,
			payload: event,
		}

		// using default profile
		sess := manager.sessions[run.profile]
		if err := f.Invoke(sess); err != nil {
			return "", err
		}

		return f.response, nil

	default:
		if gitrepo.URL != "" {
			log.Debug(fmt.Sprintln("Source Type: [git-repo file] Detected, Fetching Source: ", source))
			out, ok := gitrepo.Files[source]
			if ok {
				return out, nil
			} else if !ok {
				log.Warn(fmt.Sprintf("config [%s] not found in git repo - checking local file system", source))
			}

		}

		log.Debug(fmt.Sprintln("Source Type: [file] Detected, Fetching Source: ", source))
		b, err := ioutil.ReadFile(source)
		if err != nil {
			return "", err
		}
		return string(b), nil
	}
}
<commit_msg>added log.debug to print config read<commit_after>package commands

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/url"
	"regexp"
	"strings"

	"github.com/daidokoro/qaz/bucket"
	"github.com/daidokoro/qaz/utils"
)

// TODO: Come up with a better way to do this
// fetchContent - checks the source type, url/s3/file and calls the corresponding function
func fetchContent(source string) (string, error) {

	src, err := url.Parse(source)
	if err != nil {
		return "", err
	}

	switch src.Scheme {
	case "http", "https":
		log.Debug(fmt.Sprintln("Source Type: [http] Detected, Fetching Source: ", source))
		resp, err := utils.Get(source)
		if err != nil {
			return "", err
		}
		return resp, nil
	case "s3":
		log.Debug(fmt.Sprintln("Source Type: [s3] Detected, Fetching Source: ", source))
		sess, err := manager.GetSess(run.profile)
		utils.HandleError(err)

		resp, err := bucket.S3Read(source, sess)
		if err != nil {
			return "", err
		}
		return resp, nil
	case "lambda":
		log.Debug(fmt.Sprintln("Source Type: [lambda] Detected, Fetching Source: ", source))
		lambdaSrc := strings.Split(strings.Replace(source, "lambda:", "", -1), "@")

		var raw interface{}
		if err := json.Unmarshal([]byte(lambdaSrc[0]), &raw); err != nil {
			return "", err
		}

		event, err := json.Marshal(raw)
		if err != nil {
			return "", err
		}

		reg, err := regexp.Compile("[^A-Za-z0-9_-]+")
		if err != nil {
			return "", err
		}

		lambdaName := reg.ReplaceAllString(lambdaSrc[1], "")

		f := awsLambda{
			name:    lambdaName,
			payload: event,
		}

		// using default profile
		sess := manager.sessions[run.profile]
		if err := f.Invoke(sess); err != nil {
			return "", err
		}

		return f.response, nil

	default:
		if gitrepo.URL != "" {
			log.Debug(fmt.Sprintln("Source Type: [git-repo file] Detected, Fetching Source: ", source))
			out, ok := gitrepo.Files[source]
			if ok {
				return out, nil
			} else if !ok {
				log.Warn(fmt.Sprintf("config [%s] not found in git repo - checking local file system", source))
			}

		}

		log.Debug(fmt.Sprintln("Source Type: [file] Detected, Fetching Source: ", source))
		b, err := ioutil.ReadFile(source)
		if err != nil {
			return "", err
		}

		log.Debug(fmt.Sprintln("config file read:", string(b)))
		return string(b), nil
	}
}
<|endoftext|>


<commit_before>package commands

import (
	"fmt"
	"github.com/PagerDuty/godspeed"
	"github.com/zorkian/go-datadog-api"
	"os"
)

// StatsdIn sends metrics to Dogstatsd on an `kvexpress in` operation.
func StatsdIn(key string, dataLength int, data string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' stats='in'", key), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, "complete")
		statsd.Incr("kvexpress.in", tags)
		statsd.Gauge("kvexpress.bytes", float64(dataLength), tags)
		statsd.Gauge("kvexpress.lines", float64(LineCount(data)), tags)
	}
}

// StatsdOut sends metrics to Dogstatsd on an `kvexpress out` operation.
func StatsdOut(key string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' stats='out'", key), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, "complete")
		statsd.Incr("kvexpress.out", tags)
	}
}

// StatsdLocked sends metrics to Dogstatsd on an `kvexpress out` operation
// that is blocked by a locked file.
func StatsdLocked(file string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' file='%s' stats='locked'", file), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(file, "complete")
		statsd.Incr("kvexpress.locked", tags)
	}
}

// StatsdLock sends metrics to Dogstatsd on an `kvexpress lock` operation.
func StatsdLock(key string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' stats='lock'", key), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, "complete")
		statsd.Incr("kvexpress.lock", tags)
	}
}

// StatsdUnlock sends metrics to Dogstatsd on an `kvexpress unlock` operation.
func StatsdUnlock(key string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' stats='unlock'", key), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, "complete")
		statsd.Incr("kvexpress.unlock", tags)
	}
}

// StatsdRaw sends metrics to Dogstatsd on an `kvexpress raw` operation.
func StatsdRaw(key string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' stats='raw'", key), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, "complete")
		statsd.Incr("kvexpress.raw", tags)
	}
}

// StatsdRunTime sends metrics to Dogstatsd on various operations.
func StatsdRunTime(key string, location string, msec int64) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' location='%s' msec='%d'", key, location, msec), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, location)
		locationTag := fmt.Sprintf("location:%s", location)
		tags = append(tags, locationTag)
		statsd.Gauge("kvexpress.time", float64(msec), tags)
	}
}

// StatsdPanic sends metrics to Dogstatsd when something really bad happens.
// It also stops the execution of kvexpress.
func StatsdPanic(key, location string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' location='%s' stats='panic'", key, location), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, location)
		statsd.Incr("kvexpress.panic", tags)
	}
	// If we're going to panic, we might as well stop right here.
	// Means we can't connect to Consul, download a URL or
	// write and/or chown files.
	os.Exit(0)
}

// DDAPIConnect connects to the Datadog API and returns a client object.
func DDAPIConnect(api, app string) *datadog.Client {
	client := datadog.NewClient(api, app)
	return client
}

// makeTags creates some standard tags for use with Dogstatsd and the Datadog API.
func makeTags(key, location string) []string {
	tags := make([]string, 4)
	keyTag := fmt.Sprintf("key:%s", key)
	hostname, _ := os.Hostname()
	hostTag := fmt.Sprintf("host:%s", hostname)
	directionTag := fmt.Sprintf("direction:%s", Direction)
	locationTag := fmt.Sprintf("location:%s", location)
	tags = append(tags, keyTag)
	tags = append(tags, hostTag)
	tags = append(tags, directionTag)
	tags = append(tags, locationTag)
	return tags
}

// TODO: These three functions are ripe for refactoring to be more Golang like.

// DDStopEvent sends a Datadog event to the API when there's a stop key present.
func DDStopEvent(dd *datadog.Client, key, value string) {
	Log(fmt.Sprintf("datadog='true' DDStopEvent='true' key='%s'", key), "debug")
	tags := makeTags(key, "stop_key_present")
	tags = append(tags, "kvexpress:stop")
	title := fmt.Sprintf("Stop key is present: %s. Stopping.", key)
	event := datadog.Event{Title: title, Text: value, AlertType: "error", Tags: tags}
	post, _ := dd.PostEvent(&event)
	if post != nil {

	}
}

// DDSaveDataEvent sends a Datadog event to the API when we have updated a Consul key.
func DDSaveDataEvent(dd *datadog.Client, key, value string) {
	Log(fmt.Sprintf("datadog='true' DDSaveDataEvent='true' key='%s'", key), "debug")
	tags := makeTags(key, "complete")
	tags = append(tags, "kvexpress:success")
	title := fmt.Sprintf("Updated: %s", key)
	event := datadog.Event{Title: title, Text: value, AlertType: "info", Tags: tags}
	post, _ := dd.PostEvent(&event)
	if post != nil {

	}
}

// DDCopyDataEvent sends a Datadog event to the API when we have used `kvexpress copy`
// to copy a Consul key.
func DDCopyDataEvent(dd *datadog.Client, keyFrom, keyTo string) {
	Log(fmt.Sprintf("datadog='true' DDCopyDataEvent='true' keyFrom='%s' keyTo='%s'", keyFrom, keyTo), "debug")
	tags := makeTags(keyTo, "complete")
	tags = append(tags, "kvexpress:success")
	tags = append(tags, fmt.Sprintf("keyFrom:%s", keyFrom))
	title := fmt.Sprintf("Copy: %s to %s", keyFrom, keyTo)
	event := datadog.Event{Title: title, Text: title, AlertType: "info", Tags: tags}
	post, _ := dd.PostEvent(&event)
	if post != nil {

	}
}

// DDSaveStopEvent sends a Datadog event when we have added a stop key to Consul.
func DDSaveStopEvent(dd *datadog.Client, key, value string) {
	Log(fmt.Sprintf("datadog='true' DDSaveStopEvent='true' key='%s'", key), "debug")
	tags := makeTags(key, "stop_key_save")
	tags = append(tags, "kvexpress:stop_set")
	title := fmt.Sprintf("Set Stop Key: %s", key)
	event := datadog.Event{Title: title, Text: value, AlertType: "warning", Tags: tags}
	post, _ := dd.PostEvent(&event)
	if post != nil {

	}
}
<commit_msg>Speeling.<commit_after>package commands

import (
	"fmt"
	"github.com/PagerDuty/godspeed"
	"github.com/zorkian/go-datadog-api"
	"os"
)

// StatsdIn sends metrics to Dogstatsd on a `kvexpress in` operation.
func StatsdIn(key string, dataLength int, data string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' stats='in'", key), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, "complete")
		statsd.Incr("kvexpress.in", tags)
		statsd.Gauge("kvexpress.bytes", float64(dataLength), tags)
		statsd.Gauge("kvexpress.lines", float64(LineCount(data)), tags)
	}
}

// StatsdOut sends metrics to Dogstatsd on a `kvexpress out` operation.
func StatsdOut(key string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' stats='out'", key), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, "complete")
		statsd.Incr("kvexpress.out", tags)
	}
}

// StatsdLocked sends metrics to Dogstatsd on a `kvexpress out` operation
// that is blocked by a locked file.
func StatsdLocked(file string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' file='%s' stats='locked'", file), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(file, "complete")
		statsd.Incr("kvexpress.locked", tags)
	}
}

// StatsdLock sends metrics to Dogstatsd on a `kvexpress lock` operation.
func StatsdLock(key string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' stats='lock'", key), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, "complete")
		statsd.Incr("kvexpress.lock", tags)
	}
}

// StatsdUnlock sends metrics to Dogstatsd on a `kvexpress unlock` operation.
func StatsdUnlock(key string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' stats='unlock'", key), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, "complete")
		statsd.Incr("kvexpress.unlock", tags)
	}
}

// StatsdRaw sends metrics to Dogstatsd on a `kvexpress raw` operation.
func StatsdRaw(key string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' stats='raw'", key), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, "complete")
		statsd.Incr("kvexpress.raw", tags)
	}
}

// StatsdRunTime sends metrics to Dogstatsd on various operations.
func StatsdRunTime(key string, location string, msec int64) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' location='%s' msec='%d'", key, location, msec), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, location)
		locationTag := fmt.Sprintf("location:%s", location)
		tags = append(tags, locationTag)
		statsd.Gauge("kvexpress.time", float64(msec), tags)
	}
}

// StatsdPanic sends metrics to Dogstatsd when something really bad happens.
// It also stops the execution of kvexpress.
func StatsdPanic(key, location string) {
	if DogStatsd {
		Log(fmt.Sprintf("dogstatsd='true' key='%s' location='%s' stats='panic'", key, location), "debug")
		statsd, _ := godspeed.NewDefault()
		defer statsd.Conn.Close()
		tags := makeTags(key, location)
		statsd.Incr("kvexpress.panic", tags)
	}
	// If we're going to panic, we might as well stop right here.
	// Means we can't connect to Consul, download a URL or
	// write and/or chown files.
	os.Exit(0)
}

// DDAPIConnect connects to the Datadog API and returns a client object.
func DDAPIConnect(api, app string) *datadog.Client {
	client := datadog.NewClient(api, app)
	return client
}

// makeTags creates some standard tags for use with Dogstatsd and the Datadog API.
func makeTags(key, location string) []string {
	tags := make([]string, 4)
	keyTag := fmt.Sprintf("key:%s", key)
	hostname, _ := os.Hostname()
	hostTag := fmt.Sprintf("host:%s", hostname)
	directionTag := fmt.Sprintf("direction:%s", Direction)
	locationTag := fmt.Sprintf("location:%s", location)
	tags = append(tags, keyTag)
	tags = append(tags, hostTag)
	tags = append(tags, directionTag)
	tags = append(tags, locationTag)
	return tags
}

// TODO: These three functions are ripe for refactoring to be more Golang like.

// DDStopEvent sends a Datadog event to the API when there's a stop key present.
func DDStopEvent(dd *datadog.Client, key, value string) {
	Log(fmt.Sprintf("datadog='true' DDStopEvent='true' key='%s'", key), "debug")
	tags := makeTags(key, "stop_key_present")
	tags = append(tags, "kvexpress:stop")
	title := fmt.Sprintf("Stop key is present: %s. Stopping.", key)
	event := datadog.Event{Title: title, Text: value, AlertType: "error", Tags: tags}
	post, _ := dd.PostEvent(&event)
	if post != nil {

	}
}

// DDSaveDataEvent sends a Datadog event to the API when we have updated a Consul key.
func DDSaveDataEvent(dd *datadog.Client, key, value string) {
	Log(fmt.Sprintf("datadog='true' DDSaveDataEvent='true' key='%s'", key), "debug")
	tags := makeTags(key, "complete")
	tags = append(tags, "kvexpress:success")
	title := fmt.Sprintf("Updated: %s", key)
	event := datadog.Event{Title: title, Text: value, AlertType: "info", Tags: tags}
	post, _ := dd.PostEvent(&event)
	if post != nil {

	}
}

// DDCopyDataEvent sends a Datadog event to the API when we have used `kvexpress copy`
// to copy a Consul key.
func DDCopyDataEvent(dd *datadog.Client, keyFrom, keyTo string) {
	Log(fmt.Sprintf("datadog='true' DDCopyDataEvent='true' keyFrom='%s' keyTo='%s'", keyFrom, keyTo), "debug")
	tags := makeTags(keyTo, "complete")
	tags = append(tags, "kvexpress:success")
	tags = append(tags, fmt.Sprintf("keyFrom:%s", keyFrom))
	title := fmt.Sprintf("Copy: %s to %s", keyFrom, keyTo)
	event := datadog.Event{Title: title, Text: title, AlertType: "info", Tags: tags}
	post, _ := dd.PostEvent(&event)
	if post != nil {

	}
}

// DDSaveStopEvent sends a Datadog event when we have added a stop key to Consul.
func DDSaveStopEvent(dd *datadog.Client, key, value string) {
	Log(fmt.Sprintf("datadog='true' DDSaveStopEvent='true' key='%s'", key), "debug")
	tags := makeTags(key, "stop_key_save")
	tags = append(tags, "kvexpress:stop_set")
	title := fmt.Sprintf("Set Stop Key: %s", key)
	event := datadog.Event{Title: title, Text: value, AlertType: "warning", Tags: tags}
	post, _ := dd.PostEvent(&event)
	if post != nil {

	}
}
<|endoftext|>


<commit_before>package commands

import (
	"bytes"
	"fmt"
	"github.com/jingweno/gh/github"
	"github.com/jingweno/gh/utils"
	"github.com/jingweno/go-octokit/octokit"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"sync/atomic"
)

var (
	cmdRelease = &Command{
		Run:   release,
		Usage: "release",
		Short: "Retrieve releases from GitHub",
		Long:  `Retrieve releases from GitHub for the project that the "origin" remote points to.`}

	cmdCreateRelease = &Command{
		Key:   "create",
		Run:   createRelease,
		Usage: "release create [-d] [-p] [-a <ASSETS_DIR>] [-m <MESSAGE>|-f <FILE>] TAG",
		Short: "Create a new release in GitHub",
		Long: `Create a new release in GitHub for the project that the "origin" remote points to.
- It requires the name of the tag to release as a first argument.
- The assets to include in the release are taken from releases/TAG or from the directory specified by -a.
- Use the flag -d to create a draft.
- Use the flag -p to create a prerelease.
`}

	flagReleaseDraft,
	flagReleasePrerelease bool

	flagReleaseAssetsDir,
	flagReleaseMessage,
	flagReleaseFile string
)

func init() {
	cmdRelease.Use(cmdCreateRelease)

	cmdRelease.Flag.BoolVarP(&flagReleaseDraft, "draft", "d", false, "DRAFT")
	cmdRelease.Flag.BoolVarP(&flagReleasePrerelease, "prerelease", "p", false, "PRERELEASE")
	cmdRelease.Flag.StringVarP(&flagReleaseAssetsDir, "assets", "a", "", "ASSETS_DIR")
	cmdRelease.Flag.StringVarP(&flagReleaseMessage, "message", "m", "", "MESSAGE")
	cmdRelease.Flag.StringVarP(&flagReleaseFile, "file", "f", "", "FILE")

	CmdRunner.Use(cmdRelease)
}

func release(cmd *Command, args *Args) {
	runInLocalRepo(func(localRepo *github.GitHubRepo, project *github.Project, gh *github.Client) {
		if args.Noop {
			fmt.Printf("Would request list of releases for %s\n", project)
		} else {
			releases, err := gh.Releases(project)
			utils.Check(err)
			var outputs []string
			for _, release := range releases {
				out := fmt.Sprintf("%s (%s)\n%s", release.Name, release.TagName, release.Body)
				outputs = append(outputs, out)
			}

			fmt.Println(strings.Join(outputs, "\n\n"))
		}
	})
}

func createRelease(cmd *Command, args *Args) {
	if args.IsParamsEmpty() {
		utils.Check(fmt.Errorf("Missed argument TAG"))
		return
	}

	tag := args.LastParam()

	assetsDir, err := getAssetsDirectory(flagReleaseAssetsDir, tag)
	utils.Check(err)

	runInLocalRepo(func(localRepo *github.GitHubRepo, project *github.Project, gh *github.Client) {
		currentBranch, err := localRepo.CurrentBranch()
		utils.Check(err)
		branchName := currentBranch.ShortName()

		title, body, err := github.GetTitleAndBodyFromFlags(flagReleaseMessage, flagReleaseFile)
		utils.Check(err)

		if title == "" {
			title, body, err = writeReleaseTitleAndBody(project, tag, branchName)
			utils.Check(err)
		}

		params := octokit.ReleaseParams{
			TagName:         tag,
			TargetCommitish: branchName,
			Name:            title,
			Body:            body,
			Draft:           flagReleaseDraft,
			Prerelease:      flagReleasePrerelease}

		finalRelease, err := gh.CreateRelease(project, params)
		utils.Check(err)

		uploadReleaseAssets(gh, finalRelease, assetsDir)

		fmt.Printf("\n\nRelease created: %s", finalRelease.HTMLURL)
	})
}

func writeReleaseTitleAndBody(project *github.Project, tag, currentBranch string) (string, string, error) {
	message := `
# Creating release %s for %s from %s
#
# Write a message for this release. The first block
# of the text is the title and the rest is description.
`
	message = fmt.Sprintf(message, tag, project.Name, currentBranch)

	return github.GetTitleAndBodyFromEditor("RELEASE", message)
}

func runInLocalRepo(fn func(localRepo *github.GitHubRepo, project *github.Project, client *github.Client)) {
	localRepo := github.LocalRepo()
	project, err := localRepo.CurrentProject()
	utils.Check(err)

	client := github.NewClient(project.Host)
	fn(localRepo, project, client)

	os.Exit(0)
}

func getAssetsDirectory(assetsDir, tag string) (string, error) {
	if assetsDir == "" {
		pwd, err := os.Getwd()
		utils.Check(err)

		assetsDir = filepath.Join(pwd, "releases", tag)
	}

	if !isDir(assetsDir) {
		return "", fmt.Errorf("The assets directory doesn't exist: %s", assetsDir)
	}

	if isEmptyDir(assetsDir) {
		return "", fmt.Errorf("The assets directory is empty: %s", assetsDir)
	}

	return assetsDir, nil
}

func uploadReleaseAssets(gh *github.Client, release *octokit.Release, assetsDir string) {
	var wg sync.WaitGroup
	var totalAssets, countAssets uint64

	filepath.Walk(assetsDir, func(path string, fi os.FileInfo, err error) error {
		if !fi.IsDir() {
			totalAssets += 1
		}
		return nil
	})

	printUploadProgress(&countAssets, totalAssets)

	filepath.Walk(assetsDir, func(path string, fi os.FileInfo, err error) error {
		if !fi.IsDir() {
			wg.Add(1)

			go func() {
				defer func() {
					atomic.AddUint64(&countAssets, uint64(1))
					printUploadProgress(&countAssets, totalAssets)
					wg.Done()
				}()

				uploadUrl, err := release.UploadURL.Expand(octokit.M{"name": fi.Name()})
				utils.Check(err)

				contentType := detectContentType(path, fi)

				file, err := os.Open(path)
				utils.Check(err)
				defer file.Close()

				err = gh.UploadReleaseAsset(uploadUrl, file, contentType)
				utils.Check(err)
			}()
		}

		return nil
	})

	wg.Wait()
}

func detectContentType(path string, fi os.FileInfo) string {
	file, err := os.Open(path)
	utils.Check(err)
	defer file.Close()

	fileHeader := &bytes.Buffer{}
	headerSize := int64(512)
	if fi.Size() < headerSize {
		headerSize = fi.Size()
	}

	// The content type detection only uses 512 bytes at most.
	// This way we avoid copying the whole content for big files.
	_, err = io.CopyN(fileHeader, file, headerSize)
	utils.Check(err)

	return http.DetectContentType(fileHeader.Bytes())
}

func printUploadProgress(count *uint64, total uint64) {
	out := fmt.Sprintf("Uploading assets (%d/%d)", atomic.LoadUint64(count), total)
	fmt.Print("\r" + out)
}
<commit_msg>Assign release create flags to the proper command.<commit_after>package commands

import (
	"bytes"
	"fmt"
	"github.com/jingweno/gh/github"
	"github.com/jingweno/gh/utils"
	"github.com/jingweno/go-octokit/octokit"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"sync/atomic"
)

var (
	cmdRelease = &Command{
		Run:   release,
		Usage: "release",
		Short: "Retrieve releases from GitHub",
		Long:  `Retrieve releases from GitHub for the project that the "origin" remote points to.`}

	cmdCreateRelease = &Command{
		Key:   "create",
		Run:   createRelease,
		Usage: "release create [-d] [-p] [-a <ASSETS_DIR>] [-m <MESSAGE>|-f <FILE>] TAG",
		Short: "Create a new release in GitHub",
		Long: `Create a new release in GitHub for the project that the "origin" remote points to.
- It requires the name of the tag to release as a first argument.
- The assets to include in the release are taken from releases/TAG or from the directory specified by -a.
- Use the flag -d to create a draft.
- Use the flag -p to create a prerelease.
`}

	flagReleaseDraft,
	flagReleasePrerelease bool

	flagReleaseAssetsDir,
	flagReleaseMessage,
	flagReleaseFile string
)

func init() {
	cmdCreateRelease.Flag.BoolVarP(&flagReleaseDraft, "draft", "d", false, "DRAFT")
	cmdCreateRelease.Flag.BoolVarP(&flagReleasePrerelease, "prerelease", "p", false, "PRERELEASE")
	cmdCreateRelease.Flag.StringVarP(&flagReleaseAssetsDir, "assets", "a", "", "ASSETS_DIR")
	cmdCreateRelease.Flag.StringVarP(&flagReleaseMessage, "message", "m", "", "MESSAGE")
	cmdCreateRelease.Flag.StringVarP(&flagReleaseFile, "file", "f", "", "FILE")

	cmdRelease.Use(cmdCreateRelease)
	CmdRunner.Use(cmdRelease)
}

func release(cmd *Command, args *Args) {
	runInLocalRepo(func(localRepo *github.GitHubRepo, project *github.Project, gh *github.Client) {
		if args.Noop {
			fmt.Printf("Would request list of releases for %s\n", project)
		} else {
			releases, err := gh.Releases(project)
			utils.Check(err)
			var outputs []string
			for _, release := range releases {
				out := fmt.Sprintf("%s (%s)\n%s", release.Name, release.TagName, release.Body)
				outputs = append(outputs, out)
			}

			fmt.Println(strings.Join(outputs, "\n\n"))
		}
	})
}

func createRelease(cmd *Command, args *Args) {
	if args.IsParamsEmpty() {
		utils.Check(fmt.Errorf("Missed argument TAG"))
		return
	}

	tag := args.LastParam()

	assetsDir, err := getAssetsDirectory(flagReleaseAssetsDir, tag)
	utils.Check(err)

	runInLocalRepo(func(localRepo *github.GitHubRepo, project *github.Project, gh *github.Client) {
		currentBranch, err := localRepo.CurrentBranch()
		utils.Check(err)
		branchName := currentBranch.ShortName()

		title, body, err := github.GetTitleAndBodyFromFlags(flagReleaseMessage, flagReleaseFile)
		utils.Check(err)

		if title == "" {
			title, body, err = writeReleaseTitleAndBody(project, tag, branchName)
			utils.Check(err)
		}

		params := octokit.ReleaseParams{
			TagName:         tag,
			TargetCommitish: branchName,
			Name:            title,
			Body:            body,
			Draft:           flagReleaseDraft,
			Prerelease:      flagReleasePrerelease}

		finalRelease, err := gh.CreateRelease(project, params)
		utils.Check(err)

		uploadReleaseAssets(gh, finalRelease, assetsDir)

		fmt.Printf("\n\nRelease created: %s", finalRelease.HTMLURL)
	})
}

func writeReleaseTitleAndBody(project *github.Project, tag, currentBranch string) (string, string, error) {
	message := `
# Creating release %s for %s from %s
#
# Write a message for this release. The first block
# of the text is the title and the rest is description.
`
	message = fmt.Sprintf(message, tag, project.Name, currentBranch)

	return github.GetTitleAndBodyFromEditor("RELEASE", message)
}

func runInLocalRepo(fn func(localRepo *github.GitHubRepo, project *github.Project, client *github.Client)) {
	localRepo := github.LocalRepo()
	project, err := localRepo.CurrentProject()
	utils.Check(err)

	client := github.NewClient(project.Host)
	fn(localRepo, project, client)

	os.Exit(0)
}

func getAssetsDirectory(assetsDir, tag string) (string, error) {
	if assetsDir == "" {
		pwd, err := os.Getwd()
		utils.Check(err)

		assetsDir = filepath.Join(pwd, "releases", tag)
	}

	if !isDir(assetsDir) {
		return "", fmt.Errorf("The assets directory doesn't exist: %s", assetsDir)
	}

	if isEmptyDir(assetsDir) {
		return "", fmt.Errorf("The assets directory is empty: %s", assetsDir)
	}

	return assetsDir, nil
}

func uploadReleaseAssets(gh *github.Client, release *octokit.Release, assetsDir string) {
	var wg sync.WaitGroup
	var totalAssets, countAssets uint64

	filepath.Walk(assetsDir, func(path string, fi os.FileInfo, err error) error {
		if !fi.IsDir() {
			totalAssets += 1
		}
		return nil
	})

	printUploadProgress(&countAssets, totalAssets)

	filepath.Walk(assetsDir, func(path string, fi os.FileInfo, err error) error {
		if !fi.IsDir() {
			wg.Add(1)

			go func() {
				defer func() {
					atomic.AddUint64(&countAssets, uint64(1))
					printUploadProgress(&countAssets, totalAssets)
					wg.Done()
				}()

				uploadUrl, err := release.UploadURL.Expand(octokit.M{"name": fi.Name()})
				utils.Check(err)

				contentType := detectContentType(path, fi)

				file, err := os.Open(path)
				utils.Check(err)
				defer file.Close()

				err = gh.UploadReleaseAsset(uploadUrl, file, contentType)
				utils.Check(err)
			}()
		}

		return nil
	})

	wg.Wait()
}

func detectContentType(path string, fi os.FileInfo) string {
	file, err := os.Open(path)
	utils.Check(err)
	defer file.Close()

	fileHeader := &bytes.Buffer{}
	headerSize := int64(512)
	if fi.Size() < headerSize {
		headerSize = fi.Size()
	}

	// The content type detection only uses 512 bytes at most.
	// This way we avoid copying the whole content for big files.
	_, err = io.CopyN(fileHeader, file, headerSize)
	utils.Check(err)

	return http.DetectContentType(fileHeader.Bytes())
}

func printUploadProgress(count *uint64, total uint64) {
	out := fmt.Sprintf("Uploading assets (%d/%d)", atomic.LoadUint64(count), total)
	fmt.Print("\r" + out)
}
<|endoftext|>


<commit_before>package orm

import (
	_ "gnd.la/orm/driver/sqlite"
	"reflect"
	"testing"
)

// These types should return an error when trying to register
// them because they use field codecs in an invalid way.

type HasUnexported struct {
	A int64
	b int64
}

type InvalidCodec1 struct {
	// A codec which doesn't exist
	Value []int64 `orm:",codec:nonexistent"`
}

// The following two types try to use a codec with
// structs with unexported fields, which is not allowed.

type InvalidCodec2 struct {
	Value []HasUnexported `orm:",codec:json"`
}

type InvalidCodec3 struct {
	Value []HasUnexported `orm:",codec:gob"`
}

// This type can be correctly encoded by codecs

type Rect struct {
	A, B, C, D int
	ignored    int `orm:"-"`
}

type JsonEncoded struct {
	Id    int64  `orm:",primary_key,auto_increment"`
	Rects []Rect `orm:",codec:json"`
}

type GobEncoded struct {
	Id    int64  `orm:",primary_key,auto_increment"`
	Rects []Rect `orm:",codec:gob"`
}

func TestInvalidCodecs(t *testing.T) {
	o := newMemoryOrm(t)
	defer o.Close()
	for _, v := range []interface{}{&InvalidCodec1{}, &InvalidCodec2{}, &InvalidCodec3{}} {
		_, err := o.Register(v, nil)
		if err == nil {
			t.Errorf("Expecting an error when registering %T", v)
		}
	}
}

func testCodecs(t *testing.T, o *Orm) {
	o.MustRegister((*JsonEncoded)(nil), nil)
	o.MustRegister((*GobEncoded)(nil), nil)
	o.MustInitialize()
	q := Eq("Id", 1)
	rects := []Rect{{A: 1, B: 2, C: 3, D: 4}, {A: 2, B: 3, C: 4, D: 5}}
	j1 := &JsonEncoded{Rects: rects}
	o.MustSave(j1)
	var j2 *JsonEncoded
	err := o.One(q, &j2)
	if err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(j2.Rects, rects) {
		t.Errorf("invalid JSON decoded field. Want %v, got %v.", rects, j2.Rects)
	}
	g1 := &GobEncoded{Rects: rects}
	o.MustSave(g1)
	var g2 *GobEncoded
	err = o.One(q, &g2)
	if err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(g2.Rects, rects) {
		t.Errorf("invalid gob decoded field. Want %v, got %v.", rects, g2.Rects)
	}
}

func TestCodecs(t *testing.T) {
	runTest(t, testCodecs)
}
<commit_msg>Update codec specs in tests to new syntax<commit_after>package orm

import (
	_ "gnd.la/orm/driver/sqlite"
	"reflect"
	"testing"
)

// These types should return an error when trying to register
// them because they use field codecs in an invalid way.

type HasUnexported struct {
	A int64
	b int64
}

type InvalidCodec1 struct {
	// A codec which doesn't exist
	Value []int64 `orm:",codec=nonexistent"`
}

// The following two types try to use a codec with
// structs with unexported fields, which is not allowed.

type InvalidCodec2 struct {
	Value []HasUnexported `orm:",codec=json"`
}

type InvalidCodec3 struct {
	Value []HasUnexported `orm:",codec=gob"`
}

// This type can be correctly encoded by codecs

type Rect struct {
	A, B, C, D int
	ignored    int `orm:"-"`
}

type JsonEncoded struct {
	Id    int64  `orm:",primary_key,auto_increment"`
	Rects []Rect `orm:",codec=json"`
}

type GobEncoded struct {
	Id    int64  `orm:",primary_key,auto_increment"`
	Rects []Rect `orm:",codec=gob"`
}

func TestInvalidCodecs(t *testing.T) {
	o := newMemoryOrm(t)
	defer o.Close()
	for _, v := range []interface{}{&InvalidCodec1{}, &InvalidCodec2{}, &InvalidCodec3{}} {
		_, err := o.Register(v, nil)
		if err == nil {
			t.Errorf("Expecting an error when registering %T", v)
		}
	}
}

func testCodecs(t *testing.T, o *Orm) {
	o.MustRegister((*JsonEncoded)(nil), nil)
	o.MustRegister((*GobEncoded)(nil), nil)
	o.MustInitialize()
	q := Eq("Id", 1)
	rects := []Rect{{A: 1, B: 2, C: 3, D: 4}, {A: 2, B: 3, C: 4, D: 5}}
	j1 := &JsonEncoded{Rects: rects}
	o.MustSave(j1)
	var j2 *JsonEncoded
	err := o.One(q, &j2)
	if err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(j2.Rects, rects) {
		t.Errorf("invalid JSON decoded field. Want %v, got %v.", rects, j2.Rects)
	}
	g1 := &GobEncoded{Rects: rects}
	o.MustSave(g1)
	var g2 *GobEncoded
	err = o.One(q, &g2)
	if err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(g2.Rects, rects) {
		t.Errorf("invalid gob decoded field. Want %v, got %v.", rects, g2.Rects)
	}
}

func TestCodecs(t *testing.T) {
	runTest(t, testCodecs)
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package walletdb

import (
	"errors"
)

// Errors that can occur during driver registration.
var (
	// ErrDbTypeRegistered is returned when two different database drivers
	// attempt to register with the name database type.
	ErrDbTypeRegistered = errors.New("database type already registered")
)

// Errors that the various database functions may return.
var (
	// ErrDbUnknownType is returned when there is no driver registered for
	// the specified database type.
	ErrDbUnknownType = errors.New("unknown database type")

	// ErrDbDoesNotExist is returned when open is called for a database that
	// does not exist.
	ErrDbDoesNotExist = errors.New("database does not exist")

	// ErrDbExists is returned when create is called for a database that
	// already exists.
	ErrDbExists = errors.New("database already exists")

	// ErrDbNotOpen is returned when a database instance is accessed before
	// it is opened or after it is closed.
	ErrDbNotOpen = errors.New("database not open")

	// ErrDbAlreadyOpen is returned when open is called on a database that
	// is already open.
	ErrDbAlreadyOpen = errors.New("database already open")

	// ErrInvalid is returned if the specified database is not valid.
	ErrInvalid = errors.New("invalid database")
)

// Errors that can occur when beginning or committing a transaction.
var (
	// ErrTxClosed is returned when attempting to commit or rollback a
	// transaction that has already had one of those operations performed.
	ErrTxClosed = errors.New("tx closed")

	// ErrTxNotWritable is returned when an operation that requires write
	// access to the database is attempted against a read-only transaction.
	ErrTxNotWritable = errors.New("tx not writable")
)

// Errors that can occur when putting or deleting a value or bucket.
var (
	// ErrBucketNotFound is returned when trying to access a bucket that has
	// not been created yet.
	ErrBucketNotFound = errors.New("bucket not found")

	// ErrBucketExists is returned when creating a bucket that already exists.
	ErrBucketExists = errors.New("bucket already exists")

	// ErrBucketNameRequired is returned when creating a bucket with a blank name.
	ErrBucketNameRequired = errors.New("bucket name required")

	// ErrKeyRequired is returned when inserting a zero-length key.
	ErrKeyRequired = errors.New("key required")

	// ErrKeyTooLarge is returned when inserting a key that is larger than MaxKeySize.
	ErrKeyTooLarge = errors.New("key too large")

	// ErrValueTooLarge is returned when inserting a value that is larger than MaxValueSize.
	ErrValueTooLarge = errors.New("value too large")

	// ErrIncompatibleValue is returned when trying create or delete a
	// bucket on an existing non-bucket key or when trying to create or
	// delete a non-bucket key on an existing bucket key.
	ErrIncompatibleValue = errors.New("incompatible value")
)
<commit_msg>walletdb: add new ErrDryRunRollBack error<commit_after>// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package walletdb

import (
	"errors"
)

// Errors that can occur during driver registration.
var (
	// ErrDbTypeRegistered is returned when two different database drivers
	// attempt to register with the name database type.
	ErrDbTypeRegistered = errors.New("database type already registered")
)

// Errors that the various database functions may return.
var (
	// ErrDbUnknownType is returned when there is no driver registered for
	// the specified database type.
	ErrDbUnknownType = errors.New("unknown database type")

	// ErrDbDoesNotExist is returned when open is called for a database that
	// does not exist.
	ErrDbDoesNotExist = errors.New("database does not exist")

	// ErrDbExists is returned when create is called for a database that
	// already exists.
	ErrDbExists = errors.New("database already exists")

	// ErrDbNotOpen is returned when a database instance is accessed before
	// it is opened or after it is closed.
	ErrDbNotOpen = errors.New("database not open")

	// ErrDbAlreadyOpen is returned when open is called on a database that
	// is already open.
	ErrDbAlreadyOpen = errors.New("database already open")

	// ErrInvalid is returned if the specified database is not valid.
	ErrInvalid = errors.New("invalid database")

	// ErrDryRunRollBack is returned if a database transaction should be
	// rolled back because its changes were a dry-run only.
	ErrDryRunRollBack = errors.New("dry run only; should roll back")
)

// Errors that can occur when beginning or committing a transaction.
var (
	// ErrTxClosed is returned when attempting to commit or rollback a
	// transaction that has already had one of those operations performed.
	ErrTxClosed = errors.New("tx closed")

	// ErrTxNotWritable is returned when an operation that requires write
	// access to the database is attempted against a read-only transaction.
	ErrTxNotWritable = errors.New("tx not writable")
)

// Errors that can occur when putting or deleting a value or bucket.
var (
	// ErrBucketNotFound is returned when trying to access a bucket that has
	// not been created yet.
	ErrBucketNotFound = errors.New("bucket not found")

	// ErrBucketExists is returned when creating a bucket that already exists.
	ErrBucketExists = errors.New("bucket already exists")

	// ErrBucketNameRequired is returned when creating a bucket with a blank name.
	ErrBucketNameRequired = errors.New("bucket name required")

	// ErrKeyRequired is returned when inserting a zero-length key.
	ErrKeyRequired = errors.New("key required")

	// ErrKeyTooLarge is returned when inserting a key that is larger than MaxKeySize.
	ErrKeyTooLarge = errors.New("key too large")

	// ErrValueTooLarge is returned when inserting a value that is larger than MaxValueSize.
	ErrValueTooLarge = errors.New("value too large")

	// ErrIncompatibleValue is returned when trying create or delete a
	// bucket on an existing non-bucket key or when trying to create or
	// delete a non-bucket key on an existing bucket key.
	ErrIncompatibleValue = errors.New("incompatible value")
)
<|endoftext|>