<commit_before>package godrv

import (
	"database/sql"
	"testing"
)

func init() {
	Register("set names utf8")
}

func checkErr(t *testing.T, err error) {
	if err != nil {
		t.Fatalf("Error: %v", err)
	}
}
func checkErrId(t *testing.T, err error, rid, eid int64) {
	checkErr(t, err)
	if rid != eid {
		t.Fatal("res.LastInsertId() ==", rid, "but should be", eid)
	}
}

func TestAll(t *testing.T) {
	data := []string{"jeden", "dwa"}

	db, err := sql.Open("mymysql", "test/testuser/TestPasswd9")
	checkErr(t, err)
	defer db.Close()

	db.Exec("DROP TABLE go")

	_, err = db.Exec(
		`CREATE TABLE go (
			id  INT PRIMARY KEY AUTO_INCREMENT,
			txt TEXT
		) ENGINE=InnoDB`)
	checkErr(t, err)

	ins, err := db.Prepare("INSERT go SET txt=?")
	checkErr(t, err)

	tx, err := db.Begin()
	checkErr(t, err)

	res, err := ins.Exec(data[0])
	checkErr(t, err)
	id, err := res.LastInsertId()
	checkErrId(t, err, id, 1)

	res, err = ins.Exec(data[1])
	checkErr(t, err)
	id, err = res.LastInsertId()
	checkErrId(t, err, id, 2)

	checkErr(t, tx.Commit())

	tx, err = db.Begin()
	checkErr(t, err)

	res, err = tx.Exec("INSERT go SET txt=?", "trzy")
	checkErr(t, err)
	id, err = res.LastInsertId()
	checkErrId(t, err, id, 3)

	checkErr(t, tx.Rollback())

	rows, err := db.Query("SELECT * FROM go")
	checkErr(t, err)
	for rows.Next() {
		var id int
		var txt string
		checkErr(t, rows.Scan(&id, &txt))
		if id > len(data) {
			t.Fatal("To many rows in table")
		}
		if data[id-1] != txt {
			t.Fatalf("txt[%d] == '%s' != '%s'", id, txt, data[id-1])
		}
	}

	sql := "select sum(41) as test"
	rows, err = db.Query(sql)
	checkErr(t, err)
	if !rows.Next() {
		t.Fatal(sql, " : len(rows) == 0")
	}
}
<commit_msg>More tests for decimals returned by MySQL sum() function<commit_after>package godrv

import (
	"database/sql"
	"testing"
)

func init() {
	Register("set names utf8")
}

func checkErr(t *testing.T, err error) {
	if err != nil {
		t.Fatalf("Error: %v", err)
	}
}
func checkErrId(t *testing.T, err error, rid, eid int64) {
	checkErr(t, err)
	if rid != eid {
		t.Fatal("res.LastInsertId() ==", rid, "but should be", eid)
	}
}

func TestAll(t *testing.T) {
	data := []string{"jeden", "dwa"}

	db, err := sql.Open("mymysql", "test/testuser/TestPasswd9")
	checkErr(t, err)
	defer db.Close()

	db.Exec("DROP TABLE go")

	_, err = db.Exec(
		`CREATE TABLE go (
			id  INT PRIMARY KEY AUTO_INCREMENT,
			txt TEXT
		) ENGINE=InnoDB`)
	checkErr(t, err)

	ins, err := db.Prepare("INSERT go SET txt=?")
	checkErr(t, err)

	tx, err := db.Begin()
	checkErr(t, err)

	res, err := ins.Exec(data[0])
	checkErr(t, err)
	id, err := res.LastInsertId()
	checkErrId(t, err, id, 1)

	res, err = ins.Exec(data[1])
	checkErr(t, err)
	id, err = res.LastInsertId()
	checkErrId(t, err, id, 2)

	checkErr(t, tx.Commit())

	tx, err = db.Begin()
	checkErr(t, err)

	res, err = tx.Exec("INSERT go SET txt=?", "trzy")
	checkErr(t, err)
	id, err = res.LastInsertId()
	checkErrId(t, err, id, 3)

	checkErr(t, tx.Rollback())

	rows, err := db.Query("SELECT * FROM go")
	checkErr(t, err)
	for rows.Next() {
		var id int
		var txt string
		checkErr(t, rows.Scan(&id, &txt))
		if id > len(data) {
			t.Fatal("To many rows in table")
		}
		if data[id-1] != txt {
			t.Fatalf("txt[%d] == '%s' != '%s'", id, txt, data[id-1])
		}
	}

	sql := "select sum(41) as test"
	row := db.QueryRow(sql)
	var vi int64
	checkErr(t, row.Scan(&vi))
	if vi != 41 {
		t.Fatal(sql)
	}
	sql = "select sum(4123232323232) as test"
	row = db.QueryRow(sql)
	var vf float64
	checkErr(t, row.Scan(&vf))
	if vf != 4123232323232 {
		t.Fatal(sql)
	}
}
<|endoftext|>


<commit_before>//
// Keithley S46 RF Switch example
//
//
// The general flow of the code is
//      Open Resource Manager
//      Open VISA Session to an Instrument
//      Write the Identification Query Using viWrite
//      Try to Read a Response With viRead
//      Close the VISA Session
//

package main

import (
	"fmt"

	vi "github.com/jpoirier/visa"
	ke "github.com/jpoirier/visa/keithley"
)

func main() {
	// First we must call viOpenDefaultRM to get the resource manager
	// handle.  We will store this handle in defaultRM.
	rm, status := vi.OpenDefaultRM()
	if status < vi.SUCCESS {
		fmt.Println("Could not open a session to the VISA Resource Manager!")
		return
	}
	defer rm.Close()

	//
	instr, status := ke.OpenGpib(rm, 0, 2, vi.NULL, vi.NULL)
	if status < vi.SUCCESS {
		fmt.Println("An error occurred opening the session to GPIB 0:2")
		return
	}
	defer instr.Close()

	instr.Reset()
	instr.OpenAllChans()
	instr.OpenChan(1)
	instr.CloseChan(1)
	list, _ := instr.ClosedChanList()
	fmt.Println("Closed channel list: ", list)
	fmt.Println("Closing Sessions...")
}
<commit_msg>fixed example<commit_after>//
// Keithley S46 RF Switch example
//
//
//

package main

import (
	"fmt"

	vi "github.com/jpoirier/visa"
	ke "github.com/jpoirier/visa/keithley"
)

func main() {
	// First we must call viOpenDefaultRM to get the resource manager
	// handle.  We will store this handle in defaultRM.
	rm, status := vi.OpenDefaultRM()
	if status < vi.SUCCESS {
		fmt.Println("Could not open a session to the VISA Resource Manager!")
		return
	}
	defer rm.Close()

	//
	instr, status := ke.OpenGpib(rm, 0, 2, vi.NULL, vi.NULL)
	if status < vi.SUCCESS {
		fmt.Println("An error occurred opening the session to GPIB 0:2")
		return
	}
	defer instr.Close()

	instr.Reset()
	instr.OpenAllChans()
	instr.OpenChan(1)
	instr.CloseChan(1)
	list, _ := instr.ClosedChanList()
	fmt.Println("Closed channel list: ", list)
	fmt.Println("Closing Sessions...")
}
<|endoftext|>


<commit_before>package gmgmap

import (
	"fmt"
	"math"
	"math/rand"
)

type Building struct {
	r          rect
	importance int
}

func (b Building) addNPC(c *Layer) {
	// Try to place a random NPC somewhere inside the building
	for i := 0; i < 100; i++ {
		x := rand.Intn(b.r.w-2) + b.r.x + 1
		y := rand.Intn(b.r.h-2) + b.r.y + 1
		if c.getTile(x, y) == nothing {
			c.setTile(x, y, player)
			break
		}
	}
}

// NewVillage - create a village, made up of multiple buildings
func NewVillage(width, height, buildingPadding int) *Map {
	m := NewMap(width, height)
	g := m.Layer("Ground")
	s := m.Layer("Structures")
	f := m.Layer("Furniture")
	c := m.Layer("Characters")
	// Store usage of paths as weights
	pathUsage := make([][]int, height)
	for i := range pathUsage {
		pathUsage[i] = make([]int, width)
	}

	// Grass
	g.fill(grass)

	// Buildings
	buildings := make([]Building, 0)
	// Keep placing buildings for a while
	for i := 0; i < 500; i++ {
		w := rand.Intn(3) + 5
		h := rand.Intn(3) + 5
		x := rand.Intn(width - w)
		y := rand.Intn(height - h)
		if x < 0 || y < 0 {
			continue
		}
		// Check if it overlaps with any existing buildings
		overlaps := false
		for _, b := range buildings {
			// Add a bit of padding between the buildings
			if rectOverlaps(
				b.r,
				rect{
					x - buildingPadding,
					y - buildingPadding,
					w + buildingPadding*2,
					h + buildingPadding*2}) {
				overlaps = true
				break
			}
		}
		if overlaps {
			continue
		}
		addBuilding(g, s, f, x, y, w, h)
		buildings = append(buildings, Building{rect{x, y, w, h}, 0})
	}

	// Randomly assign importance to buildings
	impSum := 0
	for _, building := range buildings {
		building.importance = int(math.Pow(float64(rand.Intn(3)+1), 2))
		impSum += building.importance
		// Place NPCs based on importance
		for i := 0; i < building.importance; i++ {
			building.addNPC(c)
		}
	}

	// Draw paths between random pairs of entrances via importance
	// Ensure at least one path exists for all buildings
	buildingsWithPaths := map[int]bool{}
	numPaths := len(buildings) * 3
	for i := 0; i < numPaths || len(buildingsWithPaths) < len(buildings); i++ {
		for {
			// Check for path valid and exists
			building1 := rand.Intn(len(buildings))
			// randomly select second building by importance
			impFact := rand.Intn(impSum)
			building2 := 0
			impFactSum := 0
			for j, b2 := range buildings {
				impFactSum += b2.importance
				if impFactSum > impFact {
					building2 = j
					break
				}
			}
			if building1 == building2 {
				continue
			}
			buildingsWithPaths[building1] = true
			buildingsWithPaths[building2] = true
			// TODO: find entrance and start/end paths there
			b1 := buildings[building1]
			b2 := buildings[building2]
			startX := b1.r.x + b1.r.w/2
			startY := b1.r.y + b1.r.h
			endX := b2.r.x + b2.r.w/2
			endY := b2.r.y + b2.r.h
			path, _, found := addPath(g, s, startX, startY, endX, endY)
			if !found {
				fmt.Println("Could not find path")
			} else {
				for _, t := range path {
					pathUsage[t.(*Tile).y][t.(*Tile).x]++
				}
			}
			break
		}
	}

	// Draw paths based on how well they're used
	for y := range pathUsage {
		for x, usage := range pathUsage[y] {
			if usage == 0 {
				if g.getTile(x, y) == grass && s.getTile(x, y) == nothing {
					s.setTile(x, y, tree)
				}
			} else if usage <= 3 {
				// Leave as grass
			} else if usage <= 6 {
				g.setTile(x, y, road)
			} else {
				g.setTile(x, y, road2)
			}
		}
	}

	return m
}

func addBuilding(g, s, f *Layer, x, y, w, h int) {
	// Perimeter
	s.rectangle(rect{x, y, w, h}, wall, false)
	// Floor
	g.rectangle(rect{x + 1, y + 1, w - 2, h - 2}, room, true)
	// Entrance
	entranceX := x + w/2
	entranceY := y + h - 1
	g.setTile(entranceX, entranceY, room)
	s.setTile(entranceX, entranceY, door)
	f.setTile(entranceX-1, entranceY, sign)
}
<commit_msg>Important buildings look different<commit_after>package gmgmap

