<commit_before>package lsl

import (
	"fmt"
	"io"
	"log"
	"path/filepath"

	"github.com/gobuffalo/packr"
	"github.com/yuin/gopher-lua"
	"layeh.com/gopher-luar"
)

var (
	luaBox     packr.Box
	uTestBox   packr.Box
	lslFrame   string
	uTestFrame string
)

func init() {
	var err error
	luaBox = packr.NewBox("./lua")
	lslFrame, err = luaBox.MustString("env.lua")
	if err != nil {
		log.Fatalf("Failed to load lua env %s", err)
	}
	uTestBox = packr.NewBox("./lua/u-test")
	uTestFrame, err = uTestBox.MustString("u-test.lua")
	if err != nil {
		log.Fatalf("Failed to test env %s", err)
	}
}

// OutputWriter ... function for writing
type OutputWriter func(txt string)

// InputReader ... function for reading input
type InputReader func() string

// LuaLog ...  Log capture system
type LuaLog struct {
	Output io.Writer
}

// Error ... Log error
func (ll *LuaLog) Error(txt string) {
	msg := fmt.Sprintf("ERROR: %s", txt)
	ll.Log(msg)
}

// Info ... Info log wrapper
func (ll *LuaLog) Info(txt string) {
	msg := fmt.Sprintf("INFO: %s", txt)
	ll.Log(msg)
}

// Debug ... Very low level effort
func (ll *LuaLog) Debug(txt string) {
	msg := fmt.Sprintf("DEBUG: %s", txt)
	ll.Log(msg)
}

// Log ... Just output some text
func (ll *LuaLog) Log(v interface{}) {
	msg := fmt.Sprintf("%v\n", v)
	log.Print(msg)
	ll.Output.Write([]byte(msg))
}

// LuaLoader ... Simple loader system
type LuaLoader struct {
	State    *lua.LState
	Input    io.Reader
	Output   io.Writer
	Log      *LuaLog
	EnvMap   map[string]interface{}
	DslPath  string
	envBuilt bool
}

// NewLuaLoader ... creates a new LuaLoader
func NewLuaLoader(in io.Reader, out io.Writer, dslPath string) *LuaLoader {
	ll := &LuaLoader{State: lua.NewState(), Input: in, Output: out, Log: &LuaLog{out}, EnvMap: make(map[string]interface{}), DslPath: dslPath, envBuilt: false}
	return ll
}

// SetGlobalVar ... Push into enviroment
func (ll *LuaLoader) SetGlobalVar(n string, v interface{}) {
	// If already exists then remove it first
	if _, exists := ll.EnvMap[n]; exists {
		delete(ll.EnvMap, n)
	}
	ll.EnvMap[n] = v
}

func (ll *LuaLoader) BuildEnv() {
	// Don't build the more than once
	if ll.envBuilt {
		return
	}
	err := ll.State.DoString(lslFrame)
	if err != nil {
		log.Fatalf("Failed to load lsl framework %s", err)
	}
	// Log wrappers
	ll.SetGlobalVar("log_debug", luar.New(ll.State, ll.Log.Debug))
	ll.SetGlobalVar("log_info", luar.New(ll.State, ll.Log.Info))
	ll.SetGlobalVar("log_error", luar.New(ll.State, ll.Log.Error))
	ll.SetGlobalVar("log", luar.New(ll.State, ll.Log.Log))
	//ll.SetGlobalVar("print", luar.New(ll.State, ll.Log.Log))
	ll.State.SetGlobal("env_map", luar.New(ll.State, ll.EnvMap))
	ll.envBuilt = true
}

// Code ... Execute code path
func (ll *LuaLoader) Code(code string) error {
	ll.BuildEnv()
	return ll.State.CallByParam(lua.P{
		Fn:      ll.State.GetGlobal("run_code_with_env"),
		NRet:    1,
		Protect: true,
	}, lua.LString(code))
}

// File ... Runs a DSL file
func (ll *LuaLoader) File(path string) error {
	ll.BuildEnv()
	return ll.State.CallByParam(lua.P{
		Fn:      ll.State.GetGlobal("run_file_with_env"),
		NRet:    1,
		Protect: true,
	}, lua.LString(path))
}

// Test ... Execute test file in dsl mode
func (ll *LuaLoader) Test(path string) error {
	ll.State.SetGlobal("print", luar.New(ll.State, func(msg string) {
		ll.Output.Write([]byte(msg))
	}))

	ut, err := ll.State.LoadString(uTestFrame)
	if err != nil {
		log.Fatalf("Failed to load u-test framework %s", err)
	}
	ll.State.SetGlobal("utest", ut)
	ll.BuildEnv()
	testPath := filepath.Dir(path)
	return ll.State.CallByParam(lua.P{
		Fn:      ll.State.GetGlobal("run_test_with_env"),
		NRet:    1,
		Protect: true,
	}, lua.LString(path), lua.LString(testPath))
}

// Close ... End execution and exit
func (ll *LuaLoader) Close() {
	ll.State.Close()
}
<commit_msg>Cleanup<commit_after>package lsl

import (
	"fmt"
	"io"
	"log"
	"path/filepath"

	"github.com/gobuffalo/packr"
	"github.com/yuin/gopher-lua"
	"layeh.com/gopher-luar"
)

var (
	luaBox     packr.Box
	uTestBox   packr.Box
	lslFrame   string
	uTestFrame string
)

func init() {
	var err error
	luaBox = packr.NewBox("./lua")
	lslFrame, err = luaBox.MustString("env.lua")
	if err != nil {
		log.Fatalf("Failed to load lua env %s", err)
	}
	uTestBox = packr.NewBox("./lua/u-test")
	uTestFrame, err = uTestBox.MustString("u-test.lua")
	if err != nil {
		log.Fatalf("Failed to test env %s", err)
	}
}

// OutputWriter ... function for writing
type OutputWriter func(txt string)

// InputReader ... function for reading input
type InputReader func() string

// LuaLog ...  Log capture system
type LuaLog struct {
	Output io.Writer
}

// Error ... Log error
func (ll *LuaLog) Error(txt string) {
	msg := fmt.Sprintf("ERROR: %s", txt)
	ll.Log(msg)
}

// Info ... Info log wrapper
func (ll *LuaLog) Info(txt string) {
	msg := fmt.Sprintf("INFO: %s", txt)
	ll.Log(msg)
}

// Debug ... Very low level effort
func (ll *LuaLog) Debug(txt string) {
	msg := fmt.Sprintf("DEBUG: %s", txt)
	ll.Log(msg)
}

// Log ... Just output some text
func (ll *LuaLog) Log(v interface{}) {
	msg := fmt.Sprintf("%v\n", v)
	log.Print(msg)
	ll.Output.Write([]byte(msg))
}

// LuaLoader ... Simple loader system
type LuaLoader struct {
	State    *lua.LState
	Input    io.Reader
	Output   io.Writer
	Log      *LuaLog
	EnvMap   map[string]interface{}
	DslPath  string
	envBuilt bool
}

// NewLuaLoader ... creates a new LuaLoader
func NewLuaLoader(in io.Reader, out io.Writer, dslPath string) *LuaLoader {
	ll := &LuaLoader{State: lua.NewState(), Input: in, Output: out, Log: &LuaLog{out}, EnvMap: make(map[string]interface{}), DslPath: dslPath, envBuilt: false}
	return ll
}

// SetGlobalVar ... Push into enviroment
func (ll *LuaLoader) SetGlobalVar(n string, v interface{}) {
	// If already exists then remove it first
	if _, exists := ll.EnvMap[n]; exists {
		delete(ll.EnvMap, n)
	}
	ll.EnvMap[n] = v
}

func (ll *LuaLoader) BuildEnv() {
	// Don't build the more than once
	if ll.envBuilt {
		return
	}
	err := ll.State.DoString(lslFrame)
	if err != nil {
		log.Fatalf("Failed to load lsl framework %s", err)
	}
	// Log wrappers
	ll.SetGlobalVar("log_debug", luar.New(ll.State, ll.Log.Debug))
	ll.SetGlobalVar("log_info", luar.New(ll.State, ll.Log.Info))
	ll.SetGlobalVar("log_error", luar.New(ll.State, ll.Log.Error))
	ll.SetGlobalVar("log", luar.New(ll.State, ll.Log.Log))
	ll.State.SetGlobal("env_map", luar.New(ll.State, ll.EnvMap))
	ll.envBuilt = true
}

// Code ... Execute code path
func (ll *LuaLoader) Code(code string) error {
	ll.BuildEnv()
	return ll.State.CallByParam(lua.P{
		Fn:      ll.State.GetGlobal("run_code_with_env"),
		NRet:    1,
		Protect: true,
	}, lua.LString(code))
}

// File ... Runs a DSL file
func (ll *LuaLoader) File(path string) error {
	ll.BuildEnv()
	return ll.State.CallByParam(lua.P{
		Fn:      ll.State.GetGlobal("run_file_with_env"),
		NRet:    1,
		Protect: true,
	}, lua.LString(path))
}

// Test ... Execute test file in dsl mode
func (ll *LuaLoader) Test(path string) error {
	ll.State.SetGlobal("print", luar.New(ll.State, func(msg string) {
		ll.Output.Write([]byte(msg))
	}))

	ut, err := ll.State.LoadString(uTestFrame)
	if err != nil {
		log.Fatalf("Failed to load u-test framework %s", err)
	}
	ll.State.SetGlobal("utest", ut)
	ll.BuildEnv()
	testPath := filepath.Dir(path)
	return ll.State.CallByParam(lua.P{
		Fn:      ll.State.GetGlobal("run_test_with_env"),
		NRet:    1,
		Protect: true,
	}, lua.LString(path), lua.LString(testPath))
}

// Close ... End execution and exit
func (ll *LuaLoader) Close() {
	ll.State.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"github.com/coopernurse/gorp"
	_ "github.com/mattn/go-sqlite3"
	"log"
)

type User struct {
	Id       int64  `db: "id"`
	Name     string `json: "name"`
	Email    string `json: "email"`
	Password string `json: "password"`
}

type Point struct {
	X int
	Y int
}

type State struct {
	X       int  `json: "x"`
	Y       int  `json: "y"`
	Crashed bool `json: "crashed"`
	Speed   int  `json: "speed"`
}

type Road struct {
	InnerRoad []Point
	OuterRoad []Point
}

type Car struct {
	Color int
	Point Point
	State State
}

func (u User) Save() {
	dbmap := initDb()
	defer dbmap.Db.Close()

	err := dbmap.Insert(u)
	checkErr(err, "User saving failed")
}

func (u User) Get(id int) User {
	dbmap := initDb()
	defer dbmap.Db.Close()
	user := User{}
	err := dbmap.SelectOne(&user, "Select * from users where id=?", id)
	checkErr(err, "User is unreachable")
	return user
}

func (c Car) MoveTo(point Point) Point {
	c.Point = point
	// ToDo: implement correct algorithm with use of intersection
	// Assume collision detection done on client side for now
	return c.Point
}

func (c Car) Status() State {
	// ToDo: this should return summarized car's status at current time.
	// probably it should contain coords, state, leadership
	return c.State
}

func (u User) GetRoom() string {
	// ToDo this should return users room data, or room itself.
	return "room data"
}

func (u User) MoveToRoom() {
	// ToDo: this will place user to new room
}

func initDb() *gorp.DbMap {
	// connect to db using standard Go database/sql API
	// use whatever database/sql driver you wish
	db, err := sql.Open("sqlite3", "./tmp/post_db.bin")
	checkErr(err, "sql.Open failed")

	// construct a gorp DbMap
	dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}

	// add a table, setting the table name to 'posts' and
	// specifying that the Id property is an auto incrementing PK
	dbmap.AddTableWithName(User{}, "posts").SetKeys(true, "Id")

	// create the table. in a production system you'd generally
	// use a migration tool, or create the tables via scripts
	err = dbmap.CreateTablesIfNotExists()
	checkErr(err, "Create tables failed")

	return dbmap
}

func checkErr(err error, msg string) {
	if err != nil {
		log.Fatalln(msg, err)
	}
}
<commit_msg>started addin rooms<commit_after>package main

import (
	"database/sql"
	"github.com/coopernurse/gorp"
	_ "github.com/mattn/go-sqlite3"
	"log"
)

type User struct {
	Id       int64  `db: "id"`
	Name     string `json: "name"`
	Email    string `json: "email"`
	Password string `json: "password"`
}

type Point struct {
	X int
	Y int
}

type State struct {
	X       int  `json: "x"`
	Y       int  `json: "y"`
	Crashed bool `json: "crashed"`
	Speed   int  `json: "speed"`
}

type Road struct {
	InnerRoad []Point
	OuterRoad []Point
}

type Car struct {
	Color int
	Point Point
	State State
}

type Room struct {
	room_id      int64
	room_channel string
}