import (
	"fmt"
	"math"
	"math/rand"
)

type Building struct {
	r          rect
	importance int
}

func (b Building) addNPC(c *Layer) {
	// Try to place a random NPC somewhere inside the building
	for i := 0; i < 100; i++ {
		x := rand.Intn(b.r.w-2) + b.r.x + 1
		y := rand.Intn(b.r.h-2) + b.r.y + 1
		if c.getTile(x, y) == nothing {
			c.setTile(x, y, player)
			break
		}
	}
}

// NewVillage - create a village, made up of multiple buildings
func NewVillage(width, height, buildingPadding int) *Map {
	m := NewMap(width, height)
	g := m.Layer("Ground")
	s := m.Layer("Structures")
	f := m.Layer("Furniture")
	c := m.Layer("Characters")
	// Store usage of paths as weights
	pathUsage := make([][]int, height)
	for i := range pathUsage {
		pathUsage[i] = make([]int, width)
	}

	// Grass
	g.fill(grass)

	// Buildings
	buildings := make([]Building, 0)
	// Keep placing buildings for a while
	for i := 0; i < 500; i++ {
		w := rand.Intn(3) + 5
		h := rand.Intn(3) + 5
		x := rand.Intn(width - w)
		y := rand.Intn(height - h)
		if x < 0 || y < 0 {
			continue
		}
		// Check if it overlaps with any existing buildings
		overlaps := false
		for _, b := range buildings {
			// Add a bit of padding between the buildings
			if rectOverlaps(
				b.r,
				rect{
					x - buildingPadding,
					y - buildingPadding,
					w + buildingPadding*2,
					h + buildingPadding*2}) {
				overlaps = true
				break
			}
		}
		if overlaps {
			continue
		}
		buildings = append(buildings, Building{rect{x, y, w, h}, 0})
	}

	// Randomly assign importance to buildings
	impSum := 0
	for i, building := range buildings {
		imp := int(math.Pow(float64(rand.Float32()*3.0+1), 2))
		buildings[i].importance = imp
		impSum += imp

		// Use tiles based on importance
		tileRoom, tileWall := room, wall
		if imp > 10 {
			tileRoom, tileWall = room2, wall2
		}
		hasSign := imp > 5
		addBuilding(g, s, f, building.r, tileRoom, tileWall, hasSign)
	}

	// Draw paths between random pairs of entrances via importance
	// Ensure at least one path exists for all buildings
	buildingsWithPaths := map[int]bool{}
	numPaths := len(buildings) * 3
	for i := 0; i < numPaths || len(buildingsWithPaths) < len(buildings); i++ {
		for {
			// Check for path valid and exists
			building1 := rand.Intn(len(buildings))
			// randomly select second building by importance
			impFact := rand.Intn(impSum)
			building2 := 0
			impFactSum := 0
			for j, b2 := range buildings {
				impFactSum += b2.importance
				if impFactSum > impFact {
					building2 = j
					break
				}
			}
			if building1 == building2 {
				continue
			}
			buildingsWithPaths[building1] = true
			buildingsWithPaths[building2] = true
			// TODO: find entrance and start/end paths there
			b1 := buildings[building1]
			b2 := buildings[building2]
			startX := b1.r.x + b1.r.w/2
			startY := b1.r.y + b1.r.h
			endX := b2.r.x + b2.r.w/2
			endY := b2.r.y + b2.r.h
			path, _, found := addPath(g, s, startX, startY, endX, endY)
			if !found {
				fmt.Println("Could not find path")
			} else {
				for _, t := range path {
					pathUsage[t.(*Tile).y][t.(*Tile).x]++
				}
			}
			break
		}
	}

	// Draw paths based on how well they're used
	for y := range pathUsage {
		for x, usage := range pathUsage[y] {
			if usage == 0 {
				if g.getTile(x, y) == grass && s.getTile(x, y) == nothing {
					s.setTile(x, y, tree)
				}
			} else if usage <= 3 {
				// Leave as grass
			} else if usage <= 6 {
				g.setTile(x, y, road)
			} else {
				g.setTile(x, y, road2)
			}
		}
	}

	// Place NPCs based on importance
	for _, building := range buildings {
		for i := 0; i < building.importance/2; i++ {
			building.addNPC(c)
		}
	}

	return m
}

func addBuilding(g, s, f *Layer, r rect, tileRoom, tileWall rune, hasSign bool) {
	// Perimeter
	s.rectangle(r, tileWall, false)
	// Floor
	g.rectangle(rect{r.x + 1, r.y + 1, r.w - 2, r.h - 2}, tileRoom, true)
	// Entrance
	entranceX := r.x + r.w/2
	entranceY := r.y + r.h - 1
	g.setTile(entranceX, entranceY, tileRoom)
	s.setTile(entranceX, entranceY, door)
	if hasSign {
		f.setTile(entranceX-1, entranceY, sign)
	}
}
<|endoftext|>


<commit_before>package clock

import (
	"fmt"
)

const testVersion = 3

type Clock struct {
	h, m int
}

func New(hour, minute int) Clock {
	hour = (hour + minute/60) % 24
	minute = minute % 60
	return Clock{hour, minute}
}

func (c Clock) String() string {
	return fmt.Sprintf("%02d:%02d", c.h, c.m)
}

func (Clock) Add(minutes int) Clock {
	return Clock{1, minutes}
}
<commit_msg>fix the init code to work with negative values<commit_after>package clock

import (
	"fmt"
)

const testVersion = 3

type Clock struct {
	h, m int
}

func New(hour, minute int) Clock {
	hour = (hour + minute/60) % 24
	minute = minute % 60
	if minute < 0 {
		hour--
		minute = minute + 60
	}
	if hour < 0 {
		hour = hour + 24
	}
	return Clock{hour, minute}
}

func (c Clock) String() string {
	return fmt.Sprintf("%02d:%02d", c.h, c.m)
}

func (c Clock) Add(minutes int) Clock {
	var hour = (c.h + (c.m+minutes)/60) % 24
	minutes = (minutes + c.m) % 60
	if minutes < 0 {
		hour--
		minutes = minutes + 60
	}
	if hour < 0 {
		hour = hour + 24
	}
	return Clock{hour, minutes}
}
<|endoftext|>


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

// relog provides an alternate logger api with support for logging levels
// Although flexible, the recommended usage is to create a logger object,
// set it as the global logger, and use the package level functions to execute
// the logging.
// Multiple logger objects are only meant for those who like trouble.
package relog

import (
	"fmt"
	"io"
	"log"
	"os"
	"strings"
	"syscall"
)

func init() {
	globalLogger = New(os.Stdout, "", log.LstdFlags, INFO)
}

var globalLogger *Logger

const (
	DEBUG = iota
	INFO
	WARNING
	ERROR
	FATAL
	NONE
)

var levelNames = []string{
	"DEBUG",
	"INFO",
	"WARNING",
	"ERROR",
	"FATAL",
	"NONE",
}

var levelPrefixes []string

func init() {
	levelPrefixes = make([]string, len(levelNames))
	for i, name := range levelNames {
		levelPrefixes[i] = name + ": "
	}
}

func Debug(format string, args ...interface{}) {
	globalLogger.Output(DEBUG, format, args...)
}

func Info(format string, args ...interface{}) {
	globalLogger.Output(INFO, format, args...)
}

func Warning(format string, args ...interface{}) {
	globalLogger.Output(WARNING, format, args...)
}

func Error(format string, args ...interface{}) {
	globalLogger.Output(ERROR, format, args...)
}

func Fatal(format string, args ...interface{}) {
	globalLogger.Output(FATAL, format, args...)
	os.Exit(1)
}

func SetLogger(logger *Logger) {
	globalLogger = logger
}

type Logger struct {
	logger *log.Logger
	level  int
}

func New(out io.Writer, prefix string, flag, level int) *Logger {
	return &Logger{logger: log.New(out, prefix, flag), level: level}
}

func (logger *Logger) Debug(format string, args ...interface{}) {
	logger.Output(DEBUG, format, args...)
}

func (logger *Logger) Info(format string, args ...interface{}) {
	logger.Output(INFO, format, args...)
}

func (logger *Logger) Warning(format string, args ...interface{}) {
	logger.Output(WARNING, format, args...)
}

func (logger *Logger) Error(format string, args ...interface{}) {
	logger.Output(ERROR, format, args...)
}

func (logger *Logger) Fatal(format string, args ...interface{}) {
	logger.Output(FATAL, format, args...)
	os.Exit(1)
}

// Redactor is an interface for types that may contain sensitive
// information (like passwords), which shouldn't be printed to the
// log.
type Redactor interface {
	// Redact returns a copy of the instance with sensitive
	// information removed.
	Redact() interface{}
}

// Redact returns a string of * having the same length as s.
func Redact(s string) string {
	return strings.Repeat("*", len(s))
}

func (logger *Logger) Output(level int, format string, args ...interface{}) {
	if logger.level > level {
		return
	}
	redactedArgs := make([]interface{}, len(args))
	for i, arg := range args {
		if redactor, ok := arg.(Redactor); ok {
			redactedArgs[i] = redactor.Redact()
		} else {
			redactedArgs[i] = arg
		}
	}
	// Judicious call depth setting: all callers are 3 levels deep
	logger.logger.Output(3, levelPrefixes[level]+fmt.Sprintf(format, redactedArgs...))
}

func (logger *Logger) SetFlags(flag int) {
	logger.logger.SetFlags(flag)
}

func (logger *Logger) SetPrefix(prefix string) {
	logger.logger.SetPrefix(prefix)
}

func (logger *Logger) SetLevel(level int) {
	logger.level = level
}

func LogNameToLogLevel(name string) int {
	s := strings.ToUpper(name)
	for i, level := range levelNames {
		if level == s {
			return i
		}
	}
	panic(fmt.Errorf("no log level: %v", name))
}

// Replace stdout and stderr with a file. This overwrites the actual file
// descriptors which means even top level panic output will show up in
// these files.
func HijackStdio(fOut *os.File, fErr *os.File) error {
	if fOut != nil {
		if err := syscall.Dup2(int(fOut.Fd()), int(os.Stdout.Fd())); err != nil {
			return err
		}
	}
	if fErr != nil {
		if err := syscall.Dup2(int(fErr.Fd()), int(os.Stderr.Fd())); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>It's Redacted, not Redact.<commit_after>// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// relog provides an alternate logger api with support for logging levels
// Although flexible, the recommended usage is to create a logger object,
// set it as the global logger, and use the package level functions to execute
// the logging.
// Multiple logger objects are only meant for those who like trouble.
package relog

import (
	"fmt"
	"io"
	"log"
	"os"
	"strings"
	"syscall"
)

func init() {
	globalLogger = New(os.Stdout, "", log.LstdFlags, INFO)
}

var globalLogger *Logger

const (
	DEBUG = iota
	INFO
	WARNING
	ERROR
	FATAL
	NONE
)

var levelNames = []string{
	"DEBUG",
	"INFO",
	"WARNING",
	"ERROR",
	"FATAL",
	"NONE",
}

var levelPrefixes []string

func init() {
	levelPrefixes = make([]string, len(levelNames))
	for i, name := range levelNames {
		levelPrefixes[i] = name + ": "
	}
}

func Debug(format string, args ...interface{}) {
	globalLogger.Output(DEBUG, format, args...)
}

func Info(format string, args ...interface{}) {
	globalLogger.Output(INFO, format, args...)
}

func Warning(format string, args ...interface{}) {
	globalLogger.Output(WARNING, format, args...)
}

func Error(format string, args ...interface{}) {
	globalLogger.Output(ERROR, format, args...)
}

func Fatal(format string, args ...interface{}) {
	globalLogger.Output(FATAL, format, args...)
	os.Exit(1)
}

func SetLogger(logger *Logger) {
	globalLogger = logger
}

type Logger struct {
	logger *log.Logger
	level  int
}

func New(out io.Writer, prefix string, flag, level int) *Logger {
	return &Logger{logger: log.New(out, prefix, flag), level: level}
}

func (logger *Logger) Debug(format string, args ...interface{}) {
	logger.Output(DEBUG, format, args...)
}

func (logger *Logger) Info(format string, args ...interface{}) {
	logger.Output(INFO, format, args...)
}

func (logger *Logger) Warning(format string, args ...interface{}) {
	logger.Output(WARNING, format, args...)
}

func (logger *Logger) Error(format string, args ...interface{}) {
	logger.Output(ERROR, format, args...)
}

func (logger *Logger) Fatal(format string, args ...interface{}) {
	logger.Output(FATAL, format, args...)
	os.Exit(1)
}

// Redactor is an interface for types that may contain sensitive
// information (like passwords), which shouldn't be printed to the
// log.
type Redactor interface {
	// Redacted returns a copy of the instance with sensitive
	// information removed.
	Redacted() interface{}
}

// Redact returns a string of * having the same length as s.
func Redact(s string) string {
	return strings.Repeat("*", len(s))
}

func (logger *Logger) Output(level int, format string, args ...interface{}) {
	if logger.level > level {
		return
	}
	redactedArgs := make([]interface{}, len(args))
	for i, arg := range args {
		if redactor, ok := arg.(Redactor); ok {
			redactedArgs[i] = redactor.Redacted()
		} else {
			redactedArgs[i] = arg
		}
	}
	// Judicious call depth setting: all callers are 3 levels deep
	logger.logger.Output(3, levelPrefixes[level]+fmt.Sprintf(format, redactedArgs...))
}

func (logger *Logger) SetFlags(flag int) {
	logger.logger.SetFlags(flag)
}

func (logger *Logger) SetPrefix(prefix string) {
	logger.logger.SetPrefix(prefix)
}

func (logger *Logger) SetLevel(level int) {
	logger.level = level
}

func LogNameToLogLevel(name string) int {
	s := strings.ToUpper(name)
	for i, level := range levelNames {
		if level == s {
			return i
		}
	}
	panic(fmt.Errorf("no log level: %v", name))
}

// Replace stdout and stderr with a file. This overwrites the actual file
// descriptors which means even top level panic output will show up in
// these files.
func HijackStdio(fOut *os.File, fErr *os.File) error {
	if fOut != nil {
		if err := syscall.Dup2(int(fOut.Fd()), int(os.Stdout.Fd())); err != nil {
			return err
		}
	}
	if fErr != nil {
		if err := syscall.Dup2(int(fErr.Fd()), int(os.Stderr.Fd())); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


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

// This file describes the abstract model of services (and their instances) as
// represented in Istio. This model is independent of the underlying platform
// (Kubernetes, Mesos, etc.). Platform specific adapters found populate the
// model object with various fields, from the metadata found in the platform.
// The platform independent proxy code uses the representation in the model to
// generate the configuration files for the Layer 7 proxy sidecar. The proxy
// code is specific to individual proxy implementations

package model

import (
	"bytes"
	"fmt"
	"sort"
	"strings"
)

// Service describes an Istio service (e.g., catalog.mystore.com:8080)
// Each service has a fully qualified domain name (FQDN) and one or more
// ports where the service is listening for connections. *Optionally*, a
// service can have a single load balancer/virtual IP address associated
// with it, such that the DNS queries for the FQDN resolves to the virtual
// IP address (a load balancer IP).
//
// E.g., in kubernetes, a service foo is associated with
// foo.default.svc.cluster.local hostname, has a virtual IP of 10.0.1.1 and
// listens on ports 80, 8080
type Service struct {
	// Hostname of the service, e.g. "catalog.mystore.com"
	Hostname string `json:"hostname"`

	// Address specifies the service IPv4 address of the load balancer
	Address string `json:"address,omitempty"`

	// Ports is the set of network ports where the service is listening for
	// connections
	Ports PortList `json:"ports,omitempty"`

	ExternalName string `json:"external"`
}

// Port represents a network port where a service is listening for
// connections. The port should be annotated with the type of protocol
// used by the port.
type Port struct {
	// Name ascribes a human readable name for the port object. When a
	// service has multiple ports, the name field is mandatory
	Name string `json:"name,omitempty"`

	// Port number where the service can be reached. Does not necessarily
	// map to the corresponding port numbers for the instances behind the
	// service. See NetworkEndpoint definition below.
	Port int `json:"port"`

	// Protocol to be used for the port.
	Protocol Protocol `json:"protocol,omitempty"`
}

// PortList is a set of ports
type PortList []*Port

// Protocol defines network protocols for ports
type Protocol string

// Protocols used by the services
const (
	ProtocolGRPC  Protocol = "GRPC"
	ProtocolHTTPS Protocol = "HTTPS"
	ProtocolHTTP2 Protocol = "HTTP2"
	ProtocolHTTP  Protocol = "HTTP"
	ProtocolTCP   Protocol = "TCP"
	ProtocolUDP   Protocol = "UDP"
)

// NetworkEndpoint defines a network address (IP:port) associated with an instance of the
// service. A service has one or more instances each running in a
// container/VM/pod. If a service has multiple ports, then the same
// instance IP is expected to be listening on multiple ports (one per each
// service port). Note that the port associated with an instance does not
// have to be the same as the port associated with the service. Depending
// on the network setup (NAT, overlays), this could vary.
//
// For e.g., if catalog.mystore.com is accessible through port 80 and 8080,
// and it maps to an instance with IP 172.16.0.1, such that connections to
// port 80 are forwarded to port 55446, and connections to port 8080 are
// forwarded to port 33333,
//
// then internally, we have two two endpoint structs for the
// service catalog.mystore.com
//  --> 172.16.0.1:54546 (with ServicePort pointing to 80) and
//  --> 172.16.0.1:33333 (with ServicePort pointing to 8080)
type NetworkEndpoint struct {
	// Address of the network endpoint, typically an IPv4 address
	Address string `json:"ip_address,omitempty"`

	// Port number where this instance is listening for connections This
	// need not be the same as the port where the service is accessed.
	// e.g., catalog.mystore.com:8080 -> 172.16.0.1:55446
	Port int `json:"port"`

	// Port declaration from the service declaration This is the port for
	// the service associated with this instance (e.g.,
	// catalog.mystore.com)
	ServicePort *Port `json:"service_port"`
}

// Tags is a non empty set of arbitrary strings. Each version of a service can
// be differentiated by a unique set of tags associated with the version. These
// tags are assigned to all instances of a particular service version. For
// example, lets say catalog.mystore.com has 2 versions v1 and v2. v1 instances
// could have tags gitCommit=aeiou234, region=us-east, while v2 instances could
// have tags name=kittyCat,region=us-east.
type Tags map[string]string

// TagsList is a collection of tags used for comparing tags against a
// collection of tags
type TagsList []Tags

// ServiceInstance represents an individual instance of a specific version
// of a service. It binds a network endpoint (ip:port), the service
// description (which is oblivious to various versions) and a set of tags
// that describe the service version associated with this instance.
//
// The tags associated with a service instance are unique per a network endpoint.
// There is one well defined set of tags for each service instance network endpoint.
//
// For example, the set of service instances associated with catalog.mystore.com
// are modeled like this
//      --> NetworkEndpoint(172.16.0.1:8888), Service(catalog.myservice.com), Tag(foo=bar)
//      --> NetworkEndpoint(172.16.0.2:8888), Service(catalog.myservice.com), Tag(foo=bar)
//      --> NetworkEndpoint(172.16.0.3:8888), Service(catalog.myservice.com), Tag(kitty=cat)
//      --> NetworkEndpoint(172.16.0.4:8888), Service(catalog.myservice.com), Tag(kitty=cat)
type ServiceInstance struct {
	Endpoint NetworkEndpoint `json:"endpoint,omitempty"`
	Service  *Service        `json:"service,omitempty"`
	Tags     Tags            `json:"tags,omitempty"`
}

// ServiceDiscovery enumerates Istio service instances.
type ServiceDiscovery interface {
	// Services list declarations of all services in the system
	Services() []*Service

	// GetService retrieves a service by host name if it exists
	GetService(hostname string) (*Service, bool)

	// Instances retrieves instances for a service and its ports that match
	// any of the supplied tags. All instances match an empty tag list.
	//
	// For example, consider the example of catalog.mystore.com as described in NetworkEndpoints
	// Instances(catalog.myservice.com, 80) ->
	//      --> NetworkEndpoint(172.16.0.1:8888), Service(catalog.myservice.com), Tag(foo=bar)
	//      --> NetworkEndpoint(172.16.0.2:8888), Service(catalog.myservice.com), Tag(foo=bar)
	//      --> NetworkEndpoint(172.16.0.3:8888), Service(catalog.myservice.com), Tag(kitty=cat)
	//      --> NetworkEndpoint(172.16.0.4:8888), Service(catalog.myservice.com), Tag(kitty=cat)
	//
	// Calling Instances with specific tags returns a trimmed list.
	// e.g., Instances(catalog.myservice.com, 80, foo=bar) ->
	//      --> NetworkEndpoint(172.16.0.1:8888), Service(catalog.myservice.com), Tag(foo=bar)
	//      --> NetworkEndpoint(172.16.0.2:8888), Service(catalog.myservice.com), Tag(foo=bar)
	//
	// Similar concepts apply for calling this function with a specific
	// port, hostname and tags.
	Instances(hostname string, ports []string, tags TagsList) []*ServiceInstance

	// HostInstances lists service instances for a given set of IPv4 addresses.
	HostInstances(addrs map[string]bool) []*ServiceInstance

	// Gets all the Istio service accounts mapped from service hostname, in istio identity format.
	// For example,
	// GetIstioServiceAccounts(catalog.myservice.com) -->
	//      --> [istio:serviceaccount1, istio:serviceaccount2]
	// GetIstioServiceAccounts(backend.myservice.com) --> [istio:serviceaccount3]
	GetIstioServiceAccounts(hostname string) ([]string, error)
}

// SubsetOf is true if the tag has identical values for the keys
func (t Tags) SubsetOf(that Tags) bool {
	for k, v := range t {
		if that[k] != v {
			return false
		}
	}
	return true
}

// Equals returns true if the tags are identical
func (t Tags) Equals(that Tags) bool {
	if t == nil {
		return that == nil
	}
	if that == nil {
		return t == nil
	}
	return t.SubsetOf(that) && that.SubsetOf(t)
}

// HasSubsetOf returns true if the input tags are a super set of one tags in a
// collection or if the tag collection is empty
func (tags TagsList) HasSubsetOf(that Tags) bool {
	if len(tags) == 0 {
		return true
	}
	for _, tag := range tags {
		if tag.SubsetOf(that) {
			return true
		}
	}
	return false
}

// GetNames returns port names
func (ports PortList) GetNames() []string {
	names := make([]string, 0)
	for _, port := range ports {
		names = append(names, port.Name)
	}
	return names
}

// Get retrieves a port declaration by name
func (ports PortList) Get(name string) (*Port, bool) {
	for _, port := range ports {
		if port.Name == name {
			return port, true
		}
	}
	return nil, false
}

// Key generates a unique string referencing service instances for a given port and tags.
// The separator character must be exclusive to the regular expressions allowed in the
// service declaration.
func (s *Service) Key(port *Port, tag Tags) string {
	// TODO: check port is non nil and membership of port in service
	return ServiceKey(s.Hostname, PortList{port}, TagsList{tag})
}

// ServiceKey generates a service key for a collection of ports and tags
func ServiceKey(hostname string, servicePorts PortList, serviceTags TagsList) string {
	// example: name.namespace|http|env=prod;env=test,version=my-v1
	var buffer bytes.Buffer
	buffer.WriteString(hostname)
	np := len(servicePorts)
	nt := len(serviceTags)

	if nt == 1 && serviceTags[0] == nil {
		nt = 0
	}

	if np == 0 && nt == 0 {
		return buffer.String()
	} else if np == 1 && nt == 0 && servicePorts[0].Name == "" {
		return buffer.String()
	} else {
		buffer.WriteString("|")
	}

	if np > 0 {
		ports := make([]string, np)
		for i := 0; i < np; i++ {
			ports[i] = servicePorts[i].Name
		}
		sort.Strings(ports)
		for i := 0; i < np; i++ {
			if i > 0 {
				buffer.WriteString(",")
			}
			buffer.WriteString(ports[i])
		}
	}

	if nt > 0 {
		buffer.WriteString("|")
		tags := make([]string, nt)
		for i := 0; i < nt; i++ {
			tags[i] = serviceTags[i].String()
		}
		sort.Strings(tags)
		for i := 0; i < nt; i++ {
			if i > 0 {
				buffer.WriteString(";")
			}
			buffer.WriteString(tags[i])
		}
	}
	return buffer.String()
}

// ParseServiceKey is the inverse of the Service.String() method
func ParseServiceKey(s string) (hostname string, ports PortList, tags TagsList) {
	parts := strings.Split(s, "|")
	hostname = parts[0]

	var names []string
	if len(parts) > 1 {
		names = strings.Split(parts[1], ",")
	} else {
		names = []string{""}
	}

	for _, name := range names {
		ports = append(ports, &Port{Name: name})
	}

	if len(parts) > 2 && len(parts[2]) > 0 {
		for _, tag := range strings.Split(parts[2], ";") {
			tags = append(tags, ParseTagString(tag))
		}
	}
	return
}

func (t Tags) String() string {
	labels := make([]string, 0)
	for k, v := range t {
		if len(v) > 0 {
			labels = append(labels, fmt.Sprintf("%s=%s", k, v))
		} else {
			labels = append(labels, k)
		}
	}
	sort.Strings(labels)

	var buffer bytes.Buffer
	var first = true
	for _, label := range labels {
		if !first {
			buffer.WriteString(",")
		} else {
			first = false
		}
		buffer.WriteString(label)
	}
	return buffer.String()
}

// ParseTagString extracts tags from a string
func ParseTagString(s string) Tags {
	tag := make(map[string]string)
	for _, pair := range strings.Split(s, ",") {
		kv := strings.Split(pair, "=")
		if len(kv) > 1 {
			tag[kv[0]] = kv[1]
		} else {
			tag[kv[0]] = ""
		}
	}
	return tag
}
<commit_msg>update istio service model<commit_after>// Copyright 2017 Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This file describes the abstract model of services (and their instances) as
// represented in Istio. This model is independent of the underlying platform
// (Kubernetes, Mesos, etc.). Platform specific adapters found populate the
// model object with various fields, from the metadata found in the platform.
// The platform independent proxy code uses the representation in the model to
// generate the configuration files for the Layer 7 proxy sidecar. The proxy
// code is specific to individual proxy implementations

package model

import (
	"bytes"
	"fmt"
	"sort"
	"strings"
)

// Service describes an Istio service (e.g., catalog.mystore.com:8080)
// Each service has a fully qualified domain name (FQDN) and one or more
// ports where the service is listening for connections. *Optionally*, a
// service can have a single load balancer/virtual IP address associated
// with it, such that the DNS queries for the FQDN resolves to the virtual
// IP address (a load balancer IP).
//
// E.g., in kubernetes, a service foo is associated with
// foo.default.svc.cluster.local hostname, has a virtual IP of 10.0.1.1 and
// listens on ports 80, 8080
type Service struct {
	// Hostname of the service, e.g. "catalog.mystore.com"
	Hostname string `json:"hostname"`

	// Address specifies the service IPv4 address of the load balancer
	Address string `json:"address,omitempty"`

	// Ports is the set of network ports where the service is listening for
	// connections
	Ports PortList `json:"ports,omitempty"`

	// ExternalName is only set for external services and holds the external
	// service DNS name.  External services are name-based solution to represent
	// external service instances as a service inside the cluster.
	ExternalName string `json:"external"`
}

// Port represents a network port where a service is listening for
// connections. The port should be annotated with the type of protocol
// used by the port.
type Port struct {
	// Name ascribes a human readable name for the port object. When a
	// service has multiple ports, the name field is mandatory
	Name string `json:"name,omitempty"`

	// Port number where the service can be reached. Does not necessarily
	// map to the corresponding port numbers for the instances behind the
	// service. See NetworkEndpoint definition below.
	Port int `json:"port"`

	// Protocol to be used for the port.
	Protocol Protocol `json:"protocol,omitempty"`
}

// PortList is a set of ports
type PortList []*Port

// Protocol defines network protocols for ports
type Protocol string

const (
	// ProtocolGRPC declares that the port carries gRPC traffic
	ProtocolGRPC Protocol = "GRPC"
	// ProtocolHTTPS declares that the port carries HTTPS traffic
	ProtocolHTTPS Protocol = "HTTPS"
	// ProtocolHTTP2 declares that the port carries HTTP/2 traffic
	ProtocolHTTP2 Protocol = "HTTP2"
	// ProtocolHTTP declares that the port carries HTTP/1.1 traffic.
	// Note that HTTP/1.0 or earlier may not be supported by the proxy.
	ProtocolHTTP Protocol = "HTTP"
	// ProtocolTCP declares the the port uses TCP.
	// This is the default protocol for a service port.
	ProtocolTCP Protocol = "TCP"
	// ProtocolUDP declares that the port uses UDP.
	// Note that UDP protocol is not currently supported by the proxy.
	ProtocolUDP Protocol = "UDP"
)

// NetworkEndpoint defines a network address (IP:port) associated with an instance of the
// service. A service has one or more instances each running in a
// container/VM/pod. If a service has multiple ports, then the same
// instance IP is expected to be listening on multiple ports (one per each
// service port). Note that the port associated with an instance does not
// have to be the same as the port associated with the service. Depending
// on the network setup (NAT, overlays), this could vary.
//
// For e.g., if catalog.mystore.com is accessible through port 80 and 8080,
// and it maps to an instance with IP 172.16.0.1, such that connections to
// port 80 are forwarded to port 55446, and connections to port 8080 are
// forwarded to port 33333,
//
// then internally, we have two two endpoint structs for the
// service catalog.mystore.com
//  --> 172.16.0.1:54546 (with ServicePort pointing to 80) and
//  --> 172.16.0.1:33333 (with ServicePort pointing to 8080)
type NetworkEndpoint struct {
	// Address of the network endpoint, typically an IPv4 address
	Address string `json:"ip_address,omitempty"`

	// Port number where this instance is listening for connections This
	// need not be the same as the port where the service is accessed.
	// e.g., catalog.mystore.com:8080 -> 172.16.0.1:55446
	Port int `json:"port"`

	// Port declaration from the service declaration This is the port for
	// the service associated with this instance (e.g.,
	// catalog.mystore.com)
	ServicePort *Port `json:"service_port"`
}

// Tags is a non empty set of arbitrary strings. Each version of a service can
// be differentiated by a unique set of tags associated with the version. These
// tags are assigned to all instances of a particular service version. For
// example, lets say catalog.mystore.com has 2 versions v1 and v2. v1 instances
// could have tags gitCommit=aeiou234, region=us-east, while v2 instances could
// have tags name=kittyCat,region=us-east.
type Tags map[string]string

// TagsList is a collection of tags used for comparing tags against a
// collection of tags
type TagsList []Tags

// ServiceInstance represents an individual instance of a specific version
// of a service. It binds a network endpoint (ip:port), the service
// description (which is oblivious to various versions) and a set of tags
// that describe the service version associated with this instance.
//
// The tags associated with a service instance are unique per a network endpoint.
// There is one well defined set of tags for each service instance network endpoint.
//
// For example, the set of service instances associated with catalog.mystore.com
// are modeled like this
//      --> NetworkEndpoint(172.16.0.1:8888), Service(catalog.myservice.com), Tag(foo=bar)
//      --> NetworkEndpoint(172.16.0.2:8888), Service(catalog.myservice.com), Tag(foo=bar)
//      --> NetworkEndpoint(172.16.0.3:8888), Service(catalog.myservice.com), Tag(kitty=cat)
//      --> NetworkEndpoint(172.16.0.4:8888), Service(catalog.myservice.com), Tag(kitty=cat)
type ServiceInstance struct {
	Endpoint NetworkEndpoint `json:"endpoint,omitempty"`
	Service  *Service        `json:"service,omitempty"`
	Tags     Tags            `json:"tags,omitempty"`
}

// ServiceDiscovery enumerates Istio service instances.
type ServiceDiscovery interface {
	// Services list declarations of all services in the system
	Services() []*Service

	// GetService retrieves a service by host name if it exists
	GetService(hostname string) (*Service, bool)

	// Instances retrieves instances for a service and its ports that match
	// any of the supplied tags. All instances match an empty tag list.
	//
	// For example, consider the example of catalog.mystore.com as described in NetworkEndpoints
	// Instances(catalog.myservice.com, 80) ->
	//      --> NetworkEndpoint(172.16.0.1:8888), Service(catalog.myservice.com), Tag(foo=bar)
	//      --> NetworkEndpoint(172.16.0.2:8888), Service(catalog.myservice.com), Tag(foo=bar)
	//      --> NetworkEndpoint(172.16.0.3:8888), Service(catalog.myservice.com), Tag(kitty=cat)
	//      --> NetworkEndpoint(172.16.0.4:8888), Service(catalog.myservice.com), Tag(kitty=cat)
	//
	// Calling Instances with specific tags returns a trimmed list.
	// e.g., Instances(catalog.myservice.com, 80, foo=bar) ->
	//      --> NetworkEndpoint(172.16.0.1:8888), Service(catalog.myservice.com), Tag(foo=bar)
	//      --> NetworkEndpoint(172.16.0.2:8888), Service(catalog.myservice.com), Tag(foo=bar)
	//
	// Similar concepts apply for calling this function with a specific
	// port, hostname and tags.
	Instances(hostname string, ports []string, tags TagsList) []*ServiceInstance

	// HostInstances lists service instances for a given set of IPv4 addresses.
	HostInstances(addrs map[string]bool) []*ServiceInstance
}

// ServiceAccounts exposes Istio service accounts
type ServiceAccounts interface {
	// GetIstioServiceAccounts returns a list of service accounts looked up from
	// the specified service hostname and ports.
	GetIstioServiceAccounts(hostname string, ports []string) []string
}

// SubsetOf is true if the tag has identical values for the keys
func (t Tags) SubsetOf(that Tags) bool {
	for k, v := range t {
		if that[k] != v {
			return false
		}
	}
	return true
}

// Equals returns true if the tags are identical
func (t Tags) Equals(that Tags) bool {
	if t == nil {
		return that == nil
	}
	if that == nil {
		return t == nil
	}
	return t.SubsetOf(that) && that.SubsetOf(t)
}

// HasSubsetOf returns true if the input tags are a super set of one tags in a
// collection or if the tag collection is empty
func (tags TagsList) HasSubsetOf(that Tags) bool {
	if len(tags) == 0 {
		return true
	}
	for _, tag := range tags {
		if tag.SubsetOf(that) {
			return true
		}
	}
	return false
}

// GetNames returns port names
func (ports PortList) GetNames() []string {
	names := make([]string, 0, len(ports))
	for _, port := range ports {
		names = append(names, port.Name)
	}
	return names
}

// Get retrieves a port declaration by name
func (ports PortList) Get(name string) (*Port, bool) {
	for _, port := range ports {
		if port.Name == name {
			return port, true
		}
	}
	return nil, false
}

// GetByPort retrieves a port declaration by port value
func (ports PortList) GetByPort(num int) (*Port, bool) {
	for _, port := range ports {
		if port.Port == num {
			return port, true
		}
	}
	return nil, false
}

// External predicate checks whether the service is external
func (s *Service) External() bool {
	return s.ExternalName != ""
}

// Key generates a unique string referencing service instances for a given port and tags.
// The separator character must be exclusive to the regular expressions allowed in the
// service declaration.
func (s *Service) Key(port *Port, tag Tags) string {
	// TODO: check port is non nil and membership of port in service
	return ServiceKey(s.Hostname, PortList{port}, TagsList{tag})
}

// ServiceKey generates a service key for a collection of ports and tags
func ServiceKey(hostname string, servicePorts PortList, serviceTags TagsList) string {
	// example: name.namespace|http|env=prod;env=test,version=my-v1
	var buffer bytes.Buffer
	buffer.WriteString(hostname)
	np := len(servicePorts)
	nt := len(serviceTags)

	if nt == 1 && serviceTags[0] == nil {
		nt = 0
	}

	if np == 0 && nt == 0 {
		return buffer.String()
	} else if np == 1 && nt == 0 && servicePorts[0].Name == "" {
		return buffer.String()
	} else {
		buffer.WriteString("|")
	}

	if np > 0 {
		ports := make([]string, np)
		for i := 0; i < np; i++ {
			ports[i] = servicePorts[i].Name
		}
		sort.Strings(ports)
		for i := 0; i < np; i++ {
			if i > 0 {
				buffer.WriteString(",")
			}
			buffer.WriteString(ports[i])
		}
	}

	if nt > 0 {
		buffer.WriteString("|")
		tags := make([]string, nt)
		for i := 0; i < nt; i++ {
			tags[i] = serviceTags[i].String()
		}
		sort.Strings(tags)
		for i := 0; i < nt; i++ {
			if i > 0 {
				buffer.WriteString(";")
			}
			buffer.WriteString(tags[i])
		}
	}
	return buffer.String()
}

// ParseServiceKey is the inverse of the Service.String() method
func ParseServiceKey(s string) (hostname string, ports PortList, tags TagsList) {
	parts := strings.Split(s, "|")
	hostname = parts[0]

	var names []string
	if len(parts) > 1 {
		names = strings.Split(parts[1], ",")
	} else {
		names = []string{""}
	}

	for _, name := range names {
		ports = append(ports, &Port{Name: name})
	}

	if len(parts) > 2 && len(parts[2]) > 0 {
		for _, tag := range strings.Split(parts[2], ";") {
			tags = append(tags, ParseTagString(tag))
		}
	}
	return
}

func (t Tags) String() string {
	labels := make([]string, 0, len(t))
	for k, v := range t {
		if len(v) > 0 {
			labels = append(labels, fmt.Sprintf("%s=%s", k, v))
		} else {
			labels = append(labels, k)
		}
	}
	sort.Strings(labels)

	var buffer bytes.Buffer
	var first = true
	for _, label := range labels {
		if !first {
			buffer.WriteString(",")
		} else {
			first = false
		}
		buffer.WriteString(label)
	}
	return buffer.String()
}

// ParseTagString extracts tags from a string
func ParseTagString(s string) Tags {
	pairs := strings.Split(s, ",")
	tag := make(map[string]string, len(pairs))

	for _, pair := range pairs {
		kv := strings.Split(pair, "=")
		if len(kv) > 1 {
			tag[kv[0]] = kv[1]
		} else {
			tag[kv[0]] = ""
		}
	}
	return tag
}
<|endoftext|>


<commit_before>package executor

import (
	"fmt"
	"reflect"
	"sync"

	"github.com/tallstreet/graphql"
	"github.com/tallstreet/graphql/schema"
	"golang.org/x/net/context"
)

type Executor struct {
	schema *schema.Schema
}

func New(schema *schema.Schema) *Executor {
	return &Executor{
		schema: schema,
	}
}

func (e *Executor) HandleOperation(ctx context.Context, o *graphql.Operation) (interface{}, error) {
	rootSelections := o.SelectionSet
	rootFields := e.schema.RootFields()
	result := make(map[string]interface{})

	for _, selection := range rootSelections {
		rootFieldHandler, ok := rootFields[selection.Field.Name]
		if !ok {
			return nil, fmt.Errorf("Root field '%s' is not registered", selection.Field.Name)
		}
		partial, err := rootFieldHandler.Func(ctx, e, selection.Field)
		if err != nil {
			return nil, err
		}
		resolved, err := e.Resolve(ctx, partial, selection.Field)
		if err != nil {
			return nil, err
		}
		result[selection.Field.Alias] = resolved
	}
	return result, nil
}

func isSlice(value interface{}) bool {
	if value == nil {
		return false
	}
	return reflect.TypeOf(value).Kind() == reflect.Slice
}

type fieldResult struct {
	FieldName string
	Value     interface{}
	Err       error
}

func (e *Executor) findFields(selectionSet graphql.SelectionSet) ([]*graphql.Field) {

	fields := []*graphql.Field{}
	for _, selection := range selectionSet {
		if selection.InlineFragment != nil {
			childFields := e.findFields(selection.InlineFragment.SelectionSet)
			fields = append(fields, childFields...)
		}

		if selection.Field != nil {
			fields = append(fields, selection.Field)
		}
	}
	return fields
}

func (e *Executor) Resolve(ctx context.Context, partial interface{}, field *graphql.Field) (interface{}, error) {
	if partial != nil && isSlice(partial) {
		return e.resolveSlice(ctx, partial, field)
	}
	graphQLValue, ok := partial.(schema.GraphQLType)
	// if we have a scalar we're done
	if !ok {
		//log.Printf("returning scalar %T: %v\n", partial, partial)
		return partial, nil
	}
	// check against returning object as non-leaf
	if len(field.SelectionSet) == 0 {
		return nil, fmt.Errorf("Cannot return a '%T' as a leaf", graphQLValue)
	}

	fields := e.findFields(field.SelectionSet)

	result := map[string]interface{}{}
	typeInfo := schema.WithIntrospectionField(graphQLValue.GraphQLTypeInfo())
	results := make(chan fieldResult)
	wg := sync.WaitGroup{}

	for _, selection := range fields {
		fieldName := selection.Name
		fieldHandler, ok := typeInfo.Fields[fieldName]
		if !ok {
			return nil, fmt.Errorf("No handler for field '%s' on type '%T'", fieldName, graphQLValue)
		}
		wg.Add(1)
		go func(selection *graphql.Field) {
			defer wg.Done()
			partial, err := fieldHandler.Func(ctx, e, selection)
			if err != nil {
				results <- fieldResult{Err: err}
				return
			}
			resolved, err := e.Resolve(ctx, partial, selection)
			if err != nil {
				results <- fieldResult{Err: err}
				return
			}
			if selection.Alias != "" {
				fieldName = selection.Alias
			}
			results <- fieldResult{
				FieldName: fieldName, Value: resolved, Err: err,
			}
		}(selection)
	}
	go func() {
		wg.Wait()
		close(results)
	}()
	for r := range results {
		if r.Err != nil {
			return nil, r.Err
		}
		result[r.FieldName] = r.Value
	}
	return result, nil
}

func (e *Executor) resolveSlice(ctx context.Context, partials interface{}, field *graphql.Field) (interface{}, error) {
	v := reflect.ValueOf(partials)
	results := make([]interface{}, 0, v.Len())
	resChan := make(chan fieldResult)
	wg := sync.WaitGroup{}
	for i := 0; i < v.Len(); i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			result, err := e.Resolve(ctx, v.Index(i).Interface(), field)
			resChan <- fieldResult{Value: result, Err: err}
		}(i)
	}
	go func() {
		wg.Wait()
		close(resChan)
	}()
	for result := range resChan {
		if result.Err != nil {
			return nil, result.Err
		}
		results = append(results, result.Value)
	}
	return results, nil
}
<commit_msg> Ability to merge nodes results down so they get the maximum set of data<commit_after>package executor

import (
	"fmt"
	"reflect"
	"sync"

	"github.com/tallstreet/graphql"
	"github.com/tallstreet/graphql/schema"
	"golang.org/x/net/context"
)

type Executor struct {
	schema *schema.Schema
}

func New(schema *schema.Schema) *Executor {
	return &Executor{
		schema: schema,
	}
}

func (e *Executor) HandleOperation(ctx context.Context, o *graphql.Operation) (interface{}, error) {
	rootSelections := o.SelectionSet
	rootFields := e.schema.RootFields()
	result := make(map[string]interface{})

	for _, selection := range rootSelections {
		rootFieldHandler, ok := rootFields[selection.Field.Name]
		if !ok {
			return nil, fmt.Errorf("Root field '%s' is not registered", selection.Field.Name)
		}
		partial, err := rootFieldHandler.Func(ctx, e, selection.Field)
		if err != nil {
			return nil, err
		}
		resolved, err := e.Resolve(ctx, partial, selection.Field)
		if err != nil {
			return nil, err
		}
		result[selection.Field.Alias] = resolved
	}
	return result, nil
}

func isSlice(value interface{}) bool {
	if value == nil {
		return false
	}
	return reflect.TypeOf(value).Kind() == reflect.Slice
}

type fieldResult struct {
	FieldName string
	Value     interface{}
	Err       error
}

func (e *Executor) findFields(selectionSet graphql.SelectionSet) []*graphql.Field {

	fields := []*graphql.Field{}
	for _, selection := range selectionSet {
		if selection.InlineFragment != nil {
			childFields := e.findFields(selection.InlineFragment.SelectionSet)
			fields = append(fields, childFields...)
		}

		if selection.Field != nil {
			fields = append(fields, selection.Field)
		}
	}
	return fields
}

func (e *Executor) mergeValues(oldValue interface{}, newValue interface{}) interface{} {
	if isSlice(oldValue) {
		oldValueSlice := oldValue.([]interface{})
		newValueSlice := newValue.([]interface{})
		newSlice := make([]interface{}, 0, len(oldValueSlice))
		for k := range oldValueSlice {
			newSlice = append(newSlice, e.mergeValues(oldValueSlice[k], newValueSlice[k]))
		}
		return newSlice
	}
	if reflect.TypeOf(oldValue).Kind() == reflect.Map {
		oldValueMap := oldValue.(map[string]interface{})
		newValueMap := newValue.(map[string]interface{})
		newMap := newValueMap
		for k := range oldValueMap {
			if oldValueMap[k] != nil && newValueMap[k] != nil {
				newMap[k] = e.mergeValues(oldValueMap[k], newValueMap[k])
			} else {
				newMap[k] = oldValueMap[k]
			}
		}
		return newMap

	}
	if oldValue != nil {
		return oldValue
	}
	if newValue != nil {
		return newValue
	}
	return nil
}

func (e *Executor) Resolve(ctx context.Context, partial interface{}, field *graphql.Field) (interface{}, error) {
	if partial != nil && isSlice(partial) {
		return e.resolveSlice(ctx, partial, field)
	}
	graphQLValue, ok := partial.(schema.GraphQLType)
	// if we have a scalar we're done
	if !ok {
		//log.Printf("returning scalar %T: %v\n", partial, partial)
		return partial, nil
	}
	// check against returning object as non-leaf
	if len(field.SelectionSet) == 0 {
		return nil, fmt.Errorf("Cannot return a '%T' as a leaf", graphQLValue)
	}

	fields := e.findFields(field.SelectionSet)

	result := map[string]interface{}{}
	typeInfo := schema.WithIntrospectionField(graphQLValue.GraphQLTypeInfo())
	results := make(chan fieldResult)
	wg := sync.WaitGroup{}

	for _, selection := range fields {
		fieldName := selection.Name
		fieldHandler, ok := typeInfo.Fields[fieldName]
		if !ok {
			return nil, fmt.Errorf("No handler for field '%s' on type '%T'", fieldName, graphQLValue)
		}
		wg.Add(1)
		go func(selection *graphql.Field) {
			defer wg.Done()
			partial, err := fieldHandler.Func(ctx, e, selection)
			if err != nil {
				results <- fieldResult{Err: err}
				return
			}
			resolved, err := e.Resolve(ctx, partial, selection)
			if err != nil {
				results <- fieldResult{Err: err}
				return
			}
			if selection.Alias != "" {
				fieldName = selection.Alias
			}
			results <- fieldResult{
				FieldName: fieldName, Value: resolved, Err: err,
			}
		}(selection)
	}
	go func() {
		wg.Wait()
		close(results)
	}()
	for r := range results {
		if r.Err != nil {
			return nil, r.Err
		}
		if result[r.FieldName] != nil {
			result[r.FieldName] = e.mergeValues(result[r.FieldName], r.Value)
		} else {
			result[r.FieldName] = r.Value
		}
	}
	return result, nil
}

func (e *Executor) resolveSlice(ctx context.Context, partials interface{}, field *graphql.Field) (interface{}, error) {
	v := reflect.ValueOf(partials)
	results := make([]interface{}, 0, v.Len())
	resChan := make(chan fieldResult)
	wg := sync.WaitGroup{}
	for i := 0; i < v.Len(); i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			result, err := e.Resolve(ctx, v.Index(i).Interface(), field)
			resChan <- fieldResult{Value: result, Err: err}
		}(i)
	}
	go func() {
		wg.Wait()
		close(resChan)
	}()
	for result := range resChan {
		if result.Err != nil {
			return nil, result.Err
		}
		results = append(results, result.Value)
	}
	return results, nil
}
<|endoftext|>