func (u User) Save() {
	dbmap := initDb()
	defer dbmap.Db.Close()

	err := dbmap.Insert(u)
	checkErr(err, "User saving failed")
}

func (u User) Get(id int) User {
	dbmap := initDb()
	defer dbmap.Db.Close()
	user := User{}
	err := dbmap.SelectOne(&user, "Select * from users where id=?", id)
	checkErr(err, "User is unreachable")
	return user
}

func (c Car) MoveTo(point Point) Point {
	c.Point = point
	// ToDo: implement correct algorithm with use of intersection
	// Assume collision detection done on client side for now
	return c.Point
}

func (c Car) Status() State {
	// ToDo: this should return summarized car's status at current time.
	// probably it should contain coords, state, leadership
	return c.State
}

func (u User) GetRoom() string {
	// ToDo this should return users room data, or room itself.
	return "room data"
}

func (u User) MoveToRoom() {
	// ToDo: this will place user to new room
}

func initDb() *gorp.DbMap {
	// connect to db using standard Go database/sql API
	// use whatever database/sql driver you wish
	db, err := sql.Open("sqlite3", "./tmp/post_db.bin")
	checkErr(err, "sql.Open failed")

	// construct a gorp DbMap
	dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}

	// add a table, setting the table name to 'posts' and
	// specifying that the Id property is an auto incrementing PK
	dbmap.AddTableWithName(User{}, "posts").SetKeys(true, "Id")

	// create the table. in a production system you'd generally
	// use a migration tool, or create the tables via scripts
	err = dbmap.CreateTablesIfNotExists()
	checkErr(err, "Create tables failed")

	return dbmap
}

func checkErr(err error, msg string) {
	if err != nil {
		log.Fatalln(msg, err)
	}
}
<|endoftext|>


<commit_before>package vips

/*
#cgo pkg-config: vips
#include "conversion.h"
*/
import "C"

type Extend int

const (
	ExtendBlack      = C.VIPS_EXTEND_BLACK
	ExtendCopy       = C.VIPS_EXTEND_COPY
	ExtendRepeat     = C.VIPS_EXTEND_REPEAT
	ExtendMirror     = C.VIPS_EXTEND_MIRROR
	ExtendWhite      = C.VIPS_EXTEND_WHITE
	ExtendBackground = C.VIPS_EXTEND_BACKGROUND
)

type Angle int

const (
	Angle0   = C.VIPS_ANGLE_D0
	Angle90  = C.VIPS_ANGLE_D90
	Angle180 = C.VIPS_ANGLE_D180
	Angle270 = C.VIPS_ANGLE_D270
)

type Direction int

const (
	DirectionHorizontal = C.VIPS_DIRECTION_HORIZONTAL
	DirectionVertical   = C.VIPS_DIRECTION_VERTICAL
)

func (in Image) Cast(format BandFormat) (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_cast(in.vi, &out, C.VipsBandFormat(format))
	return imageError(out, e)
}

func (in Image) Copy() (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_copy(in.vi, &out)
	return imageError(out, e)
}

func (in Image) Embed(left, top, width, height int, extend Extend) (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_embed(in.vi, &out, C.int(left), C.int(top), C.int(width), C.int(height), C.int(extend))
	return imageError(out, e)
}

func (in Image) ExtractArea(left, top, width, height int) (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_extract_area(in.vi, &out, C.int(left), C.int(top), C.int(width), C.int(height))
	return imageError(out, e)
}

func (in Image) Flip(direction Direction) (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_flip(in.vi, &out, C.VipsDirection(direction))
	return imageError(out, e)
}

func (in Image) Premultiply() (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_premultiply(in.vi, &out)
	return imageError(out, e)
}

func (in Image) Rot(angle Angle) (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_rot(in.vi, &out, C.VipsAngle(angle))
	return imageError(out, e)
}

func (in Image) Unpremultiply() (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_unpremultiply(in.vi, &out)
	return imageError(out, e)
}
<commit_msg>Add Go types onto some VIPS enums.<commit_after>package vips

/*
#cgo pkg-config: vips
#include "conversion.h"
*/
import "C"

type Extend int

const (
	ExtendBlack      Extend = C.VIPS_EXTEND_BLACK
	ExtendCopy       Extend = C.VIPS_EXTEND_COPY
	ExtendRepeat     Extend = C.VIPS_EXTEND_REPEAT
	ExtendMirror     Extend = C.VIPS_EXTEND_MIRROR
	ExtendWhite      Extend = C.VIPS_EXTEND_WHITE
	ExtendBackground Extend = C.VIPS_EXTEND_BACKGROUND
)

type Angle int

const (
	Angle0   Angle = C.VIPS_ANGLE_D0
	Angle90  Angle = C.VIPS_ANGLE_D90
	Angle180 Angle = C.VIPS_ANGLE_D180
	Angle270 Angle = C.VIPS_ANGLE_D270
)

type Direction int

const (
	DirectionHorizontal Direction = C.VIPS_DIRECTION_HORIZONTAL
	DirectionVertical   Direction = C.VIPS_DIRECTION_VERTICAL
)

func (in Image) Cast(format BandFormat) (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_cast(in.vi, &out, C.VipsBandFormat(format))
	return imageError(out, e)
}

func (in Image) Copy() (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_copy(in.vi, &out)
	return imageError(out, e)
}

func (in Image) Embed(left, top, width, height int, extend Extend) (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_embed(in.vi, &out, C.int(left), C.int(top), C.int(width), C.int(height), C.int(extend))
	return imageError(out, e)
}

func (in Image) ExtractArea(left, top, width, height int) (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_extract_area(in.vi, &out, C.int(left), C.int(top), C.int(width), C.int(height))
	return imageError(out, e)
}

func (in Image) Flip(direction Direction) (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_flip(in.vi, &out, C.VipsDirection(direction))
	return imageError(out, e)
}

func (in Image) Premultiply() (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_premultiply(in.vi, &out)
	return imageError(out, e)
}

func (in Image) Rot(angle Angle) (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_rot(in.vi, &out, C.VipsAngle(angle))
	return imageError(out, e)
}

func (in Image) Unpremultiply() (*Image, error) {
	var out *C.struct__VipsImage
	e := C.cgo_vips_unpremultiply(in.vi, &out)
	return imageError(out, e)
}
<|endoftext|>


<commit_before>package stringsutil

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

// SliceTrimSpace removes leading and trailing spaces per
// string and optionally removes empty strings.
func SliceLinesTrimSpace(lines []string, condense bool) []string {
	return SliceLinesTrim(lines, " ", condense)
}

func SliceLinesTrim(lines []string, cutstr string, condense bool) []string {
	for i, line := range lines {
		line = strings.Trim(line, cutstr)
		if condense && len(line) == 0 {
			continue
		}
		lines[i] = line
	}
	return lines
}

func SliceIndexOrEmpty(s []string, index uint64) string {
	if int(index) >= len(s) {
		return ""
	}
	return s[index]
}

// JoinAny takes an array of interface{} and converts
// each value to a string using fmt.Sprintf("%v")
func JoinAny(a []interface{}, sep string) string {
	strs := []string{}
	for _, item := range a {
		strs = append(strs, fmt.Sprintf("%v", item))
	}
	return strings.Join(strs, sep)
}

func JoinInt(a []int, sep string) string {
	strs := []string{}
	for _, i := range a {
		strs = append(strs, strconv.Itoa(i))
	}
	return strings.Join(strs, sep)
}

func JoinCondenseTrimSpace(slice []string, sep string) string {
	return strings.Join(SliceLinesTrimSpace(slice, true), sep)
}

func SliceCondenseRegexps(texts []string, regexps []*regexp.Regexp, replacement string) []string {
	parts := []string{}
	for _, part := range texts {
		for _, rx := range regexps {
			part = rx.ReplaceAllString(part, replacement)
		}
		part = strings.TrimSpace(part)
		if len(part) > 0 {
			parts = append(parts, part)
		}
	}
	return parts
}

func SliceCondensePunctuation(texts []string) []string {
	parts := []string{}
	for _, part := range texts {
		part = regexp.MustCompile(`[^a-zA-Z0-9]+`).ReplaceAllString(part, " ")
		part = regexp.MustCompile(`\s+`).ReplaceAllString(part, " ")
		part = strings.TrimSpace(part)
		if len(part) > 0 {
			parts = append(parts, part)
		}
	}
	return parts
}

func SliceCondenseAndQuoteSpace(items []string, quoteLeft, quoteRight string) []string {
	return SliceCondenseAndQuote(items, " ", " ", quoteLeft, quoteRight)
}

func SliceCondenseAndQuote(items []string, trimLeft, trimRight, quoteLeft, quoteRight string) []string {
	newItems := []string{}
	for _, item := range items {
		item = strings.TrimLeft(item, trimLeft)
		item = strings.TrimRight(item, trimRight)
		if len(item) > 0 {
			item = quoteLeft + item + quoteRight
			newItems = append(newItems, item)
		}
	}
	return newItems
}

// SplitTrimSpace splits a string and trims spaces on
// remaining elements.
func SplitTrimSpace(s, sep string) []string {
	split := strings.Split(s, sep)
	strs := []string{}
	for _, str := range split {
		strs = append(strs, strings.TrimSpace(str))
	}
	return strs
}

// SliceToSingleIntOrNeg converts a single element slice
// with a string to an integer or `-1`
func SliceToSingleIntOrNeg(vals []string) int {
	if len(vals) != 1 {
		return -1
	}
	num, err := strconv.Atoi(vals[0])
	if err != nil {
		return -1
	}
	return num
}

// Dedupe returns a string slice with duplicate values
// removed. First observance is kept.
func Dedupe(vals []string) []string {
	deduped := []string{}
	seen := map[string]int{}

	for _, val := range vals {
		if _, ok := seen[val]; ok {
			continue
		}
		seen[val] = 1
		deduped = append(deduped, val)
	}
	return deduped
}

// SliceIndexOf returns the index of an element in a
// string slice. Returns -1 if not found.
func SliceIndexOf(needle string, haystack []string) int {
	for k, v := range haystack {
		if v == needle {
			return k
		}
	}
	return -1 //not found.
}

// SliceIndexOfLcTrimSpace returns the index of an element in a
// string slice. Returns -1 if not found.
func SliceIndexOfLcTrimSpace(needle string, haystack []string) int {
	needle = strings.ToLower(strings.TrimSpace(needle))
	for k, v := range haystack {
		v = strings.ToLower(strings.TrimSpace(v))
		if v == needle {
			return k
		}
	}
	return -1 //not found.
}

func SliceChooseOnePreferredLowerTrimSpace(options, preferenceOrder []string) string {
	if len(options) == 0 {
		return ""
	} else if len(preferenceOrder) == 0 {
		return strings.ToLower(strings.TrimSpace(options[0]))
	}
	optMap := map[string]int{}
	for _, opt := range options {
		opt = strings.ToLower(strings.TrimSpace(opt))
		if len(opt) > 0 {
			optMap[opt] = 1
		}
	}
	for _, pref := range preferenceOrder {
		pref = strings.ToLower(strings.TrimSpace(pref))
		if _, ok := optMap[pref]; ok {
			return pref
		}
	}
	return strings.ToLower(strings.TrimSpace(options[0]))
}

func SliceJoinQuotedMaxLength(slice []string, begQuote, endQuote, sep string, maxLength int) []string {
	words := []string{}
	curWords := []string{}
	curLength := 0
	for _, word := range slice {
		if curLength+len(begQuote+word+endQuote+sep) > maxLength {
			words = append(words, strings.Join(curWords, sep))
			curWords = []string{}
			curLength = 0
		} else {
			curWords = append(curWords, begQuote+word+endQuote)
			curLength += len(begQuote + word + endQuote + sep)
		}
	}
	if len(curWords) > 0 {
		words = append(words, strings.Join(curWords, sep))
	}
	return words
}

type JoinCustomConfig struct {
	QuoteBegin string
	QuoteEnd   string
	Separator  string
	MaxLength  int
	TrimSpace  bool
	SkipEmpty  bool
}

func JoinCustom(slice []string, cfg JoinCustomConfig) []string {
	lines := []string{}
	curWords := []string{}
	curLength := 0
	for _, word := range slice {
		if cfg.TrimSpace {
			word = strings.TrimSpace(word)
		}
		if cfg.SkipEmpty && len(word) == 0 {
			continue
		}
		if cfg.MaxLength > 0 {
			if curLength+len(cfg.QuoteBegin+word+cfg.QuoteEnd+cfg.Separator) > cfg.MaxLength {
				lines = append(lines, strings.Join(curWords, cfg.Separator))
				curWords = []string{}
				curLength = 0
			} else {
				curWords = append(curWords, cfg.QuoteBegin+word+cfg.QuoteEnd)
				curLength += len(cfg.QuoteBegin + word + cfg.QuoteEnd + cfg.Separator)
			}
		} else {
			curWords = append(curWords, cfg.QuoteBegin+word+cfg.QuoteEnd)
		}
	}
	if len(curWords) > 0 {
		lines = append(lines, strings.Join(curWords, cfg.Separator))
	}
	return lines
}