<commit_before>package mongo

import (
	"labix.org/v2/mgo/bson"
	"log"
)

//for debug
//return all collection data
//
// this method is not userd web app
// becouse return is interface(map)
// and map is not defined  order
func GetAllColData(collectionName string) (*[]interface{}, error) {
	db, session := mongoInit()
	col := db.C(collectionName)
	defer session.Close()

	var results []interface{}
	err := col.Find(nil).All(&results)
	if err != nil {
		return nil, err
	}
	return &results, nil
}

func SetAllUserCol() {
	db, session := mongoInit()
	col := db.C("user")
	defer session.Close()
	usersCol := []UserCol{}
	if err = col.Find(nil).All(&usersCol); err != nil {
		log.Println("can not find user from mongo", err)
	}

	for _, userCol := range usersCol {
		users[userCol.UserId] = userCol
	}
}

func SetUserCol(userIds []string) {
	db, session := mongoInit()
	col := db.C("user")
	defer session.Close()

	for _, userId := range userIds {

		userCol := UserCol{}
		findQuery := bson.M{"userId": userId}

		if err = col.Find(findQuery).One(&userCol); err != nil {
			log.Println("can not find user from mongo", err)
		}

		users[userId] = userCol
	}
}

func SetAllPlayerCol() {
	db, session := mongoInit()
	col := db.C("player")
	defer session.Close()
	playersCol := []PlayerCol{}
	if err = col.Find(nil).All(&playersCol); err != nil {
		log.Println("can not find player from mongo", err)
	}

	for _, playerCol := range playersCol {
		players[playerCol.UserId] = playerCol
	}
}

func SetPlayerCol(userIds []string) {
	db, session := mongoInit()
	col := db.C("player")
	defer session.Close()

	for _, userId := range userIds {

		playerCol := PlayerCol{}
		findQuery := bson.M{"userid": userId}

		if err = col.Find(findQuery).One(&playerCol); err != nil {
			log.Println("can not find player from mongo", err)
		}

		players[userId] = playerCol
	}
}

func SetAllFieldCol() {
	db, session := mongoInit()
	col := db.C("field")
	defer session.Close()
	fieldsCol := []FieldCol{}
	if err = col.Find(nil).All(&fieldsCol); err != nil {
		log.Println("can not find field from mongo", err)
	}

	for _, fieldCol := range fieldsCol {
		fields[fieldCol.Hole] = fieldCol
	}
}

func SetFieldCol(hole int) {
	db, session := mongoInit()
	col := db.C("field")
	defer session.Close()

	fieldCol := FieldCol{}
	findQuery := bson.M{"hole": hole}

	if err = col.Find(findQuery).One(&fieldCol); err != nil {
		log.Println("can not find field from mongo", err)
	}

	fields[hole] = fieldCol
}

func SetAllTeamCol() {
	db, session := mongoInit()
	col := db.C("team")
	defer session.Close()
	teamsCol := []TeamCol{}
	if err = col.Find(nil).All(&teamsCol); err != nil {
		log.Println("can not find team from mongo", err)
	}

	for _, teamCol := range teamsCol {
		teams[teamCol.Name] = teamCol
	}
}