func SliceJoinQuotedMaxLengthTrimSpaceSkipEmpty(slice []string, begQuote, endQuote, sep string, maxLength int) []string {
	words := []string{}
	curWords := []string{}
	curLength := 0
	for _, word := range slice {
		if curLength+len(begQuote+word+endQuote+sep) > maxLength {
			words = append(words, strings.Join(curWords, sep))
			curWords = []string{}
			curLength = 0
		} else {
			curWords = append(curWords, begQuote+word+endQuote)
			curLength += len(begQuote + word + endQuote + sep)
		}
	}
	if len(curWords) > 0 {
		words = append(words, strings.Join(curWords, sep))
	}
	return words
}

func SliceJoinQuoted(slice []string, begQuote, endQuote, sep string) string {
	words := []string{}
	for _, word := range slice {
		words = append(words, begQuote+word+endQuote)
	}
	return strings.Join(words, sep)
}
<commit_msg>add stringsutil.Unshift and stringsutil comments<commit_after>package stringsutil

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

// Unshift adds an element at the first position
// of the slice.
func Unshift(a []string, x string) []string {
	return append([]string{x}, a...)
}

// SliceLinesTrimSpace removes leading and trailing spaces per
// string and optionally removes empty strings.
func SliceLinesTrimSpace(lines []string, condense bool) []string {
	return SliceLinesTrim(lines, " ", condense)
}

// SliceLinesTrim trims each line in a slice of lines using a
// provided cut string.
func SliceLinesTrim(lines []string, cutstr string, condense bool) []string {
	for i, line := range lines {
		line = strings.Trim(line, cutstr)
		if condense && len(line) == 0 {
			continue
		}
		lines[i] = line
	}
	return lines
}

// SliceIndexOrEmpty returns the element at the index
// provided or an empty string.
func SliceIndexOrEmpty(s []string, index uint64) string {
	if int(index) >= len(s) {
		return ""
	}
	return s[index]
}

// JoinAny takes an array of interface{} and converts
// each value to a string using fmt.Sprintf("%v")
func JoinAny(a []interface{}, sep string) string {
	strs := []string{}
	for _, item := range a {
		strs = append(strs, fmt.Sprintf("%v", item))
	}
	return strings.Join(strs, sep)
}

func JoinInt(a []int, sep string) string {
	strs := []string{}
	for _, i := range a {
		strs = append(strs, strconv.Itoa(i))
	}
	return strings.Join(strs, sep)
}

func JoinCondenseTrimSpace(slice []string, sep string) string {
	return strings.Join(SliceLinesTrimSpace(slice, true), sep)
}

func SliceCondenseRegexps(texts []string, regexps []*regexp.Regexp, replacement string) []string {
	parts := []string{}
	for _, part := range texts {
		for _, rx := range regexps {
			part = rx.ReplaceAllString(part, replacement)
		}
		part = strings.TrimSpace(part)
		if len(part) > 0 {
			parts = append(parts, part)
		}
	}
	return parts
}

func SliceCondensePunctuation(texts []string) []string {
	parts := []string{}
	for _, part := range texts {
		part = regexp.MustCompile(`[^a-zA-Z0-9]+`).ReplaceAllString(part, " ")
		part = regexp.MustCompile(`\s+`).ReplaceAllString(part, " ")
		part = strings.TrimSpace(part)
		if len(part) > 0 {
			parts = append(parts, part)
		}
	}
	return parts
}

func SliceCondenseAndQuoteSpace(items []string, quoteLeft, quoteRight string) []string {
	return SliceCondenseAndQuote(items, " ", " ", quoteLeft, quoteRight)
}

func SliceCondenseAndQuote(items []string, trimLeft, trimRight, quoteLeft, quoteRight string) []string {
	newItems := []string{}
	for _, item := range items {
		item = strings.TrimLeft(item, trimLeft)
		item = strings.TrimRight(item, trimRight)
		if len(item) > 0 {
			item = quoteLeft + item + quoteRight
			newItems = append(newItems, item)
		}
	}
	return newItems
}

// SplitTrimSpace splits a string and trims spaces on
// remaining elements.
func SplitTrimSpace(s, sep string) []string {
	split := strings.Split(s, sep)
	strs := []string{}
	for _, str := range split {
		strs = append(strs, strings.TrimSpace(str))
	}
	return strs
}

// SliceToSingleIntOrNeg converts a single element slice
// with a string to an integer or `-1`
func SliceToSingleIntOrNeg(vals []string) int {
	if len(vals) != 1 {
		return -1
	}
	num, err := strconv.Atoi(vals[0])
	if err != nil {
		return -1
	}
	return num
}

// Dedupe returns a string slice with duplicate values
// removed. First observance is kept.
func Dedupe(vals []string) []string {
	deduped := []string{}
	seen := map[string]int{}

	for _, val := range vals {
		if _, ok := seen[val]; ok {
			continue
		}
		seen[val] = 1
		deduped = append(deduped, val)
	}
	return deduped
}

// SliceIndexOf returns the index of an element in a
// string slice. Returns -1 if not found.
func SliceIndexOf(needle string, haystack []string) int {
	for k, v := range haystack {
		if v == needle {
			return k
		}
	}
	return -1 //not found.
}

// SliceIndexOfLcTrimSpace returns the index of an element in a
// string slice. Returns -1 if not found.
func SliceIndexOfLcTrimSpace(needle string, haystack []string) int {
	needle = strings.ToLower(strings.TrimSpace(needle))
	for k, v := range haystack {
		v = strings.ToLower(strings.TrimSpace(v))
		if v == needle {
			return k
		}
	}
	return -1 //not found.
}

func SliceChooseOnePreferredLowerTrimSpace(options, preferenceOrder []string) string {
	if len(options) == 0 {
		return ""
	} else if len(preferenceOrder) == 0 {
		return strings.ToLower(strings.TrimSpace(options[0]))
	}
	optMap := map[string]int{}
	for _, opt := range options {
		opt = strings.ToLower(strings.TrimSpace(opt))
		if len(opt) > 0 {
			optMap[opt] = 1
		}
	}
	for _, pref := range preferenceOrder {
		pref = strings.ToLower(strings.TrimSpace(pref))
		if _, ok := optMap[pref]; ok {
			return pref
		}
	}
	return strings.ToLower(strings.TrimSpace(options[0]))
}

func SliceJoinQuotedMaxLength(slice []string, begQuote, endQuote, sep string, maxLength int) []string {
	words := []string{}
	curWords := []string{}
	curLength := 0
	for _, word := range slice {
		if curLength+len(begQuote+word+endQuote+sep) > maxLength {
			words = append(words, strings.Join(curWords, sep))
			curWords = []string{}
			curLength = 0
		} else {
			curWords = append(curWords, begQuote+word+endQuote)
			curLength += len(begQuote + word + endQuote + sep)
		}
	}
	if len(curWords) > 0 {
		words = append(words, strings.Join(curWords, sep))
	}
	return words
}

type JoinCustomConfig struct {
	QuoteBegin string
	QuoteEnd   string
	Separator  string
	MaxLength  int
	TrimSpace  bool
	SkipEmpty  bool
}

func JoinCustom(slice []string, cfg JoinCustomConfig) []string {
	lines := []string{}
	curWords := []string{}
	curLength := 0
	for _, word := range slice {
		if cfg.TrimSpace {
			word = strings.TrimSpace(word)
		}
		if cfg.SkipEmpty && len(word) == 0 {
			continue
		}
		if cfg.MaxLength > 0 {
			if curLength+len(cfg.QuoteBegin+word+cfg.QuoteEnd+cfg.Separator) > cfg.MaxLength {
				lines = append(lines, strings.Join(curWords, cfg.Separator))
				curWords = []string{}
				curLength = 0
			} else {
				curWords = append(curWords, cfg.QuoteBegin+word+cfg.QuoteEnd)
				curLength += len(cfg.QuoteBegin + word + cfg.QuoteEnd + cfg.Separator)
			}
		} else {
			curWords = append(curWords, cfg.QuoteBegin+word+cfg.QuoteEnd)
		}
	}
	if len(curWords) > 0 {
		lines = append(lines, strings.Join(curWords, cfg.Separator))
	}
	return lines
}

func SliceJoinQuotedMaxLengthTrimSpaceSkipEmpty(slice []string, begQuote, endQuote, sep string, maxLength int) []string {
	words := []string{}
	curWords := []string{}
	curLength := 0
	for _, word := range slice {
		if curLength+len(begQuote+word+endQuote+sep) > maxLength {
			words = append(words, strings.Join(curWords, sep))
			curWords = []string{}
			curLength = 0
		} else {
			curWords = append(curWords, begQuote+word+endQuote)
			curLength += len(begQuote + word + endQuote + sep)
		}
	}
	if len(curWords) > 0 {
		words = append(words, strings.Join(curWords, sep))
	}
	return words
}

func SliceJoinQuoted(slice []string, begQuote, endQuote, sep string) string {
	words := []string{}
	for _, word := range slice {
		words = append(words, begQuote+word+endQuote)
	}
	return strings.Join(words, sep)
}
<|endoftext|>


<commit_before>package core

import (
	"path"
	"regexp"
	"strings"

	"fmt"
	"gopkg.in/op/go-logging.v1"
)

var log = logging.MustGetLogger("core")

// Representation of an identifier of a build target, eg. //spam/eggs:ham
// corresponds to BuildLabel{PackageName: spam/eggs name: ham}
// BuildLabels are always absolute, so relative identifiers
// like :ham are always parsed into an absolute form.
// There is also implicit expansion of the final element of a target (ala Blaze)
// so //spam/eggs is equivalent to //spam/eggs:eggs
type BuildLabel struct {
	PackageName string
	Name        string
}

// Build label that represents parsing the entire graph.
// We use this specially in one or two places.
var WholeGraph = []BuildLabel{{PackageName: "", Name: "..."}}

// Used to indicate that we're going to consume build labels from stdin.
var BuildLabelStdin = BuildLabel{PackageName: "", Name: "_STDIN"}

// Used to indicate one of the originally requested targets on the command line.
var OriginalTarget = BuildLabel{PackageName: "", Name: "_ORIGINAL"}

// This is a little strict; doesn't allow for non-ascii names, for example.
const packagePart = "[A-Za-z0-9\\._-]+"
const packageName = "(" + packagePart + "(?:/" + packagePart + ")*)"
const targetName = "([A-Za-z0-9\\._+-]+(?:#[A-Za-z0-9_+-]+)*)"

// Regexes for matching the various ways of writing a build label.
// Fully specified labels, e.g. //src/core:core
var absoluteTarget = regexp.MustCompile(fmt.Sprintf("^//(?:%s)?:%s$", packageName, targetName))

// Targets in local package, e.g. :core
var localTarget = regexp.MustCompile(fmt.Sprintf("^:%s$", targetName))

// Targets with an implicit target name, e.g. //src/core (expands to //src/core:core)
var implicitTarget = regexp.MustCompile(fmt.Sprintf("^//(?:%s/)?(%s)$", packageName, packagePart))

// All targets underneath a package, e.g. //src/core/...
var subTargets = regexp.MustCompile(fmt.Sprintf("^//%s/(\\.\\.\\.)$", packageName))

// Sub targets immediately underneath the root; //...
var rootSubTargets = regexp.MustCompile(fmt.Sprintf("^(//)(\\.\\.\\.)$"))

// The following cases only apply on the command line and can't be used in BUILD files.
// A relative target, e.g. core:core (expands to //src/core:core if already in src)
var relativeTarget = regexp.MustCompile(fmt.Sprintf("^%s:%s$", packageName, targetName))

// A relative target with implicitly specified target name, e.g. src/core (expands to //src/core:core)
var relativeImplicitTarget = regexp.MustCompile(fmt.Sprintf("^(?:%s/)?(%s)$", packageName, packagePart))

// All targets underneath a relative package, e.g. src/core/...
var relativeSubTargets = regexp.MustCompile(fmt.Sprintf("^(?:%s/)?(\\.\\.\\.)$", packageName))

// Package and target names only, used for validation.
var packageNameOnly = regexp.MustCompile(fmt.Sprintf("^%s?$", packageName))
var targetNameOnly = regexp.MustCompile(fmt.Sprintf("^%s$", targetName))

func (label BuildLabel) String() string {
	if label.Name != "" {
		return "//" + label.PackageName + ":" + label.Name
	}
	return "//" + label.PackageName
}

// NewBuildLabel constructs a new build label from the given components. Panics on failure.
func NewBuildLabel(pkgName string, name string) BuildLabel {
	label, err := TryNewBuildLabel(pkgName, name)
	if err != nil {
		panic(err)
	}
	return label
}