func SetTeamCol(teamName string) {
	db, session := mongoInit()
	col := db.C("team")
	defer session.Close()

	teamCol := TeamCol{}
	findQuery := bson.M{"name": teamName}

	if err = col.Find(findQuery).One(&teamCol); err != nil {
		log.Println("can not find team from mongo", err)
	}

	teams[teamName] = teamCol
}

func SetAllThreadCol() {
	db, session := mongoInit()
	col := db.C("thread")
	defer session.Close()
	threadsCol := []ThreadCol{}
	if err = col.Find(nil).All(&threadsCol); err != nil {
		log.Println("can not find thread from mongo", err)
	}

	for _, threadCol := range threadsCol {
		threads[threadCol.ThreadId] = threadCol
	}
}

func SetThreadCol(threadId string) {
	db, session := mongoInit()
	col := db.C("thread")
	defer session.Close()

	threadCol := ThreadCol{}
	findQuery := bson.M{"threadId": threadId}

	if err = col.Find(findQuery).One(&threadCol); err != nil {
		log.Println("can not find thread from mongo", err)
	}

	threads[threadId] = threadCol
}
<commit_msg>change lower camel to lower only .<commit_after>package mongo

import (
	"labix.org/v2/mgo/bson"
	"log"
)

//for debug
//return all collection data
//
// this method is not userd web app
// becouse return is interface(map)
// and map is not defined  order
func GetAllColData(collectionName string) (*[]interface{}, error) {
	db, session := mongoInit()
	col := db.C(collectionName)
	defer session.Close()

	var results []interface{}
	err := col.Find(nil).All(&results)
	if err != nil {
		return nil, err
	}
	return &results, nil
}

func SetAllUserCol() {
	db, session := mongoInit()
	col := db.C("user")
	defer session.Close()
	usersCol := []UserCol{}
	if err = col.Find(nil).All(&usersCol); err != nil {
		log.Println("can not find user from mongo", err)
	}

	for _, userCol := range usersCol {
		users[userCol.UserId] = userCol
	}
}

func SetUserCol(userIds []string) {
	db, session := mongoInit()
	col := db.C("user")
	defer session.Close()

	for _, userId := range userIds {

		userCol := UserCol{}
		findQuery := bson.M{"userid": userId}

		if err = col.Find(findQuery).One(&userCol); err != nil {
			log.Println("can not find user from mongo", err)
		}

		users[userId] = userCol
	}
}

func SetAllPlayerCol() {
	db, session := mongoInit()
	col := db.C("player")
	defer session.Close()
	playersCol := []PlayerCol{}
	if err = col.Find(nil).All(&playersCol); err != nil {
		log.Println("can not find player from mongo", err)
	}

	for _, playerCol := range playersCol {
		players[playerCol.UserId] = playerCol
	}
}

func SetPlayerCol(userIds []string) {
	db, session := mongoInit()
	col := db.C("player")
	defer session.Close()

	for _, userId := range userIds {

		playerCol := PlayerCol{}
		findQuery := bson.M{"userid": userId}

		if err = col.Find(findQuery).One(&playerCol); err != nil {
			log.Println("can not find player from mongo", err)
		}

		players[userId] = playerCol
	}
}

func SetAllFieldCol() {
	db, session := mongoInit()
	col := db.C("field")
	defer session.Close()
	fieldsCol := []FieldCol{}
	if err = col.Find(nil).All(&fieldsCol); err != nil {
		log.Println("can not find field from mongo", err)
	}

	for _, fieldCol := range fieldsCol {
		fields[fieldCol.Hole] = fieldCol
	}
}

func SetFieldCol(hole int) {
	db, session := mongoInit()
	col := db.C("field")
	defer session.Close()

	fieldCol := FieldCol{}
	findQuery := bson.M{"hole": hole}

	if err = col.Find(findQuery).One(&fieldCol); err != nil {
		log.Println("can not find field from mongo", err)
	}

	fields[hole] = fieldCol
}

func SetAllTeamCol() {
	db, session := mongoInit()
	col := db.C("team")
	defer session.Close()
	teamsCol := []TeamCol{}
	if err = col.Find(nil).All(&teamsCol); err != nil {
		log.Println("can not find team from mongo", err)
	}

	for _, teamCol := range teamsCol {
		teams[teamCol.Name] = teamCol
	}
}

func SetTeamCol(teamName string) {
	db, session := mongoInit()
	col := db.C("team")
	defer session.Close()

	teamCol := TeamCol{}
	findQuery := bson.M{"name": teamName}

	if err = col.Find(findQuery).One(&teamCol); err != nil {
		log.Println("can not find team from mongo", err)
	}

	teams[teamName] = teamCol
}

func SetAllThreadCol() {
	db, session := mongoInit()
	col := db.C("thread")
	defer session.Close()
	threadsCol := []ThreadCol{}
	if err = col.Find(nil).All(&threadsCol); err != nil {
		log.Println("can not find thread from mongo", err)
	}

	for _, threadCol := range threadsCol {
		threads[threadCol.ThreadId] = threadCol
	}
}

func SetThreadCol(threadId string) {
	db, session := mongoInit()
	col := db.C("thread")
	defer session.Close()

	threadCol := ThreadCol{}
	findQuery := bson.M{"threadid": threadId}

	if err = col.Find(findQuery).One(&threadCol); err != nil {
		log.Println("can not find thread from mongo", err)
	}

	threads[threadId] = threadCol
}
<|endoftext|>


<commit_before>package build

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"neon/util"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"unicode/utf8"
)

type Build struct {
	File    string
	Dir     string
	Here    string
	Name    string
	Default []string
	Doc     string
	Context *Context
	Targets map[string]*Target
	Debug   bool
}