// TryNewBuildLabel constructs a new build label from the given components.
func TryNewBuildLabel(pkgName string, name string) (BuildLabel, error) {
	if !packageNameOnly.MatchString(pkgName) {
		return BuildLabel{}, fmt.Errorf("Invalid package name: %s", pkgName)
	} else if !targetNameOnly.MatchString(name) {
		return BuildLabel{}, fmt.Errorf("Invalid target name: %s", name)
	}
	return BuildLabel{PackageName: pkgName, Name: name}, nil
}

// ParseBuildLabel parses a single build label from a string. Panics on failure.
func ParseBuildLabel(target string, currentPath string) BuildLabel {
	label, err := TryParseBuildLabel(target, currentPath)
	if err != nil {
		panic(err)
	}
	return label
}

// TryParseBuildLabel attempts to parse a single build label from a string. Returns an error if unsuccessful.
func TryParseBuildLabel(target string, currentPath string) (BuildLabel, error) {
	matches := absoluteTarget.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(matches[1], matches[2]), nil
	}
	matches = localTarget.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(currentPath, matches[1]), nil
	}
	matches = subTargets.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(matches[1], matches[2]), nil
	}
	matches = rootSubTargets.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel("", matches[2]), nil
	}
	matches = implicitTarget.FindStringSubmatch(target)
	if matches != nil {
		if matches[1] != "" {
			return NewBuildLabel(matches[1]+"/"+matches[2], matches[2]), nil
		}
		return NewBuildLabel(matches[2], matches[2]), nil
	}
	return BuildLabel{}, fmt.Errorf("Invalid build label: %s", target)
}

// As above, but allows parsing of relative labels (eg. src/parse/rules:python_rules)
// which is convenient at the shell prompt
func parseMaybeRelativeBuildLabel(target, subdir string) BuildLabel {
	// Try the ones that don't need locating the repo root first.
	if !strings.HasPrefix(target, ":") {
		if label, err := TryParseBuildLabel(target, ""); err == nil {
			return label
		}
	}
	// Now we need to locate the repo root and initial package.
	// Deliberately leave this till after the above to facilitate the --repo_root flag.
	if subdir == "" {
		_, subdir = getRepoRoot(true)
	}
	matches := relativeTarget.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(path.Join(subdir, matches[1]), matches[2])
	}
	matches = relativeSubTargets.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(path.Join(subdir, matches[1]), matches[2])
	}
	matches = relativeImplicitTarget.FindStringSubmatch(target)
	if matches != nil {
		if matches[1] != "" {
			return NewBuildLabel(path.Join(subdir, matches[1], matches[2]), matches[2])
		}
		return NewBuildLabel(path.Join(subdir, matches[2]), matches[2])
	}
	matches = localTarget.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(subdir, matches[1])
	}
	log.Fatalf("Invalid build target label: %s", target)
	return BuildLabel{}
}

// Parse a bunch of build labels.
// Relative labels are allowed since this is generally used at initialisation.
func ParseBuildLabels(targets []string) []BuildLabel {
	defer func() {
		if r := recover(); r != nil {
			log.Fatalf("%s", r)
		}
	}()

	var ret []BuildLabel
	for _, target := range targets {
		ret = append(ret, parseMaybeRelativeBuildLabel(target, ""))
	}
	return ret
}

// Returns true if the label ends in ..., ie. it includes all subpackages.
func (label BuildLabel) IsAllSubpackages() bool {
	return label.Name == "..."
}

// Returns true if the label is the pseudo-label referring to all targets in this package.
func (label BuildLabel) IsAllTargets() bool {
	return label.Name == "all"
}

// covers returns true if label includes the other label (//pkg:target1 is covered by //pkg:all etc).
func (label BuildLabel) includes(that BuildLabel) bool {
	if strings.HasPrefix(that.PackageName, label.PackageName) {
		// We're in the same package or a subpackage of this visibility spec
		if label.IsAllSubpackages() {
			return true
		} else if label.PackageName == that.PackageName {
			if label.Name == that.Name || label.IsAllTargets() {
				return true
			}
		}
	}
	return false
}

func (this BuildLabel) Less(that BuildLabel) bool {
	if this.PackageName == that.PackageName {
		return this.Name < that.Name
	} else {
		return this.PackageName < that.PackageName
	}
}

// Implementation of BuildInput interface
func (label BuildLabel) Paths(graph *BuildGraph) []string {
	target := graph.TargetOrDie(label)
	outputs := target.Outputs()
	ret := make([]string, len(outputs), len(outputs))
	for i, output := range outputs {
		ret[i] = path.Join(label.PackageName, output)
	}
	return ret
}

func (label BuildLabel) FullPaths(graph *BuildGraph) []string {
	target := graph.TargetOrDie(label)
	outputs := target.Outputs()
	ret := make([]string, len(outputs), len(outputs))
	for i, output := range outputs {
		ret[i] = path.Join(target.OutDir(), output)
	}
	return ret
}

func (label BuildLabel) LocalPaths(graph *BuildGraph) []string {
	return graph.TargetOrDie(label).Outputs()
}

func (label BuildLabel) Label() *BuildLabel {
	return &label
}

// UnmarshalFlag unmarshals a build label from a command line flag. Implementation of flags.Unmarshaler interface.
func (label *BuildLabel) UnmarshalFlag(value string) error {
	// This is only allowable here, not in any other usage of build labels.
	if value == "-" {
		*label = BuildLabelStdin
		return nil
	}

	defer func() {
		if r := recover(); r != nil {
			// This has to be fatal because of the way we're using the flags package;
			// we lose incoming flags if we return errors.
			log.Fatalf("%s", r)
		}
	}()
	*label = parseMaybeRelativeBuildLabel(value, "")
	return nil
}

// Parent returns what would be the parent of a build label, or the label itself if it's parentless.
// Note that there is not a concrete guarantee that the returned label exists in the build graph,
// and that the label returned is the ultimate ancestor (ie. not necessarily immediate parent).
func (label BuildLabel) Parent() BuildLabel {
	index := strings.IndexRune(label.Name, '#')
	if index == -1 || !strings.HasPrefix(label.Name, "_") {
		return label
	}
	label.Name = strings.TrimLeft(label.Name[:index], "_")
	return label
}

// LooksLikeABuildLabel returns true if the string appears to be a build label, false if not.
// Useful for cases like rule sources where sources can be a filename or a label.
func LooksLikeABuildLabel(str string) bool {
	return strings.HasPrefix(str, "//") || strings.HasPrefix(str, ":")
}

// Make slices of these guys sortable.
type BuildLabels []BuildLabel

func (slice BuildLabels) Len() int {
	return len(slice)
}
func (slice BuildLabels) Less(i, j int) bool {
	return slice[i].Less(slice[j])
}
func (slice BuildLabels) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}
<commit_msg>Allow +'s in package names<commit_after>package core

import (
	"path"
	"regexp"
	"strings"

	"fmt"
	"gopkg.in/op/go-logging.v1"
)

var log = logging.MustGetLogger("core")

// Representation of an identifier of a build target, eg. //spam/eggs:ham
// corresponds to BuildLabel{PackageName: spam/eggs name: ham}
// BuildLabels are always absolute, so relative identifiers
// like :ham are always parsed into an absolute form.
// There is also implicit expansion of the final element of a target (ala Blaze)
// so //spam/eggs is equivalent to //spam/eggs:eggs
type BuildLabel struct {
	PackageName string
	Name        string
}

// Build label that represents parsing the entire graph.
// We use this specially in one or two places.
var WholeGraph = []BuildLabel{{PackageName: "", Name: "..."}}

// Used to indicate that we're going to consume build labels from stdin.
var BuildLabelStdin = BuildLabel{PackageName: "", Name: "_STDIN"}

// Used to indicate one of the originally requested targets on the command line.
var OriginalTarget = BuildLabel{PackageName: "", Name: "_ORIGINAL"}

// This is a little strict; doesn't allow for non-ascii names, for example.
const packagePart = "[A-Za-z0-9\\._\\+-]+"
const packageName = "(" + packagePart + "(?:/" + packagePart + ")*)"
const targetName = "([A-Za-z0-9\\._\\+-]+(?:#[A-Za-z0-9_\\+-]+)*)"

// Regexes for matching the various ways of writing a build label.
// Fully specified labels, e.g. //src/core:core
var absoluteTarget = regexp.MustCompile(fmt.Sprintf("^//(?:%s)?:%s$", packageName, targetName))

// Targets in local package, e.g. :core
var localTarget = regexp.MustCompile(fmt.Sprintf("^:%s$", targetName))

// Targets with an implicit target name, e.g. //src/core (expands to //src/core:core)
var implicitTarget = regexp.MustCompile(fmt.Sprintf("^//(?:%s/)?(%s)$", packageName, packagePart))

// All targets underneath a package, e.g. //src/core/...
var subTargets = regexp.MustCompile(fmt.Sprintf("^//%s/(\\.\\.\\.)$", packageName))

// Sub targets immediately underneath the root; //...
var rootSubTargets = regexp.MustCompile(fmt.Sprintf("^(//)(\\.\\.\\.)$"))

// The following cases only apply on the command line and can't be used in BUILD files.
// A relative target, e.g. core:core (expands to //src/core:core if already in src)
var relativeTarget = regexp.MustCompile(fmt.Sprintf("^%s:%s$", packageName, targetName))

// A relative target with implicitly specified target name, e.g. src/core (expands to //src/core:core)
var relativeImplicitTarget = regexp.MustCompile(fmt.Sprintf("^(?:%s/)?(%s)$", packageName, packagePart))

// All targets underneath a relative package, e.g. src/core/...
var relativeSubTargets = regexp.MustCompile(fmt.Sprintf("^(?:%s/)?(\\.\\.\\.)$", packageName))

// Package and target names only, used for validation.
var packageNameOnly = regexp.MustCompile(fmt.Sprintf("^%s?$", packageName))
var targetNameOnly = regexp.MustCompile(fmt.Sprintf("^%s$", targetName))

func (label BuildLabel) String() string {
	if label.Name != "" {
		return "//" + label.PackageName + ":" + label.Name
	}
	return "//" + label.PackageName
}

// NewBuildLabel constructs a new build label from the given components. Panics on failure.
func NewBuildLabel(pkgName string, name string) BuildLabel {
	label, err := TryNewBuildLabel(pkgName, name)
	if err != nil {
		panic(err)
	}
	return label
}

// TryNewBuildLabel constructs a new build label from the given components.
func TryNewBuildLabel(pkgName string, name string) (BuildLabel, error) {
	if !packageNameOnly.MatchString(pkgName) {
		return BuildLabel{}, fmt.Errorf("Invalid package name: %s", pkgName)
	} else if !targetNameOnly.MatchString(name) {
		return BuildLabel{}, fmt.Errorf("Invalid target name: %s", name)
	}
	return BuildLabel{PackageName: pkgName, Name: name}, nil
}

// ParseBuildLabel parses a single build label from a string. Panics on failure.
func ParseBuildLabel(target string, currentPath string) BuildLabel {
	label, err := TryParseBuildLabel(target, currentPath)
	if err != nil {
		panic(err)
	}
	return label
}

// TryParseBuildLabel attempts to parse a single build label from a string. Returns an error if unsuccessful.
func TryParseBuildLabel(target string, currentPath string) (BuildLabel, error) {
	matches := absoluteTarget.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(matches[1], matches[2]), nil
	}
	matches = localTarget.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(currentPath, matches[1]), nil
	}
	matches = subTargets.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(matches[1], matches[2]), nil
	}
	matches = rootSubTargets.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel("", matches[2]), nil
	}
	matches = implicitTarget.FindStringSubmatch(target)
	if matches != nil {
		if matches[1] != "" {
			return NewBuildLabel(matches[1]+"/"+matches[2], matches[2]), nil
		}
		return NewBuildLabel(matches[2], matches[2]), nil
	}
	return BuildLabel{}, fmt.Errorf("Invalid build label: %s", target)
}

// As above, but allows parsing of relative labels (eg. src/parse/rules:python_rules)
// which is convenient at the shell prompt
func parseMaybeRelativeBuildLabel(target, subdir string) BuildLabel {
	// Try the ones that don't need locating the repo root first.
	if !strings.HasPrefix(target, ":") {
		if label, err := TryParseBuildLabel(target, ""); err == nil {
			return label
		}
	}
	// Now we need to locate the repo root and initial package.
	// Deliberately leave this till after the above to facilitate the --repo_root flag.
	if subdir == "" {
		_, subdir = getRepoRoot(true)
	}
	matches := relativeTarget.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(path.Join(subdir, matches[1]), matches[2])
	}
	matches = relativeSubTargets.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(path.Join(subdir, matches[1]), matches[2])
	}
	matches = relativeImplicitTarget.FindStringSubmatch(target)
	if matches != nil {
		if matches[1] != "" {
			return NewBuildLabel(path.Join(subdir, matches[1], matches[2]), matches[2])
		}
		return NewBuildLabel(path.Join(subdir, matches[2]), matches[2])
	}
	matches = localTarget.FindStringSubmatch(target)
	if matches != nil {
		return NewBuildLabel(subdir, matches[1])
	}
	log.Fatalf("Invalid build target label: %s", target)
	return BuildLabel{}
}

// Parse a bunch of build labels.
// Relative labels are allowed since this is generally used at initialisation.
func ParseBuildLabels(targets []string) []BuildLabel {
	defer func() {
		if r := recover(); r != nil {
			log.Fatalf("%s", r)
		}
	}()

	var ret []BuildLabel
	for _, target := range targets {
		ret = append(ret, parseMaybeRelativeBuildLabel(target, ""))
	}
	return ret
}

// Returns true if the label ends in ..., ie. it includes all subpackages.
func (label BuildLabel) IsAllSubpackages() bool {
	return label.Name == "..."
}

// Returns true if the label is the pseudo-label referring to all targets in this package.
func (label BuildLabel) IsAllTargets() bool {
	return label.Name == "all"
}

// covers returns true if label includes the other label (//pkg:target1 is covered by //pkg:all etc).
func (label BuildLabel) includes(that BuildLabel) bool {
	if strings.HasPrefix(that.PackageName, label.PackageName) {
		// We're in the same package or a subpackage of this visibility spec
		if label.IsAllSubpackages() {
			return true
		} else if label.PackageName == that.PackageName {
			if label.Name == that.Name || label.IsAllTargets() {
				return true
			}
		}
	}
	return false
}

func (this BuildLabel) Less(that BuildLabel) bool {
	if this.PackageName == that.PackageName {
		return this.Name < that.Name
	} else {
		return this.PackageName < that.PackageName
	}
}

// Implementation of BuildInput interface
func (label BuildLabel) Paths(graph *BuildGraph) []string {
	target := graph.TargetOrDie(label)
	outputs := target.Outputs()
	ret := make([]string, len(outputs), len(outputs))
	for i, output := range outputs {
		ret[i] = path.Join(label.PackageName, output)
	}
	return ret
}

func (label BuildLabel) FullPaths(graph *BuildGraph) []string {
	target := graph.TargetOrDie(label)
	outputs := target.Outputs()
	ret := make([]string, len(outputs), len(outputs))
	for i, output := range outputs {
		ret[i] = path.Join(target.OutDir(), output)
	}
	return ret
}

func (label BuildLabel) LocalPaths(graph *BuildGraph) []string {
	return graph.TargetOrDie(label).Outputs()
}

func (label BuildLabel) Label() *BuildLabel {
	return &label
}

// UnmarshalFlag unmarshals a build label from a command line flag. Implementation of flags.Unmarshaler interface.
func (label *BuildLabel) UnmarshalFlag(value string) error {
	// This is only allowable here, not in any other usage of build labels.
	if value == "-" {
		*label = BuildLabelStdin
		return nil
	}

	defer func() {
		if r := recover(); r != nil {
			// This has to be fatal because of the way we're using the flags package;
			// we lose incoming flags if we return errors.
			log.Fatalf("%s", r)
		}
	}()
	*label = parseMaybeRelativeBuildLabel(value, "")
	return nil
}

// Parent returns what would be the parent of a build label, or the label itself if it's parentless.
// Note that there is not a concrete guarantee that the returned label exists in the build graph,
// and that the label returned is the ultimate ancestor (ie. not necessarily immediate parent).
func (label BuildLabel) Parent() BuildLabel {
	index := strings.IndexRune(label.Name, '#')
	if index == -1 || !strings.HasPrefix(label.Name, "_") {
		return label
	}
	label.Name = strings.TrimLeft(label.Name[:index], "_")
	return label
}

// LooksLikeABuildLabel returns true if the string appears to be a build label, false if not.
// Useful for cases like rule sources where sources can be a filename or a label.
func LooksLikeABuildLabel(str string) bool {
	return strings.HasPrefix(str, "//") || strings.HasPrefix(str, ":")
}

// Make slices of these guys sortable.
type BuildLabels []BuildLabel

func (slice BuildLabels) Len() int {
	return len(slice)
}
func (slice BuildLabels) Less(i, j int) bool {
	return slice[i].Less(slice[j])
}
func (slice BuildLabels) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}
<|endoftext|>


<commit_before>package objectserver

import (
	"github.com/Symantec/Dominator/lib/hash"
	"io"
)

type FullObjectServer interface {
	DeleteObject(hashVal hash.Hash) error
	ObjectServer
	ListObjectSizes() map[hash.Hash]uint64
	ListObjects() []hash.Hash
	NumObjects() uint64
}

type ObjectGetter interface {
	GetObject(hashVal hash.Hash) (uint64, io.ReadCloser, error)
}

type ObjectsReader interface {
	Close() error
	NextObject() (uint64, io.ReadCloser, error)
}

type ObjectServer interface {
	AddObject(reader io.Reader, length uint64, expectedHash *hash.Hash) (
		hash.Hash, bool, error)
	CheckObjects(hashes []hash.Hash) ([]uint64, error)
	ObjectGetter
	GetObjects(hashes []hash.Hash) (ObjectsReader, error)
}

type StashingObjectServer interface {
	CommitObject(hash.Hash) error
	DeleteStashedObject(hashVal hash.Hash) error
	ObjectServer
	StashOrVerifyObject(io.Reader, uint64, *hash.Hash) (
		hash.Hash, []byte, error)
}

func GetObject(objSrv ObjectServer, hashVal hash.Hash) (
	uint64, io.ReadCloser, error) {
	return getObject(objSrv, hashVal)
}
<commit_msg>Define garbage collector function and interface for objectservers.<commit_after>package objectserver

import (
	"github.com/Symantec/Dominator/lib/hash"
	"io"
)

type FullObjectServer interface {
	DeleteObject(hashVal hash.Hash) error
	ObjectServer
	ListObjectSizes() map[hash.Hash]uint64
	ListObjects() []hash.Hash
	NumObjects() uint64
}

type GarbageCollector func(bytesToDelete uint64) (
	bytesDeleted uint64, err error)

type GarbageCollectorSetter interface {
	SetGarbageCollector(gc GarbageCollector)
}

type ObjectGetter interface {
	GetObject(hashVal hash.Hash) (uint64, io.ReadCloser, error)
}

type ObjectsReader interface {
	Close() error
	NextObject() (uint64, io.ReadCloser, error)
}

type ObjectServer interface {
	AddObject(reader io.Reader, length uint64, expectedHash *hash.Hash) (
		hash.Hash, bool, error)
	CheckObjects(hashes []hash.Hash) ([]uint64, error)
	ObjectGetter
	GetObjects(hashes []hash.Hash) (ObjectsReader, error)
}

type StashingObjectServer interface {
	CommitObject(hash.Hash) error
	DeleteStashedObject(hashVal hash.Hash) error
	ObjectServer
	StashOrVerifyObject(io.Reader, uint64, *hash.Hash) (
		hash.Hash, []byte, error)
}

func GetObject(objSrv ObjectServer, hashVal hash.Hash) (
	uint64, io.ReadCloser, error) {
	return getObject(objSrv, hashVal)
}
<|endoftext|>


<commit_before>// +build example
//
// Do not build by default.

package main

import (
	"fmt"
	"os"
	"time"

	"gobot.io/x/gobot"
	"gobot.io/x/gobot/drivers/i2c"
	"gobot.io/x/gobot/platforms/firmata"
)

func main() {
	firmataAdaptor := firmata.NewAdaptor(os.Args[1])
	bmp180 := i2c.NewBMP180Driver(firmataAdaptor)

	work := func() {
		gobot.Every(1*time.Second, func() {
			t, _ := bmp180.Temperature()
			fmt.Println("Temperature", t)
		})
	}

	robot := gobot.NewRobot("bmp180bot",
		[]gobot.Connection{firmataAdaptor},
		[]gobot.Device{bmp180},
		work,
	)

	robot.Start()
}
<commit_msg>i2c: change example for bmp180 to match current method signature<commit_after>// +build example
//
// Do not build by default.

package main

import (
	"fmt"
	"os"
	"time"

	"gobot.io/x/gobot"
	"gobot.io/x/gobot/drivers/i2c"
	"gobot.io/x/gobot/platforms/firmata"
)

func main() {
	firmataAdaptor := firmata.NewAdaptor(os.Args[1])
	bmp180 := i2c.NewBMP180Driver(firmataAdaptor)

	work := func() {
		gobot.Every(1*time.Second, func() {
			t, _ := bmp180.Temperature()
			fmt.Println("Temperature", t)

			p, _ := bmp180.Pressure()
			fmt.Println("Pressure", p)
		})
	}

	robot := gobot.NewRobot("bmp180bot",
		[]gobot.Connection{firmataAdaptor},
		[]gobot.Device{bmp180},
		work,
	)

	robot.Start()
}
<|endoftext|>


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

package main

import (
	"bytes"
	"fmt"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"time"

	"google.golang.org/api/cloudmonitoring/v2beta2"

	"v.io/x/devtools/internal/monitoring"
	"v.io/x/devtools/internal/runutil"
	"v.io/x/devtools/internal/test"
	"v.io/x/devtools/internal/tool"
)

var (
	qpsRE = regexp.MustCompile(`.*/methods/([^/]*)/.*: Count: (\d+).*`)
)

type qpsInfo struct {
	name       string
	objectName string
}

// checkAllServiceQPS checks service RPC QPS (per-method and total) and adds
// the results to GCM.
func checkAllServiceQPS(ctx *tool.Context) error {
	infos := []qpsInfo{
		qpsInfo{
			name:       "mounttable",
			objectName: namespaceRootFlag + "/__debug/stats/rpc/server/routing-id/*/methods/*/latency-ms/delta1m",
		},
	}

	hasError := false
	for _, info := range infos {
		if qpsPerMethod, total, err := checkOneServiceQPS(ctx, info); err != nil {
			if err == runutil.CommandTimedOutErr {
				test.Warn(ctx, "%s: [TIMEOUT]\n", info.name)
			} else {
				test.Fail(ctx, "%s\n", info.name)
				fmt.Fprintf(ctx.Stderr(), "%v\n", err)
			}
			hasError = true
		} else {
			test.Pass(ctx, "%s:\n     - Per method: %v\n     - Total: %f\n",
				info.name, qpsPerMethod, total)
		}
	}
	if hasError {
		return fmt.Errorf("failed to check RPC QPS for some services.")
	}
	return nil
}

func checkOneServiceQPS(ctx *tool.Context, info qpsInfo) (map[string]float64, float64, error) {
	qpsPerMethod, totalQPS, err := getQPSData(ctx, info)
	if err != nil {
		return nil, -1, err
	}
	if err := sendQPSDataToGCM(qpsPerMethod, totalQPS, info); err != nil {
		return nil, -1, err
	}

	return qpsPerMethod, totalQPS, nil
}

func getQPSData(ctx *tool.Context, info qpsInfo) (map[string]float64, float64, error) {
	// Run "debug stats read" for the corresponding object.
	debug := filepath.Join(binDirFlag, "debug")
	var buf bytes.Buffer
	opts := ctx.Run().Opts()
	opts.Stdout = &buf
	opts.Stderr = &buf
	args := []string{
		"--v23.credentials",
		credentialsFlag,
		"stats",
		"read",
		info.objectName,
	}
	if err := ctx.Run().TimedCommandWithOpts(timeout, opts, debug, args...); err != nil {
		if err != runutil.CommandTimedOutErr {
			return nil, -1, fmt.Errorf("debug command failed: %v\n%s", err, buf.String())
		}
		return nil, -1, err
	}

	// Parse output.
	qpsPerMethod := map[string]float64{}
	totalQPS := 0.0
	lines := strings.Split(buf.String(), "\n")
	for _, line := range lines {
		fmt.Println(line)
		// Each line is in the form of:
		// <root>/__debug/stats/rpc/server/routing-id/<routing-id>/methods/<method>/latency-ms/delta1m: Count: 10  Min: 38  Max: 43  Avg: 39.30
		matches := qpsRE.FindStringSubmatch(line)
		if matches != nil {
			method := matches[1]
			strCount := matches[2]
			count, err := strconv.ParseFloat(strCount, 64)
			qps := count / 60.0
			if err != nil {
				return nil, -1, fmt.Errorf("strconv.ParseFloat(%s, 64) failed: %v", strCount, err)
			}
			qpsPerMethod[method] += qps
			totalQPS += qps
		}
	}

	return qpsPerMethod, totalQPS, nil
}