func NewBuild(file string, debug bool) (*Build, error) {
	build := &Build{}
	build.Debug = debug
	build.Log("Loading build file '%s'", file)
	source, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, fmt.Errorf("loading build file '%s': %v", file, err)
	}
	build.Log("Parsing build file")
	var object util.Object
	err = yaml.Unmarshal(source, &object)
	if err != nil {
		return nil, fmt.Errorf("build must be a YAML map with string keys")
	}
	build.Log("Build structure: %#v", object)
	build.Log("Reading build first level fields")
	err = object.CheckFields([]string{"name", "default", "doc", "properties",
		"environment", "targets"})
	if err != nil {
		return nil, err
	}
	str, err := object.GetString("name")
	if err == nil {
		build.Name = str
	}
	list, err := object.GetListStringsOrString("default")
	if err == nil {
		build.Default = list
	}
	str, err = object.GetString("doc")
	if err == nil {
		build.Doc = str
	}
	path, err := filepath.Abs(file)
	if err != nil {
		return nil, fmt.Errorf("getting build file path: %v", err)
	}
	build.File = path
	build.Dir = filepath.Dir(path)
	here, err := os.Getwd()
	if err != nil {
		return nil, fmt.Errorf("getting current directory: %v", err)
	}
	build.Here = here
	properties, err := object.GetObject("properties")
	if err != nil {
		if err.Error() == "field 'properties' not found" {
			properties = make(map[string]interface{})
		} else {
			return nil, err
		}
	}
	environment, err := object.GetObject("environment")
	if err != nil {
		if err.Error() == "field 'environment' not found" {
			environment = make(map[string]interface{})
		} else {
			return nil, err
		}
	}
	context, err := NewContext(build, properties, environment)
	if err != nil {
		return nil, err
	}
	build.Context = context
	targets, err := object.GetObject("targets")
	if err != nil {
		if err.Error() == "field 'targets' not found" {
			properties = make(map[string]interface{})
		} else {
			return nil, err
		}
	}
	build.Targets = make(map[string]*Target)
	for name, _ := range targets {
		object, err := targets.GetObject(name)
		if err != nil {
			return nil, err
		}
		target, err := NewTarget(build, name, object)
		if err != nil {
			return nil, err
		}
		build.Targets[name] = target
	}
	return build, nil
}

func (build *Build) Run(targets []string) error {
	if len(targets) == 0 {
		if len(build.Default) == 0 {
			return fmt.Errorf("no default target")
		}
		return build.Run(build.Default)
	} else {
		for _, name := range targets {
			target, ok := build.Targets[name]
			if !ok {
				return fmt.Errorf("target '%s' not found", name)
			}
			err := target.Run()
			if err != nil {
				return err
			}
		}
		return nil
	}
}

func (build *Build) Help() error {
	newLine := false
	// print build documentation
	if build.Doc != "" {
		fmt.Println(build.Doc)
		newLine = true
	}
	// print build properties
	length := 0
	for _, name := range build.Context.Properties {
		if utf8.RuneCountInString(name) > length {
			length = utf8.RuneCountInString(name)
		}
	}
	if len(build.Context.Properties) > 0 {
		if newLine {
			fmt.Println()
		}
		fmt.Println("Properties:")
		for _, name := range build.Context.Properties {
			value, err := build.Context.GetProperty(name)
			if err != nil {
				return fmt.Errorf("getting property '%s': %v", name, err)
			}
			valueStr, err := PropertyToString(value, true)
			if err != nil {
				return fmt.Errorf("formatting property '%s': %v", name, err)
			}
			util.PrintTargetHelp(name, valueStr, []string{}, length)
		}
		newLine = true
	}
	// print build environment
	length = 0
	var names []string
	for name, _ := range build.Context.Environment {
		if utf8.RuneCountInString(name) > length {
			length = utf8.RuneCountInString(name)
		}
		names = append(names, name)
	}
	sort.Strings(names)
	if len(build.Context.Environment) > 0 {
		if newLine {
			fmt.Println()
		}
		fmt.Println("Environment:")
		for _, name := range names {
			value := "\"" + build.Context.Environment[name] + "\""
			util.PrintTargetHelp(name, value, []string{}, length)
		}
		newLine = true
	}
	// print targets documentation
	length = 0
	var targets []string
	for name, _ := range build.Targets {
		if utf8.RuneCountInString(name) > length {
			length = utf8.RuneCountInString(name)
		}
		targets = append(targets, name)
	}
	sort.Strings(targets)
	if len(targets) > 0 {
		if newLine {
			fmt.Println()
		}
		fmt.Println("Targets:")
		for _, name := range targets {
			target := build.Targets[name]
			util.PrintTargetHelp(name, target.Doc, target.Depends, length)
		}
	}
	return nil
}

func (build *Build) PrintTargets() {
	var targets []string
	for name, _ := range build.Targets {
		targets = append(targets, name)
	}
	sort.Strings(targets)
	fmt.Println(strings.Join(targets, " "))
}

func (build *Build) PrintTasks() {
	var tasks []string
	for name, _ := range TaskMap {
		tasks = append(tasks, name)
	}
	sort.Strings(tasks)
	fmt.Println(strings.Join(tasks, " "))
}

func (build *Build) PrintHelpTask(task string) {
	descriptor, found := TaskMap["task"]
	if found {
		fmt.Println(descriptor.Help)
	} else {
		fmt.Printf("Task '%s' was not found\n", task)
	}
}

func (build *Build) PrintBuiltins() {
	var builtins []string
	for name, _ := range BuiltinMap {
		builtins = append(builtins, name)
	}
	sort.Strings(builtins)
	fmt.Println(strings.Join(builtins, " "))
}

func (build *Build) PrintHelpBuiltin(builtin string) {
	descriptor, found := BuiltinMap[builtin]
	if found {
		fmt.Println(descriptor.Help)
	} else {
		fmt.Printf("Builtin '%s' was not found\n", builtin)
	}
}

func (build *Build) Log(message string, args ...interface{}) {
	if build.Debug {
		fmt.Println(fmt.Sprintf(message, args...))
	}
}
<commit_msg>Fixed task option<commit_after>package build

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"neon/util"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"unicode/utf8"
)

type Build struct {
	File    string
	Dir     string
	Here    string
	Name    string
	Default []string
	Doc     string
	Context *Context
	Targets map[string]*Target
	Debug   bool
}

func NewBuild(file string, debug bool) (*Build, error) {
	build := &Build{}
	build.Debug = debug
	build.Log("Loading build file '%s'", file)
	source, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, fmt.Errorf("loading build file '%s': %v", file, err)
	}
	build.Log("Parsing build file")
	var object util.Object
	err = yaml.Unmarshal(source, &object)
	if err != nil {
		return nil, fmt.Errorf("build must be a YAML map with string keys")
	}
	build.Log("Build structure: %#v", object)
	build.Log("Reading build first level fields")
	err = object.CheckFields([]string{"name", "default", "doc", "properties",
		"environment", "targets"})
	if err != nil {
		return nil, err
	}
	str, err := object.GetString("name")
	if err == nil {
		build.Name = str
	}
	list, err := object.GetListStringsOrString("default")
	if err == nil {
		build.Default = list
	}
	str, err = object.GetString("doc")
	if err == nil {
		build.Doc = str
	}
	path, err := filepath.Abs(file)
	if err != nil {
		return nil, fmt.Errorf("getting build file path: %v", err)
	}
	build.File = path
	build.Dir = filepath.Dir(path)
	here, err := os.Getwd()
	if err != nil {
		return nil, fmt.Errorf("getting current directory: %v", err)
	}
	build.Here = here
	properties, err := object.GetObject("properties")
	if err != nil {
		if err.Error() == "field 'properties' not found" {
			properties = make(map[string]interface{})
		} else {
			return nil, err
		}
	}
	environment, err := object.GetObject("environment")
	if err != nil {
		if err.Error() == "field 'environment' not found" {
			environment = make(map[string]interface{})
		} else {
			return nil, err
		}
	}
	context, err := NewContext(build, properties, environment)
	if err != nil {
		return nil, err
	}
	build.Context = context
	targets, err := object.GetObject("targets")
	if err != nil {
		if err.Error() == "field 'targets' not found" {
			properties = make(map[string]interface{})
		} else {
			return nil, err
		}
	}
	build.Targets = make(map[string]*Target)
	for name, _ := range targets {
		object, err := targets.GetObject(name)
		if err != nil {
			return nil, err
		}
		target, err := NewTarget(build, name, object)
		if err != nil {
			return nil, err
		}
		build.Targets[name] = target
	}
	return build, nil
}

func (build *Build) Run(targets []string) error {
	if len(targets) == 0 {
		if len(build.Default) == 0 {
			return fmt.Errorf("no default target")
		}
		return build.Run(build.Default)
	} else {
		for _, name := range targets {
			target, ok := build.Targets[name]
			if !ok {
				return fmt.Errorf("target '%s' not found", name)
			}
			err := target.Run()
			if err != nil {
				return err
			}
		}
		return nil
	}
}

func (build *Build) Help() error {
	newLine := false
	// print build documentation
	if build.Doc != "" {
		fmt.Println(build.Doc)
		newLine = true
	}
	// print build properties
	length := 0
	for _, name := range build.Context.Properties {
		if utf8.RuneCountInString(name) > length {
			length = utf8.RuneCountInString(name)
		}
	}
	if len(build.Context.Properties) > 0 {
		if newLine {
			fmt.Println()
		}
		fmt.Println("Properties:")
		for _, name := range build.Context.Properties {
			value, err := build.Context.GetProperty(name)
			if err != nil {
				return fmt.Errorf("getting property '%s': %v", name, err)
			}
			valueStr, err := PropertyToString(value, true)
			if err != nil {
				return fmt.Errorf("formatting property '%s': %v", name, err)
			}
			util.PrintTargetHelp(name, valueStr, []string{}, length)
		}
		newLine = true
	}
	// print build environment
	length = 0
	var names []string
	for name, _ := range build.Context.Environment {
		if utf8.RuneCountInString(name) > length {
			length = utf8.RuneCountInString(name)
		}
		names = append(names, name)
	}
	sort.Strings(names)
	if len(build.Context.Environment) > 0 {
		if newLine {
			fmt.Println()
		}
		fmt.Println("Environment:")
		for _, name := range names {
			value := "\"" + build.Context.Environment[name] + "\""
			util.PrintTargetHelp(name, value, []string{}, length)
		}
		newLine = true
	}
	// print targets documentation
	length = 0
	var targets []string
	for name, _ := range build.Targets {
		if utf8.RuneCountInString(name) > length {
			length = utf8.RuneCountInString(name)
		}
		targets = append(targets, name)
	}
	sort.Strings(targets)
	if len(targets) > 0 {
		if newLine {
			fmt.Println()
		}
		fmt.Println("Targets:")
		for _, name := range targets {
			target := build.Targets[name]
			util.PrintTargetHelp(name, target.Doc, target.Depends, length)
		}
	}
	return nil
}

func (build *Build) PrintTargets() {
	var targets []string
	for name, _ := range build.Targets {
		targets = append(targets, name)
	}
	sort.Strings(targets)
	fmt.Println(strings.Join(targets, " "))
}

func (build *Build) PrintTasks() {
	var tasks []string
	for name, _ := range TaskMap {
		tasks = append(tasks, name)
	}
	sort.Strings(tasks)
	fmt.Println(strings.Join(tasks, " "))
}

func (build *Build) PrintHelpTask(task string) {
	descriptor, found := TaskMap[task]
	if found {
		fmt.Println(descriptor.Help)
	} else {
		fmt.Printf("Task '%s' was not found\n", task)
	}
}

func (build *Build) PrintBuiltins() {
	var builtins []string
	for name, _ := range BuiltinMap {
		builtins = append(builtins, name)
	}
	sort.Strings(builtins)
	fmt.Println(strings.Join(builtins, " "))
}

func (build *Build) PrintHelpBuiltin(builtin string) {
	descriptor, found := BuiltinMap[builtin]
	if found {
		fmt.Println(descriptor.Help)
	} else {
		fmt.Printf("Builtin '%s' was not found\n", builtin)
	}
}

func (build *Build) Log(message string, args ...interface{}) {
	if build.Debug {
		fmt.Println(fmt.Sprintf(message, args...))
	}
}
<|endoftext|>


<commit_before>package parser

type OpCategory int

const (
	OP_ARITHMETIC OpCategory = iota
	OP_COMPARISON
	OP_BITWISE
	OP_LOGICAL
)