func sendQPSDataToGCM(qpsPerMethod map[string]float64, totalQPS float64, info qpsInfo) error {
	// Send QPS per method to GCM.
	serviceLocation := serviceLocationMap[namespaceRootFlag]
	if serviceLocation == nil {
		return fmt.Errorf("service location not found for %q", namespaceRootFlag)
	}
	mdQPSPerMethod := monitoring.CustomMetricDescriptors["service-rpc-qps-permethod"]
	s, err := monitoring.Authenticate(serviceAccountFlag, keyFileFlag)
	if err != nil {
		return err
	}
	timeStr := time.Now().Format(time.RFC3339)
	for method, qps := range qpsPerMethod {
		_, err := s.Timeseries.Write(projectFlag, &cloudmonitoring.WriteTimeseriesRequest{
			Timeseries: []*cloudmonitoring.TimeseriesPoint{
				&cloudmonitoring.TimeseriesPoint{
					Point: &cloudmonitoring.Point{
						DoubleValue: qps,
						Start:       timeStr,
						End:         timeStr,
					},
					TimeseriesDesc: &cloudmonitoring.TimeseriesDescriptor{
						Metric: mdQPSPerMethod.Name,
						Labels: map[string]string{
							mdQPSPerMethod.Labels[0].Key: serviceLocation.instance,
							mdQPSPerMethod.Labels[1].Key: serviceLocation.zone,
							mdQPSPerMethod.Labels[2].Key: info.name,
							mdQPSPerMethod.Labels[3].Key: method,
						},
					},
				},
			},
		}).Do()
		if err != nil {
			return fmt.Errorf("Timeseries Write failed: %v", err)
		}
	}

	// Send total QPS to GCM.
	mdQPSTotal := monitoring.CustomMetricDescriptors["service-rpc-qps-total"]
	_, err = s.Timeseries.Write(projectFlag, &cloudmonitoring.WriteTimeseriesRequest{
		Timeseries: []*cloudmonitoring.TimeseriesPoint{
			&cloudmonitoring.TimeseriesPoint{
				Point: &cloudmonitoring.Point{
					DoubleValue: totalQPS,
					Start:       timeStr,
					End:         timeStr,
				},
				TimeseriesDesc: &cloudmonitoring.TimeseriesDescriptor{
					Metric: mdQPSTotal.Name,
					Labels: map[string]string{
						mdQPSTotal.Labels[0].Key: serviceLocation.instance,
						mdQPSTotal.Labels[1].Key: serviceLocation.zone,
						mdQPSTotal.Labels[2].Key: info.name,
					},
				},
			},
		},
	}).Do()
	if err != nil {
		return fmt.Errorf("Timeseries Write failed: %v", err)
	}

	return nil
}
<commit_msg>TBR: vmon: fix metric name.<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"fmt"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"time"

	"google.golang.org/api/cloudmonitoring/v2beta2"

	"v.io/x/devtools/internal/monitoring"
	"v.io/x/devtools/internal/runutil"
	"v.io/x/devtools/internal/test"
	"v.io/x/devtools/internal/tool"
)

var (
	qpsRE = regexp.MustCompile(`.*/methods/([^/]*)/.*: Count: (\d+).*`)
)

type qpsInfo struct {
	name       string
	objectName string
}

// checkAllServiceQPS checks service RPC QPS (per-method and total) and adds
// the results to GCM.
func checkAllServiceQPS(ctx *tool.Context) error {
	infos := []qpsInfo{
		qpsInfo{
			name:       "mounttable",
			objectName: namespaceRootFlag + "/__debug/stats/rpc/server/routing-id/*/methods/*/latency-ms/delta1m",
		},
	}

	hasError := false
	for _, info := range infos {
		if qpsPerMethod, total, err := checkOneServiceQPS(ctx, info); err != nil {
			if err == runutil.CommandTimedOutErr {
				test.Warn(ctx, "%s: [TIMEOUT]\n", info.name)
			} else {
				test.Fail(ctx, "%s\n", info.name)
				fmt.Fprintf(ctx.Stderr(), "%v\n", err)
			}
			hasError = true
		} else {
			test.Pass(ctx, "%s:\n     - Per method: %v\n     - Total: %f\n",
				info.name, qpsPerMethod, total)
		}
	}
	if hasError {
		return fmt.Errorf("failed to check RPC QPS for some services.")
	}
	return nil
}

func checkOneServiceQPS(ctx *tool.Context, info qpsInfo) (map[string]float64, float64, error) {
	qpsPerMethod, totalQPS, err := getQPSData(ctx, info)
	if err != nil {
		return nil, -1, err
	}
	if err := sendQPSDataToGCM(qpsPerMethod, totalQPS, info); err != nil {
		return nil, -1, err
	}

	return qpsPerMethod, totalQPS, nil
}

func getQPSData(ctx *tool.Context, info qpsInfo) (map[string]float64, float64, error) {
	// Run "debug stats read" for the corresponding object.
	debug := filepath.Join(binDirFlag, "debug")
	var buf bytes.Buffer
	opts := ctx.Run().Opts()
	opts.Stdout = &buf
	opts.Stderr = &buf
	args := []string{
		"--v23.credentials",
		credentialsFlag,
		"stats",
		"read",
		info.objectName,
	}
	if err := ctx.Run().TimedCommandWithOpts(timeout, opts, debug, args...); err != nil {
		if err != runutil.CommandTimedOutErr {
			return nil, -1, fmt.Errorf("debug command failed: %v\n%s", err, buf.String())
		}
		return nil, -1, err
	}

	// Parse output.
	qpsPerMethod := map[string]float64{}
	totalQPS := 0.0
	lines := strings.Split(buf.String(), "\n")
	for _, line := range lines {
		fmt.Println(line)
		// Each line is in the form of:
		// <root>/__debug/stats/rpc/server/routing-id/<routing-id>/methods/<method>/latency-ms/delta1m: Count: 10  Min: 38  Max: 43  Avg: 39.30
		matches := qpsRE.FindStringSubmatch(line)
		if matches != nil {
			method := matches[1]
			strCount := matches[2]
			count, err := strconv.ParseFloat(strCount, 64)
			qps := count / 60.0
			if err != nil {
				return nil, -1, fmt.Errorf("strconv.ParseFloat(%s, 64) failed: %v", strCount, err)
			}
			qpsPerMethod[method] += qps
			totalQPS += qps
		}
	}

	return qpsPerMethod, totalQPS, nil
}

func sendQPSDataToGCM(qpsPerMethod map[string]float64, totalQPS float64, info qpsInfo) error {
	// Send QPS per method to GCM.
	serviceLocation := serviceLocationMap[namespaceRootFlag]
	if serviceLocation == nil {
		return fmt.Errorf("service location not found for %q", namespaceRootFlag)
	}
	mdQPSPerMethod := monitoring.CustomMetricDescriptors["service-qps-method"]
	s, err := monitoring.Authenticate(serviceAccountFlag, keyFileFlag)
	if err != nil {
		return err
	}
	timeStr := time.Now().Format(time.RFC3339)
	for method, qps := range qpsPerMethod {
		_, err := s.Timeseries.Write(projectFlag, &cloudmonitoring.WriteTimeseriesRequest{
			Timeseries: []*cloudmonitoring.TimeseriesPoint{
				&cloudmonitoring.TimeseriesPoint{
					Point: &cloudmonitoring.Point{
						DoubleValue: qps,
						Start:       timeStr,
						End:         timeStr,
					},
					TimeseriesDesc: &cloudmonitoring.TimeseriesDescriptor{
						Metric: mdQPSPerMethod.Name,
						Labels: map[string]string{
							mdQPSPerMethod.Labels[0].Key: serviceLocation.instance,
							mdQPSPerMethod.Labels[1].Key: serviceLocation.zone,
							mdQPSPerMethod.Labels[2].Key: info.name,
							mdQPSPerMethod.Labels[3].Key: method,
						},
					},
				},
			},
		}).Do()
		if err != nil {
			return fmt.Errorf("Timeseries Write failed: %v", err)
		}
	}

	// Send total QPS to GCM.
	mdQPSTotal := monitoring.CustomMetricDescriptors["service-qps-total"]
	_, err = s.Timeseries.Write(projectFlag, &cloudmonitoring.WriteTimeseriesRequest{
		Timeseries: []*cloudmonitoring.TimeseriesPoint{
			&cloudmonitoring.TimeseriesPoint{
				Point: &cloudmonitoring.Point{
					DoubleValue: totalQPS,
					Start:       timeStr,
					End:         timeStr,
				},
				TimeseriesDesc: &cloudmonitoring.TimeseriesDescriptor{
					Metric: mdQPSTotal.Name,
					Labels: map[string]string{
						mdQPSTotal.Labels[0].Key: serviceLocation.instance,
						mdQPSTotal.Labels[1].Key: serviceLocation.zone,
						mdQPSTotal.Labels[2].Key: info.name,
					},
				},
			},
		},
	}).Do()
	if err != nil {
		return fmt.Errorf("Timeseries Write failed: %v", err)
	}

	return nil
}
<|endoftext|>


<commit_before>// Package mpvipc provides an interface for communicating with the mpv media
// player via it's JSON IPC interface
package mpvipc

import (
	"bufio"
	"encoding/json"
	"fmt"
	"net"
	"runtime"
	"sync"

	"github.com/natefinch/npipe"
)

// Connection represents a connection to a mpv IPC socket
type Connection struct {
	client     net.Conn
	socketName string

	lastRequest     uint
	waitingRequests map[uint]chan *commandResult

	lastListener   uint
	eventListeners map[uint]chan<- *Event

	lastCloseWaiter uint
	closeWaiters    map[uint]chan struct{}

	lock *sync.Mutex
}

// Event represents an event received from mpv. For a list of all possible
// events, see https://mpv.io/manual/master/#list-of-events
type Event struct {
	// Name is the only obligatory field: the name of the event
	Name string `json:"event"`

	// Reason is the reason for the event: currently used for the "end-file"
	// event. When Name is "end-file", possible values of Reason are:
	// "eof", "stop", "quit", "error", "redirect", "unknown"
	Reason string `json:"reason"`

	// Prefix is the log-message prefix (only if Name is "log-message")
	Prefix string `json:"prefix"`

	// Level is the loglevel for a log-message (only if Name is "log-message")
	Level string `json:"level"`

	// Text is the text of a log-message (only if Name is "log-message")
	Text string `json:"text"`

	// ID is the user-set property ID (on events triggered by observed properties)
	ID uint `json:"id"`

	// Data is the property value (on events triggered by observed properties)
	Data interface{} `json:"data"`
}

// NewConnection returns a Connection associated with the given unix socket
func NewConnection(socketName string) *Connection {
	return &Connection{
		socketName:      socketName,
		lock:            &sync.Mutex{},
		waitingRequests: make(map[uint]chan *commandResult),
		eventListeners:  make(map[uint]chan<- *Event),
		closeWaiters:    make(map[uint]chan struct{}),
	}
}

// Open connects to the socket. Returns an error if already connected.
// It also starts listening to events, so ListenForEvents() can be called
// afterwards.
func (c *Connection) Open() error {
	c.lock.Lock()
	defer c.lock.Unlock()

	if c.client != nil {
		return fmt.Errorf("already open")
	}
	client, err := dial(c.socketName)
	if err != nil {
		return fmt.Errorf("can't connect to mpv's socket: %s", err)
	}
	c.client = client
	go c.listen()
	return nil
}

func dial(path string) (net.Conn, error) {
	if runtime.GOOS == "windows" {
		return npipe.Dial(path)
	}

	return net.Dial("unix", path)
}

// ListenForEvents blocks until something is received on the stop channel.
// In the mean time, events received on the socket will be sent on the events
// channel. They may not appear in the same order they happened in.
func (c *Connection) ListenForEvents(events chan<- *Event, stop <-chan struct{}) {
	c.lock.Lock()
	c.lastListener++
	id := c.lastListener
	c.eventListeners[id] = events
	c.lock.Unlock()

	<-stop

	c.lock.Lock()
	delete(c.eventListeners, id)
	close(events)
	c.lock.Unlock()
}

// NewEventListener is a convenience wrapper around ListenForEvents(). It
// creates and returns the event channel and the stop channel. After calling
// NewEventListener, read events from the events channel and send an empty
// struct to the stop channel to close it.
func (c *Connection) NewEventListener() (chan *Event, chan struct{}) {
	events := make(chan *Event)
	stop := make(chan struct{})
	go c.ListenForEvents(events, stop)
	return events, stop
}

// Call calls an arbitrary command and returns its result. For a list of
// possible functions, see https://mpv.io/manual/master/#commands and
// https://mpv.io/manual/master/#list-of-input-commands
func (c *Connection) Call(arguments ...interface{}) (interface{}, error) {
	c.lock.Lock()
	c.lastRequest++
	id := c.lastRequest
	resultChannel := make(chan *commandResult)
	c.waitingRequests[id] = resultChannel
	c.lock.Unlock()

	defer func() {
		c.lock.Lock()
		close(c.waitingRequests[id])
		delete(c.waitingRequests, id)
		c.lock.Unlock()
	}()

	err := c.sendCommand(id, arguments...)
	if err != nil {
		return nil, err
	}

	result := <-resultChannel
	if result.Status == "success" {
		return result.Data, nil
	}
	return nil, fmt.Errorf("mpv error: %s", result.Status)
}

// Set is a shortcut to Call("set_property", property, value)
func (c *Connection) Set(property string, value interface{}) error {
	_, err := c.Call("set_property", property, value)
	return err
}

// Get is a shortcut to Call("get_property", property)
func (c *Connection) Get(property string) (interface{}, error) {
	value, err := c.Call("get_property", property)
	return value, err
}

// Close closes the socket, disconnecting from mpv. It is safe to call Close()
// on an already closed connection.
func (c *Connection) Close() error {
	c.lock.Lock()
	defer c.lock.Unlock()

	if c.client != nil {
		err := c.client.Close()
		for waiterID := range c.closeWaiters {
			close(c.closeWaiters[waiterID])
		}
		c.client = nil
		return err
	}
	return nil
}

// IsClosed returns true if the connection is closed. There are several cases
// in which a connection is closed:
//
// 1. Close() has been called
//
// 2. The connection has been initialised but Open() hasn't been called yet
//
// 3. The connection terminated because of an error, mpv exiting or crashing
//
// It's ok to use IsClosed() to check if you need to reopen the connection
// before calling a command.
func (c *Connection) IsClosed() bool {
	return c.client == nil
}

// WaitUntilClosed blocks until the connection becomes closed. See IsClosed()
// for an explanation of the closed state.
func (c *Connection) WaitUntilClosed() {
	c.lock.Lock()
	if c.IsClosed() {
		c.lock.Unlock()
		return
	}

	closed := make(chan struct{})
	c.lastCloseWaiter++
	waiterID := c.lastCloseWaiter
	c.closeWaiters[waiterID] = closed

	c.lock.Unlock()

	<-closed

	c.lock.Lock()
	delete(c.closeWaiters, waiterID)
	c.lock.Unlock()
}

func (c *Connection) sendCommand(id uint, arguments ...interface{}) error {
	if c.client == nil {
		return fmt.Errorf("trying to send command on closed mpv client")
	}
	message := &commandRequest{
		Arguments: arguments,
		ID:        id,
	}
	data, err := json.Marshal(&message)
	if err != nil {
		return fmt.Errorf("can't encode command: %s", err)
	}
	_, err = c.client.Write(data)
	if err != nil {
		return fmt.Errorf("can't write command: %s", err)
	}
	_, err = c.client.Write([]byte("\n"))
	if err != nil {
		return fmt.Errorf("can't terminate command: %s", err)
	}
	return err
}

type commandRequest struct {
	Arguments []interface{} `json:"command"`
	ID        uint          `json:"request_id"`
}

type commandResult struct {
	Status string      `json:"error"`
	Data   interface{} `json:"data"`
	ID     uint        `json:"request_id"`
}

func (c *Connection) checkResult(data []byte) {
	result := &commandResult{}
	err := json.Unmarshal(data, &result)
	if err != nil {
		return // skip malformed data
	}
	if result.Status == "" {
		return // not a result
	}
	c.lock.Lock()
	request, ok := c.waitingRequests[result.ID]
	c.lock.Unlock()
	if ok {
		request <- result
	}
}

func (c *Connection) checkEvent(data []byte) {
	event := &Event{}
	err := json.Unmarshal(data, &event)
	if err != nil {
		return // skip malformed data
	}
	if event.Name == "" {
		return // not an event
	}
	c.lock.Lock()
	for listenerID := range c.eventListeners {
		listener := c.eventListeners[listenerID]
		go func() {
			listener <- event
		}()
	}
	c.lock.Unlock()
}

func (c *Connection) listen() {
	scanner := bufio.NewScanner(c.client)
	for scanner.Scan() {
		data := scanner.Bytes()
		c.checkEvent(data)
		c.checkResult(data)
	}
	_ = c.Close()
}
<commit_msg>use a gopkg.in import for npipe<commit_after>// Package mpvipc provides an interface for communicating with the mpv media
// player via it's JSON IPC interface
package mpvipc

import (
	"bufio"
	"encoding/json"
	"fmt"
	"net"
	"runtime"
	"sync"

	"gopkg.in/natefinch/npipe.v2"
)

// Connection represents a connection to a mpv IPC socket
type Connection struct {
	client     net.Conn
	socketName string

	lastRequest     uint
	waitingRequests map[uint]chan *commandResult

	lastListener   uint
	eventListeners map[uint]chan<- *Event

	lastCloseWaiter uint
	closeWaiters    map[uint]chan struct{}

	lock *sync.Mutex
}

// Event represents an event received from mpv. For a list of all possible
// events, see https://mpv.io/manual/master/#list-of-events
type Event struct {
	// Name is the only obligatory field: the name of the event
	Name string `json:"event"`

	// Reason is the reason for the event: currently used for the "end-file"
	// event. When Name is "end-file", possible values of Reason are:
	// "eof", "stop", "quit", "error", "redirect", "unknown"
	Reason string `json:"reason"`

	// Prefix is the log-message prefix (only if Name is "log-message")
	Prefix string `json:"prefix"`

	// Level is the loglevel for a log-message (only if Name is "log-message")
	Level string `json:"level"`

	// Text is the text of a log-message (only if Name is "log-message")
	Text string `json:"text"`

	// ID is the user-set property ID (on events triggered by observed properties)
	ID uint `json:"id"`

	// Data is the property value (on events triggered by observed properties)
	Data interface{} `json:"data"`
}

// NewConnection returns a Connection associated with the given unix socket
func NewConnection(socketName string) *Connection {
	return &Connection{
		socketName:      socketName,
		lock:            &sync.Mutex{},
		waitingRequests: make(map[uint]chan *commandResult),
		eventListeners:  make(map[uint]chan<- *Event),
		closeWaiters:    make(map[uint]chan struct{}),
	}
}

// Open connects to the socket. Returns an error if already connected.
// It also starts listening to events, so ListenForEvents() can be called
// afterwards.
func (c *Connection) Open() error {
	c.lock.Lock()
	defer c.lock.Unlock()

	if c.client != nil {
		return fmt.Errorf("already open")
	}
	client, err := dial(c.socketName)
	if err != nil {
		return fmt.Errorf("can't connect to mpv's socket: %s", err)
	}
	c.client = client
	go c.listen()
	return nil
}

func dial(path string) (net.Conn, error) {
	if runtime.GOOS == "windows" {
		return npipe.Dial(path)
	}

	return net.Dial("unix", path)
}

// ListenForEvents blocks until something is received on the stop channel.
// In the mean time, events received on the socket will be sent on the events
// channel. They may not appear in the same order they happened in.
func (c *Connection) ListenForEvents(events chan<- *Event, stop <-chan struct{}) {
	c.lock.Lock()
	c.lastListener++
	id := c.lastListener
	c.eventListeners[id] = events
	c.lock.Unlock()

	<-stop

	c.lock.Lock()
	delete(c.eventListeners, id)
	close(events)
	c.lock.Unlock()
}

// NewEventListener is a convenience wrapper around ListenForEvents(). It
// creates and returns the event channel and the stop channel. After calling
// NewEventListener, read events from the events channel and send an empty
// struct to the stop channel to close it.
func (c *Connection) NewEventListener() (chan *Event, chan struct{}) {
	events := make(chan *Event)
	stop := make(chan struct{})
	go c.ListenForEvents(events, stop)
	return events, stop
}

// Call calls an arbitrary command and returns its result. For a list of
// possible functions, see https://mpv.io/manual/master/#commands and
// https://mpv.io/manual/master/#list-of-input-commands
func (c *Connection) Call(arguments ...interface{}) (interface{}, error) {
	c.lock.Lock()
	c.lastRequest++
	id := c.lastRequest
	resultChannel := make(chan *commandResult)
	c.waitingRequests[id] = resultChannel
	c.lock.Unlock()

	defer func() {
		c.lock.Lock()
		close(c.waitingRequests[id])
		delete(c.waitingRequests, id)
		c.lock.Unlock()
	}()

	err := c.sendCommand(id, arguments...)
	if err != nil {
		return nil, err
	}

	result := <-resultChannel
	if result.Status == "success" {
		return result.Data, nil
	}
	return nil, fmt.Errorf("mpv error: %s", result.Status)
}

// Set is a shortcut to Call("set_property", property, value)
func (c *Connection) Set(property string, value interface{}) error {
	_, err := c.Call("set_property", property, value)
	return err
}

// Get is a shortcut to Call("get_property", property)
func (c *Connection) Get(property string) (interface{}, error) {
	value, err := c.Call("get_property", property)
	return value, err
}

// Close closes the socket, disconnecting from mpv. It is safe to call Close()
// on an already closed connection.
func (c *Connection) Close() error {
	c.lock.Lock()
	defer c.lock.Unlock()

	if c.client != nil {
		err := c.client.Close()
		for waiterID := range c.closeWaiters {
			close(c.closeWaiters[waiterID])
		}
		c.client = nil
		return err
	}
	return nil
}

// IsClosed returns true if the connection is closed. There are several cases
// in which a connection is closed:
//
// 1. Close() has been called
//
// 2. The connection has been initialised but Open() hasn't been called yet
//
// 3. The connection terminated because of an error, mpv exiting or crashing
//
// It's ok to use IsClosed() to check if you need to reopen the connection
// before calling a command.
func (c *Connection) IsClosed() bool {
	return c.client == nil
}

// WaitUntilClosed blocks until the connection becomes closed. See IsClosed()
// for an explanation of the closed state.
func (c *Connection) WaitUntilClosed() {
	c.lock.Lock()
	if c.IsClosed() {
		c.lock.Unlock()
		return
	}

	closed := make(chan struct{})
	c.lastCloseWaiter++
	waiterID := c.lastCloseWaiter
	c.closeWaiters[waiterID] = closed

	c.lock.Unlock()

	<-closed

	c.lock.Lock()
	delete(c.closeWaiters, waiterID)
	c.lock.Unlock()
}

func (c *Connection) sendCommand(id uint, arguments ...interface{}) error {
	if c.client == nil {
		return fmt.Errorf("trying to send command on closed mpv client")
	}
	message := &commandRequest{
		Arguments: arguments,
		ID:        id,
	}
	data, err := json.Marshal(&message)
	if err != nil {
		return fmt.Errorf("can't encode command: %s", err)
	}
	_, err = c.client.Write(data)
	if err != nil {
		return fmt.Errorf("can't write command: %s", err)
	}
	_, err = c.client.Write([]byte("\n"))
	if err != nil {
		return fmt.Errorf("can't terminate command: %s", err)
	}
	return err
}

type commandRequest struct {
	Arguments []interface{} `json:"command"`
	ID        uint          `json:"request_id"`
}

type commandResult struct {
	Status string      `json:"error"`
	Data   interface{} `json:"data"`
	ID     uint        `json:"request_id"`
}

func (c *Connection) checkResult(data []byte) {
	result := &commandResult{}
	err := json.Unmarshal(data, &result)
	if err != nil {
		return // skip malformed data
	}
	if result.Status == "" {
		return // not a result
	}
	c.lock.Lock()
	request, ok := c.waitingRequests[result.ID]
	c.lock.Unlock()
	if ok {
		request <- result
	}
}

func (c *Connection) checkEvent(data []byte) {
	event := &Event{}
	err := json.Unmarshal(data, &event)
	if err != nil {
		return // skip malformed data
	}
	if event.Name == "" {
		return // not an event
	}
	c.lock.Lock()
	for listenerID := range c.eventListeners {
		listener := c.eventListeners[listenerID]
		go func() {
			listener <- event
		}()
	}
	c.lock.Unlock()
}

func (c *Connection) listen() {
	scanner := bufio.NewScanner(c.client)
	for scanner.Scan() {
		data := scanner.Bytes()
		c.checkEvent(data)
		c.checkResult(data)
	}
	_ = c.Close()
}
<|endoftext|>


<commit_before>package api

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http" // Provides HTTP client and server implementations.

	"github.com/blockfreight/go-bftx/lib/app/bf_tx"

	"github.com/blockfreight/go-bftx/api/transaction"
	"github.com/blockfreight/go-bftx/lib/pkg/leveldb" // Provides some useful functions to work with LevelDB.
	"github.com/graphql-go/graphql"
)

func Start() error {
	http.HandleFunc("/graphql", graphRoute)
	fmt.Println("Now server is running on port 12345")
	fmt.Println("Test with Get      : curl -g 'http://localhost:12345/graphql?query={transaction(id:<BFTX-ID>){Id}}'")
	return http.ListenAndServe(":12345", nil)

}