func (v OpCategory) PrettyString() string {
	switch v {
	case OP_ARITHMETIC:
		return "arithmetic"
	case OP_COMPARISON:
		return "comparison"
	case OP_BITWISE:
		return "bitwise"
	case OP_LOGICAL:
		return "logical"
	default:
		panic("missing opcategory")
	}
}

//go:generate stringer -type=BinOpType
type BinOpType int

const (
	BINOP_ERR BinOpType = iota

	BINOP_ADD
	BINOP_SUB
	BINOP_MUL
	BINOP_DIV
	BINOP_MOD

	BINOP_GREATER
	BINOP_LESS
	BINOP_GREATER_EQ
	BINOP_LESS_EQ
	BINOP_EQ
	BINOP_NOT_EQ

	BINOP_BIT_AND
	BINOP_BIT_OR
	BINOP_BIT_XOR
	BINOP_BIT_LEFT
	BINOP_BIT_RIGHT

	BINOP_LOG_AND
	BINOP_LOG_OR
)

var binOpStrings = []string{"", "+", "-", "*", "/", "%", ">", "<", ">=", "<=",
	"==", "!=", "&", "|", "^", "<<", ">>", "&&", "||"}

func stringToBinOpType(s string) BinOpType {
	for i, str := range binOpStrings {
		if str == s {
			return BinOpType(i)
		}
	}
	return BINOP_ERR
}

func (v BinOpType) OpString() string {
	return binOpStrings[v]
}

func (v BinOpType) Category() OpCategory {
	switch v {
	case BINOP_ADD, BINOP_SUB, BINOP_MUL, BINOP_DIV, BINOP_MOD:
		return OP_ARITHMETIC
	case BINOP_GREATER, BINOP_LESS, BINOP_GREATER_EQ, BINOP_LESS_EQ, BINOP_EQ, BINOP_NOT_EQ:
		return OP_COMPARISON
	case BINOP_BIT_AND, BINOP_BIT_OR, BINOP_BIT_XOR, BINOP_BIT_LEFT, BINOP_BIT_RIGHT:
		return OP_BITWISE
	case BINOP_LOG_AND, BINOP_LOG_OR:
		return OP_LOGICAL
	default:
		panic("missing op category")
	}
}

func newBinOpPrecedenceMap() map[BinOpType]int {
	m := make(map[BinOpType]int)

	// lowest to highest
	precedences := [][]BinOpType{
		{BINOP_LOG_OR},
		{BINOP_LOG_AND},
		{BINOP_BIT_OR},
		{BINOP_BIT_AND},
		{BINOP_EQ, BINOP_NOT_EQ},
		{BINOP_GREATER, BINOP_LESS, BINOP_GREATER_EQ, BINOP_LESS_EQ},
		{BINOP_BIT_LEFT, BINOP_BIT_RIGHT},
		{BINOP_ADD, BINOP_SUB},
		{BINOP_MUL, BINOP_DIV, BINOP_MOD},
	}

	for i, list := range precedences {
		for _, op := range list {
			m[op] = i + 1
		}
	}

	return m
}

//go:generate stringer -type=UnOpType
type UnOpType int

const (
	UNOP_ERR UnOpType = iota

	UNOP_LOG_NOT

	UNOP_BIT_NOT

	UNOP_NEGATIVE

	UNOP_DEREF
)

func stringToUnOpType(s string) UnOpType {
	switch s {
	case "!":
		return UNOP_LOG_NOT

	case "~":
		return UNOP_BIT_NOT

	case "-":
		return UNOP_NEGATIVE

	case "@":
		return UNOP_DEREF

	default:
		return UNOP_ERR
	}
}

func (v UnOpType) OpString() string {
	switch v {
	case UNOP_LOG_NOT:
		return "!"

	case UNOP_BIT_NOT:
		return "~"

	case UNOP_NEGATIVE:
		return "-"

	case UNOP_DEREF:
		return "@"

	default:
		return "ERR"
	}
}
<commit_msg>Actually parse XORs<commit_after>package parser

type OpCategory int

const (
	OP_ARITHMETIC OpCategory = iota
	OP_COMPARISON
	OP_BITWISE
	OP_LOGICAL
)

func (v OpCategory) PrettyString() string {
	switch v {
	case OP_ARITHMETIC:
		return "arithmetic"
	case OP_COMPARISON:
		return "comparison"
	case OP_BITWISE:
		return "bitwise"
	case OP_LOGICAL:
		return "logical"
	default:
		panic("missing opcategory")
	}
}

//go:generate stringer -type=BinOpType
type BinOpType int

const (
	BINOP_ERR BinOpType = iota

	BINOP_ADD
	BINOP_SUB
	BINOP_MUL
	BINOP_DIV
	BINOP_MOD

	BINOP_GREATER
	BINOP_LESS
	BINOP_GREATER_EQ
	BINOP_LESS_EQ
	BINOP_EQ
	BINOP_NOT_EQ

	BINOP_BIT_AND
	BINOP_BIT_OR
	BINOP_BIT_XOR
	BINOP_BIT_LEFT
	BINOP_BIT_RIGHT

	BINOP_LOG_AND
	BINOP_LOG_OR
)

var binOpStrings = []string{"", "+", "-", "*", "/", "%", ">", "<", ">=", "<=",
	"==", "!=", "&", "|", "^", "<<", ">>", "&&", "||"}

func stringToBinOpType(s string) BinOpType {
	for i, str := range binOpStrings {
		if str == s {
			return BinOpType(i)
		}
	}
	return BINOP_ERR
}

func (v BinOpType) OpString() string {
	return binOpStrings[v]
}

func (v BinOpType) Category() OpCategory {
	switch v {
	case BINOP_ADD, BINOP_SUB, BINOP_MUL, BINOP_DIV, BINOP_MOD:
		return OP_ARITHMETIC
	case BINOP_GREATER, BINOP_LESS, BINOP_GREATER_EQ, BINOP_LESS_EQ, BINOP_EQ, BINOP_NOT_EQ:
		return OP_COMPARISON
	case BINOP_BIT_AND, BINOP_BIT_OR, BINOP_BIT_XOR, BINOP_BIT_LEFT, BINOP_BIT_RIGHT:
		return OP_BITWISE
	case BINOP_LOG_AND, BINOP_LOG_OR:
		return OP_LOGICAL
	default:
		panic("missing op category")
	}
}

func newBinOpPrecedenceMap() map[BinOpType]int {
	m := make(map[BinOpType]int)

	// lowest to highest
	precedences := [][]BinOpType{
		{BINOP_LOG_OR},
		{BINOP_LOG_AND},
		{BINOP_BIT_OR},
		{BINOP_BIT_XOR},
		{BINOP_BIT_AND},
		{BINOP_EQ, BINOP_NOT_EQ},
		{BINOP_GREATER, BINOP_LESS, BINOP_GREATER_EQ, BINOP_LESS_EQ},
		{BINOP_BIT_LEFT, BINOP_BIT_RIGHT},
		{BINOP_ADD, BINOP_SUB},
		{BINOP_MUL, BINOP_DIV, BINOP_MOD},
	}

	for i, list := range precedences {
		for _, op := range list {
			m[op] = i + 1
		}
	}

	return m
}

//go:generate stringer -type=UnOpType
type UnOpType int

const (
	UNOP_ERR UnOpType = iota

	UNOP_LOG_NOT

	UNOP_BIT_NOT

	UNOP_NEGATIVE

	UNOP_DEREF
)

func stringToUnOpType(s string) UnOpType {
	switch s {
	case "!":
		return UNOP_LOG_NOT

	case "~":
		return UNOP_BIT_NOT

	case "-":
		return UNOP_NEGATIVE

	case "@":
		return UNOP_DEREF

	default:
		return UNOP_ERR
	}
}

func (v UnOpType) OpString() string {
	switch v {
	case UNOP_LOG_NOT:
		return "!"

	case UNOP_BIT_NOT:
		return "~"

	case UNOP_NEGATIVE:
		return "-"

	case UNOP_DEREF:
		return "@"

	default:
		return "ERR"
	}
}
<|endoftext|>


<commit_before>package email

import (
	"encoding/base64"
	"fmt"
	"io"
	"mime/multipart"
	"mime/quotedprintable"
	"net/textproto"
)

// Email attachment. The content of the attachment is provided either as a
// UTF-8 string or as a Base64-encoded string ("encoded" set to "true").
type Attachment struct {
	Filename    string `json:"filename"`
	ContentType string `json:"content_type"`
	Content     string `json:"content"`
	Encoded     bool   `json:"encoded"`
}

// Write the attachment to the specified multipart writer.
func (a Attachment) Write(w *multipart.Writer) error {
	var headers textproto.MIMEHeader
	if len(a.Filename) != 0 {
		headers.Add("Content-Type", fmt.Sprintf("%s; name=%s", a.ContentType, a.Filename))
	} else {
		headers.Add("Content-Type", a.ContentType)
	}
	if a.Encoded {
		headers.Add("Content-Transfer-Encoding", "base64")
	} else {
		headers.Add("Content-Transfer-Encoding", "quoted-printable")
	}
	p, err := w.CreatePart(headers)
	if err != nil {
		return err
	}
	var writer io.Writer
	if a.Encoded {
		writer = base64.NewEncoder(base64.StdEncoding, p)
	} else {
		writer = quotedprintable.NewWriter(p)
	}
	if _, err := writer.Write([]byte(a.Content)); err != nil {
		return err
	}
	return nil
}
<commit_msg>Fixed double-encoding bug.<commit_after>package email

import (
	"fmt"
	"mime/multipart"
	"mime/quotedprintable"
	"net/textproto"
)

// Email attachment. The content of the attachment is provided either as a
// UTF-8 string or as a Base64-encoded string ("encoded" set to "true").
type Attachment struct {
	Filename    string `json:"filename"`
	ContentType string `json:"content_type"`
	Content     string `json:"content"`
	Encoded     bool   `json:"encoded"`
}

// Write the attachment to the specified multipart writer.
func (a Attachment) Write(w *multipart.Writer) error {
	var headers textproto.MIMEHeader
	if len(a.Filename) != 0 {
		headers.Add("Content-Type", fmt.Sprintf("%s; name=%s", a.ContentType, a.Filename))
	} else {
		headers.Add("Content-Type", a.ContentType)
	}
	if a.Encoded {
		headers.Add("Content-Transfer-Encoding", "base64")
	} else {
		headers.Add("Content-Transfer-Encoding", "quoted-printable")
	}
	p, err := w.CreatePart(headers)
	if err != nil {
		return err
	}
	writer := p
	if !a.Encoded {
		writer = quotedprintable.NewWriter(p)
	}
	if _, err := writer.Write([]byte(a.Content)); err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before><commit_msg>fixed MeasureTextWidth befor pdf.Cell caused char not found Error<commit_after><|endoftext|>


<commit_before><commit_msg>Cleaned up mutable graph<commit_after><|endoftext|>


<commit_before>package gvutils

import (
	"flag"
)

func FlagParser() (action string) {
	verS := flag.Bool("v", false, "displays the current version and build time")
	verL := flag.Bool("version", false, "displays the current version and build time")
	flag.Parse()

	if *verS || *verL == true {
		action = "version"
		return
	}
	return
}
<commit_msg>This closes #11 fixing a GoLint error<commit_after>package gvutils

import (
	"flag"
)

//FlagParser contains the flag implentation for go-vivid, outputing a string "action"
func FlagParser() (action string) {
	verS := flag.Bool("v", false, "displays the current version and build time")
	verL := flag.Bool("version", false, "displays the current version and build time")
	flag.Parse()

	if *verS || *verL == true {
		action = "version"
		return
	}
	return
}
<|endoftext|>