var issueDetails = graphql.NewInputObject(
	graphql.InputObjectConfig{
		Name: "IssueDetails",
		Fields: graphql.InputObjectConfigFieldMap{
			"PlaceOfIssue": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"DateOfIssue": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
		},
	},
)

var masterInfo = graphql.NewInputObject(
	graphql.InputObjectConfig{
		Name: "MasterInfo",
		Fields: graphql.InputObjectConfigFieldMap{
			"FirstName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"LastName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"Sig": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
		},
	},
)

var agentForMaster = graphql.NewInputObject(
	graphql.InputObjectConfig{
		Name: "AgentForMaster",
		Fields: graphql.InputObjectConfigFieldMap{
			"FirstName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"LastName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"Sig": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
		},
	},
)

var agentForOwner = graphql.NewInputObject(
	graphql.InputObjectConfig{
		Name: "AgentForOwner",
		Fields: graphql.InputObjectConfigFieldMap{
			"FirstName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"LastName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"Sig": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"ConditionsForCarriage": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
		},
	},
)

var propertiesType = graphql.NewInputObject(
	graphql.InputObjectConfig{
		Name: "Properties",
		Fields: graphql.InputObjectConfigFieldMap{
			"Shipper": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"BolNum": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"RefNum": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"Consignee": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"Vessel": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"PortOfLoading": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"PortOfDischarge": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"NotifyAddress": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"DescOfGoods": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"GrossWeight": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"FreightPayableAmt": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"FreightAdvAmt": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"GeneralInstructions": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"DateShipped": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"IssueDetails": &graphql.InputObjectFieldConfig{
				Type: issueDetails,
			},
			"NumBol": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"MasterInfo": &graphql.InputObjectFieldConfig{
				Type: masterInfo,
			},
			"AgentForMaster": &graphql.InputObjectFieldConfig{
				Type: agentForMaster,
			},
			"AgentForOwner": &graphql.InputObjectFieldConfig{
				Type: agentForOwner,
			},
		},
	},
)

var transactionType = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "Transaction",
		Fields: graphql.Fields{
			"Id": &graphql.Field{
				Type: graphql.String,
			},
			"Type": &graphql.Field{
				Type: graphql.String,
			},
			"Verified": &graphql.Field{
				Type: graphql.Boolean,
			},
			"Transmitted": &graphql.Field{
				Type: graphql.Boolean,
			},
			"Properties": &graphql.Field{
				Type: propertiesType,
			},
		},
	},
)

var schema, _ = graphql.NewSchema(
	graphql.SchemaConfig{
		Query:    queryType,
		Mutation: mutationType,
	},
)

func graphRoute(w http.ResponseWriter, r *http.Request) {
	query, _ := ioutil.ReadAll(r.Body)
	result := executeQuery(string(query), schema)
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(result)
}

var queryType = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "Query",
		Fields: graphql.Fields{
			"transaction": &graphql.Field{
				Type: transactionType,
				Args: graphql.FieldConfigArgument{
					"id": &graphql.ArgumentConfig{
						Type: graphql.String,
					},
				},
				Resolve: func(p graphql.ResolveParams) (interface{}, error) {
					bftxID, isOK := p.Args["id"].(string)
					if !isOK {
						return nil, nil
					}

					bftx, err := leveldb.GetBfTx(bftxID)
					if err != nil {
						return nil, nil
					}
					return bftx, nil
				},
			},
		},
	})

var mutationType = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "Mutation",
		Fields: graphql.Fields{
			"constructBFTX": &graphql.Field{
				Type: transactionType,
				Args: graphql.FieldConfigArgument{
					"Type": &graphql.ArgumentConfig{
						Type: graphql.String,
					},
					"Properties": &graphql.ArgumentConfig{
						Description: "Transaction properties.",
						Type:        propertiesType,
					},
				},
				Resolve: func(p graphql.ResolveParams) (interface{}, error) {
					bftx := bf_tx.BF_TX{}
					jsonProperties, err := json.Marshal(p.Args)
					if err = json.Unmarshal([]byte(jsonProperties), &bftx); err != nil {
						fmt.Printf("err")
						fmt.Print(err)
					}
					fmt.Printf("%+v\n", bftx)

					bftx, err = transaction.ConstructBfTx(bftx)
					if err != nil {
						return nil, err
					}

					return bftx, err
				},
			},
		},
	},
)

func executeQuery(query string, schema graphql.Schema) *graphql.Result {

	result := graphql.Do(graphql.Params{
		Schema:        schema,
		RequestString: query,
	})

	return result
}
<commit_msg>Get and save transaction working<commit_after>package api

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http" // Provides HTTP client and server implementations.

	"github.com/blockfreight/go-bftx/lib/app/bf_tx"

	"github.com/blockfreight/go-bftx/api/transaction"
	"github.com/blockfreight/go-bftx/lib/pkg/leveldb" // Provides some useful functions to work with LevelDB.
	"github.com/graphql-go/graphql"
)

func Start() error {
	http.HandleFunc("/graphql", graphRoute)
	fmt.Println("Now server is running on port 12345")
	fmt.Println("Test with Get      : curl -g 'http://localhost:12345/graphql?query={transaction(id:<BFTX-ID>){Id}}'")
	return http.ListenAndServe(":12345", nil)

}

var issueDetailsInput = graphql.NewInputObject(
	graphql.InputObjectConfig{
		Name: "IssueDetails",
		Fields: graphql.InputObjectConfigFieldMap{
			"PlaceOfIssue": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"DateOfIssue": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
		},
	},
)

var issueDetails = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "IssueDetails",
		Fields: graphql.Fields{
			"PlaceOfIssue": &graphql.Field{
				Type: graphql.String,
			},
			"DateOfIssue": &graphql.Field{
				Type: graphql.String,
			},
		},
	},
)

var masterInfoInput = graphql.NewInputObject(
	graphql.InputObjectConfig{
		Name: "MasterInfo",
		Fields: graphql.InputObjectConfigFieldMap{
			"FirstName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"LastName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"Sig": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
		},
	},
)

var masterInfo = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "MasterInfo",
		Fields: graphql.Fields{
			"FirstName": &graphql.Field{
				Type: graphql.String,
			},
			"LastName": &graphql.Field{
				Type: graphql.String,
			},
			"Sig": &graphql.Field{
				Type: graphql.String,
			},
		},
	},
)

var agentForMasterInput = graphql.NewInputObject(
	graphql.InputObjectConfig{
		Name: "AgentForMaster",
		Fields: graphql.InputObjectConfigFieldMap{
			"FirstName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"LastName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"Sig": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
		},
	},
)

var agentForMaster = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "AgentForMaster",
		Fields: graphql.Fields{
			"FirstName": &graphql.Field{
				Type: graphql.String,
			},
			"LastName": &graphql.Field{
				Type: graphql.String,
			},
			"Sig": &graphql.Field{
				Type: graphql.String,
			},
		},
	},
)

var agentForOwnerInput = graphql.NewInputObject(
	graphql.InputObjectConfig{
		Name: "AgentForOwner",
		Fields: graphql.InputObjectConfigFieldMap{
			"FirstName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"LastName": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"Sig": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"ConditionsForCarriage": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
		},
	},
)

var agentForOwner = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "agentForOwner",
		Fields: graphql.Fields{
			"FirstName": &graphql.Field{
				Type: graphql.String,
			},
			"LastName": &graphql.Field{
				Type: graphql.String,
			},
			"Sig": &graphql.Field{
				Type: graphql.String,
			},
			"ConditionsForCarriage": &graphql.Field{
				Type: graphql.String,
			},
		},
	},
)

var propertiesType = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "Properties",
		Fields: graphql.Fields{
			"Shipper": &graphql.Field{
				Type: graphql.String,
			},
			"BolNum": &graphql.Field{
				Type: graphql.Int,
			},
			"RefNum": &graphql.Field{
				Type: graphql.Int,
			},
			"Consignee": &graphql.Field{
				Type: graphql.String,
			},
			"Vessel": &graphql.Field{
				Type: graphql.Int,
			},
			"PortOfLoading": &graphql.Field{
				Type: graphql.Int,
			},
			"PortOfDischarge": &graphql.Field{
				Type: graphql.Int,
			},
			"NotifyAddress": &graphql.Field{
				Type: graphql.String,
			},
			"DescOfGoods": &graphql.Field{
				Type: graphql.String,
			},
			"GrossWeight": &graphql.Field{
				Type: graphql.Int,
			},
			"FreightPayableAmt": &graphql.Field{
				Type: graphql.Int,
			},
			"FreightAdvAmt": &graphql.Field{
				Type: graphql.Int,
			},
			"GeneralInstructions": &graphql.Field{
				Type: graphql.String,
			},
			"DateShipped": &graphql.Field{
				Type: graphql.Int,
			},
			"IssueDetails": &graphql.Field{
				Type: issueDetails,
			},
			"NumBol": &graphql.Field{
				Type: graphql.Int,
			},
			"MasterInfo": &graphql.Field{
				Type: masterInfo,
			},
			"AgentForMaster": &graphql.Field{
				Type: agentForMaster,
			},
			"AgentForOwner": &graphql.Field{
				Type: agentForOwner,
			},
		},
	},
)

var propertiesInput = graphql.NewInputObject(
	graphql.InputObjectConfig{
		Name: "Properties",
		Fields: graphql.InputObjectConfigFieldMap{
			"Shipper": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"BolNum": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"RefNum": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"Consignee": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"Vessel": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"PortOfLoading": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"PortOfDischarge": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"NotifyAddress": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"DescOfGoods": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"GrossWeight": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"FreightPayableAmt": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"FreightAdvAmt": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"GeneralInstructions": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"DateShipped": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
			"IssueDetails": &graphql.InputObjectFieldConfig{
				Type: issueDetailsInput,
			},
			"NumBol": &graphql.InputObjectFieldConfig{
				Type: graphql.Int,
			},
			"MasterInfo": &graphql.InputObjectFieldConfig{
				Type: masterInfoInput,
			},
			"AgentForMaster": &graphql.InputObjectFieldConfig{
				Type: agentForMasterInput,
			},
			"AgentForOwner": &graphql.InputObjectFieldConfig{
				Type: agentForOwnerInput,
			},
		},
	},
)

var transactionType = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "Transaction",
		Fields: graphql.Fields{
			"Id": &graphql.Field{
				Type: graphql.String,
			},
			"Type": &graphql.Field{
				Type: graphql.String,
			},
			"Verified": &graphql.Field{
				Type: graphql.Boolean,
			},
			"Transmitted": &graphql.Field{
				Type: graphql.Boolean,
			},
			"Properties": &graphql.Field{
				Type: propertiesType,
			},
		},
	},
)

var schema, _ = graphql.NewSchema(
	graphql.SchemaConfig{
		Query:    queryType,
		Mutation: mutationType,
	},
)

func graphRoute(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query().Get("query")
	if query == "" {
		params, _ := ioutil.ReadAll(r.Body)
		query = string(params)
	}

	result := executeQuery(string(query), schema)
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(result)
}

var queryType = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "Query",
		Fields: graphql.Fields{
			"transaction": &graphql.Field{
				Type: transactionType,
				Args: graphql.FieldConfigArgument{
					"id": &graphql.ArgumentConfig{
						Type: graphql.String,
					},
				},
				Resolve: func(p graphql.ResolveParams) (interface{}, error) {
					bftxID, isOK := p.Args["id"].(string)
					if !isOK {
						return nil, nil
					}

					bftx, err := leveldb.GetBfTx(bftxID)
					if err != nil {
						return nil, nil
					}

					fmt.Printf("%+v\n", bftx)

					return bftx, nil
				},
			},
		},
	})

var mutationType = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "Mutation",
		Fields: graphql.Fields{
			"constructBFTX": &graphql.Field{
				Type: transactionType,
				Args: graphql.FieldConfigArgument{
					"Type": &graphql.ArgumentConfig{
						Type: graphql.String,
					},
					"Properties": &graphql.ArgumentConfig{
						Description: "Transaction properties.",
						Type:        propertiesInput,
					},
				},
				Resolve: func(p graphql.ResolveParams) (interface{}, error) {
					bftx := bf_tx.BF_TX{}
					jsonProperties, err := json.Marshal(p.Args)
					if err = json.Unmarshal([]byte(jsonProperties), &bftx); err != nil {
						fmt.Printf("err")
						fmt.Print(err)
					}
					fmt.Printf("%+v\n", bftx)

					bftx, err = transaction.ConstructBfTx(bftx)
					if err != nil {
						return nil, err
					}

					return bftx, err
				},
			},
		},
	},
)

func executeQuery(query string, schema graphql.Schema) *graphql.Result {

	result := graphql.Do(graphql.Params{
		Schema:        schema,
		RequestString: query,
	})

	return result
}
<|endoftext|>