<commit_before>package main

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"os/exec"
	"reflect"
	"strconv"
)

// Function to run at CFG execution
type runfun func(n *node)

// Structure for AST and CFG
type node struct {
	child []*node      // child subtrees
	anc   *node        // ancestor
	start *node        // entry point in subtree (CFG)
	snext *node        // successor (CFG)
	next  [2]*node     // conditional successors, for false and for true (CFG)
	index int          // node index (dot display)
	run   runfun       // function to run at CFG execution
	val   *interface{} // pointer on generic value (CFG execution)
	ident string       // set if node is a var or func
	anode *ast.Node    // original ast node (temporary, will be removed)
}

// Interpreter execution state
type interp struct {
	entry *node // Execution entry point
}

// Returns true if node is a leaf in the AST
func (n *node) is_leaf() bool {
	return len((*n).child) == 0
}

// Walk AST in depth first order, call 'in' function at node entry and
// 'out' function at node exit
func walk(n *node, in func(n *node), out func(n *node)) {
	if in != nil {
		in(n)
	}
	for _, child := range n.child {
		walk(child, in, out)
	}
	if out != nil {
		out(n)
	}
}

// Wire AST nodes of sequential blocks
func wire_child(n *node) {
	println("wire_child", reflect.TypeOf(*n.anode).String(), n.index)
	for _, child := range n.child {
		if !child.is_leaf() {
			n.start = child.start
		}
	}
	if n.start == nil {
		println("fix self start", n.index)
		n.start = n
	}
	for i := 1; i < len(n.child); i++ {
		n.child[i-1].snext = n.child[i].start
	}
	for i := len(n.child) - 1; i >= 0; i-- {
		if !n.child[i].is_leaf() {
			println("wire next of", n.child[i].index, "to parent", n.index)
			n.child[i].snext = n
			break
		}
	}
}

// Generate a CFG from AST (wiring successors in AST)
func ast_to_cfg(root *node) {
	walk(root, nil, func(n *node) {
		switch x := (*n.anode).(type) {
		case *ast.BlockStmt:
			wire_child(n)
			// FIXME: could bypass this node at CFG and wire directly last child
			n.run = nop
			n.val = n.child[len(n.child)-1].val
			fmt.Println("block", n.index, n.start, n.snext)
		case *ast.IncDecStmt:
			wire_child(n)
			switch x.Tok {
			case token.INC:
				n.run = inc
			}
		case *ast.AssignStmt:
			n.run = assign
			wire_child(n)
		case *ast.ExprStmt:
			wire_child(n)
			// FIXME: could bypass this node at CFG and wire directly last child
			n.run = nop
			n.val = n.child[len(n.child)-1].val
		case *ast.ParenExpr:
			wire_child(n)
			// FIXME: could bypass this node at CFG and wire directly last child
			n.run = nop
			n.val = n.child[len(n.child)-1].val
		case *ast.BinaryExpr:
			wire_child(n)
			switch x.Op {
			case token.AND:
				n.run = and
			case token.EQL:
				n.run = equal
			case token.LSS:
				n.run = lower
			}
		case *ast.CallExpr:
			wire_child(n)
			n.run = call
		case *ast.IfStmt:
			n.run = nop
			n.start = n.child[0].start
			n.child[1].snext = n
			println("if nchild:", len(n.child))
			if len(n.child) == 3 {
				n.child[2].snext = n
			}
			n.child[0].next[1] = n.child[1].start
			if len(n.child) == 3 {
				n.child[0].next[0] = n.child[2].start
			} else {
				n.child[0].next[0] = n
			}
		case *ast.ForStmt:
			n.run = nop
			// FIXME: works only if for node has 4 children
			n.start = n.child[0].start
			n.child[0].snext = n.child[1].start
			n.child[1].next[0] = n
			n.child[1].next[1] = n.child[3].start
			n.child[3].snext = n.child[2].start
			n.child[2].snext = n.child[1].start
		case *ast.BasicLit:
			// FIXME: values must be converted to int or float if possible
			if v, err := strconv.ParseInt(x.Value, 0, 0); err == nil {
				*n.val = v
			} else {
				*n.val = x.Value
			}
		case *ast.Ident:
			n.ident = x.Name
		default:
			println("unknown type:", reflect.TypeOf(*n.anode).String())
		}
	})
}

// For debug: display an AST in graphviz dot(1) format using dotty(1) co-process
func astdot(root *node) {
	cmd := exec.Command("dotty", "-")
	dotin, err := cmd.StdinPipe()
	if err != nil {
		panic("dotty stdin error")
	}
	cmd.Start()
	fmt.Fprintf(dotin, "digraph ast {\n")
	walk(root, func(n *node) {
		var label string
		switch x := (*n.anode).(type) {
		case *ast.BasicLit:
			label = x.Value
		case *ast.Ident:
			label = x.Name
		case *ast.BinaryExpr:
			label = x.Op.String()
		case *ast.IncDecStmt:
			label = x.Tok.String()
		case *ast.AssignStmt:
			label = x.Tok.String()
		default:
			label = reflect.TypeOf(*n.anode).String()
		}
		fmt.Fprintf(dotin, "%d [label=\"%d: %s\"]\n", n.index, n.index, label)
		if n.anc != nil {
			fmt.Fprintf(dotin, "%d -> %d\n", n.anc.index, n.index)
		}
		//fmt.Printf("%v : %v\n", reflect.TypeOf(*n.anode), reflect.ValueOf(*n.anode))
	}, nil)
	fmt.Fprintf(dotin, "}")
}

// For debug: display a CFG in graphviz dot(1) format using dotty(1) co-process
func cfgdot(root *node) {
	cmd := exec.Command("dotty", "-")
	dotin, err := cmd.StdinPipe()
	if err != nil {
		panic("dotty stdin error")
	}
	cmd.Start()
	fmt.Fprintf(dotin, "digraph cfg {\n")
	walk(root, nil, func(n *node) {
		switch (*n.anode).(type) {
		case *ast.BasicLit:
			return
		case *ast.Ident:
			return
		}
		fmt.Fprintf(dotin, "%d [label=\"%d\"]\n", n.index, n.index)
		if n.next[1] != nil {
			fmt.Fprintf(dotin, "%d -> %d [color=green]\n", n.index, n.next[1].index)
		}
		if n.next[0] != nil {
			fmt.Fprintf(dotin, "%d -> %d [color=red]\n", n.index, n.next[0].index)
		}
		if n.next[0] == nil && n.next[1] == nil && n.snext != nil {
			fmt.Fprintf(dotin, "%d -> %d [color=purple]\n", n.index, n.snext.index)
		}
	})
	fmt.Fprintf(dotin, "}")
}

type nodestack []*node

func (s *nodestack) push(v *node) {
	*s = append(*s, v)
}

func (s *nodestack) pop() *node {
	l := len(*s) - 1
	res := (*s)[l]
	*s = (*s)[:l]
	return res
}

func (s *nodestack) top() *node {
	l := len(*s)
	if l > 0 {
		return (*s)[l-1]
	}
	return nil
}

// Functions run during execution of CFG
func assign(n *node) {
	name := n.child[0].ident   // symbol name is in the expr LHS
	sym[name] = n.child[1].val // Set symbol value
	n.child[0].val = sym[name]
	n.val = sym[name]
	fmt.Println(name, "=", *n.child[1].val, ":", *n.val)
}

func cond_branch(n *node) {
	if (*n.val).(bool) {
		n.snext = n.next[1]
	} else {
		n.snext = n.next[0]
	}
}

func and(n *node) {
	for _, child := range n.child {
		if child.ident != "" {
			child.val = sym[child.ident]
		}
	}
	*n.val = (*n.child[0].val).(int64) & (*n.child[1].val).(int64)
}

func printa(n []*node) {
	for _, m := range n {
		fmt.Printf("%v", *m.val)
	}
	fmt.Println("")
}

func call(n *node) {
	for _, child := range n.child {
		if child.ident != "" {
			child.val = sym[child.ident]
		}
	}
	switch n.child[0].ident {
	case "println":
		printa(n.child[1:])
	default:
		panic("function not implemented")
	}
}

func equal(n *node) {
	for _, child := range n.child {
		if child.ident != "" {
			child.val = sym[child.ident]
		}
	}
	*n.val = (*n.child[0].val).(int64) == (*n.child[1].val).(int64)
}

func inc(n *node) {
	n.child[0].val = sym[n.child[0].ident]
	*n.child[0].val = (*n.child[0].val).(int64) + 1
	*n.val = *n.child[0].val
}

func lower(n *node) {
	for _, child := range n.child {
		if child.ident != "" {
			child.val = sym[child.ident]
		}
	}
	*n.val = (*n.child[0].val).(int64) < (*n.child[1].val).(int64)
}

func nop(n *node) {}

// Parse src string containing go code and generate AST. Returns the root node
func src_to_ast(src string) *node {
	fset := token.NewFileSet() // positions are relative to fset
	f, err := parser.ParseFile(fset, "sample.go", src, 0)
	if err != nil {
		panic(err)
	}
	//ast.Print(fset, f)
	index := 0
	var root *node
	var anc *node
	var st nodestack
	// Populate our own private ast from go ast. A stack of ancestor nodes
	// is used to keep track of curent ancestor for each depth level
	ast.Inspect(f, func(n ast.Node) bool {
		anc = st.top()
		switch n.(type) {
		case nil:
			anc = st.pop()
		default:
			index++
			var i interface{}
			nod := &node{anc: anc, index: index, anode: &n, val: &i}
			if anc == nil {
				root = nod
			} else {
				anc.child = append(anc.child, nod)
			}
			st.push(nod)
		}
		return true
	})
	return root
}

func run_cfg(entry *node) {
	for n := entry; n != nil; {
		n.run(n)
		if n.snext != nil {
			n = n.snext
		} else if n.next[1] == nil && n.next[0] == nil {
			break
		} else if (*n.val).(bool) {
			n = n.next[1]
		} else {
			n = n.next[0]
		}
	}
}

// Symbol table (aka variables), just a global one to start.
// It should be organized in hierarchical scopes and frames
// and belong to an interpreter context.
var sym map[string]*interface{}

func main() {
	const src = `
package main

func main() {
	for a := 0; a < 20000000; a++ {
		if (a & 0x8ffff) == 0x80000 {
			println(a)
		}
	}
} `

	sym = make(map[string]*interface{})
	root := src_to_ast(src)
	cfg_entry := root.child[1].child[2] // FIXME: entry point should be resolved from 'main' name
	astdot(root)
	ast_to_cfg(cfg_entry)
	cfgdot(cfg_entry)
	run_cfg(cfg_entry.start)
}
<commit_msg>optimisation pass to reduce CFG<commit_after>package main

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"os/exec"
	"reflect"
	"strconv"
)

// Function to run at CFG execution
type runfun func(n *node)

// Structure for AST and CFG
type node struct {
	child []*node      // child subtrees
	anc   *node        // ancestor
	start *node        // entry point in subtree (CFG)
	snext *node        // successor (CFG)
	next  [2]*node     // conditional successors, for false and for true (CFG)
	index int          // node index (dot display)
	run   runfun       // function to run at CFG execution
	val   *interface{} // pointer on generic value (CFG execution)
	ident string       // set if node is a var or func
	isnop bool         // node is a no op
	anode *ast.Node    // original ast node (temporary, will be removed)
}

// Interpreter execution state
type interp struct {
	entry *node // Execution entry point
}

// Returns true if node is a leaf in the AST
func (n *node) is_leaf() bool {
	return len((*n).child) == 0
}

// Walk AST in depth first order, call 'in' function at node entry and
// 'out' function at node exit
func walk(n *node, in func(n *node), out func(n *node)) {
	if in != nil {
		in(n)
	}
	for _, child := range n.child {
		walk(child, in, out)
	}
	if out != nil {
		out(n)
	}
}

// Wire AST nodes of sequential blocks
func wire_child(n *node) {
	println("wire_child", reflect.TypeOf(*n.anode).String(), n.index)
	for _, child := range n.child {
		if !child.is_leaf() {
			n.start = child.start
		}
	}
	if n.start == nil {
		println("fix self start", n.index)
		n.start = n
	}
	for i := 1; i < len(n.child); i++ {
		n.child[i-1].snext = n.child[i].start
	}
	for i := len(n.child) - 1; i >= 0; i-- {
		if !n.child[i].is_leaf() {
			println("wire next of", n.child[i].index, "to parent", n.index)
			n.child[i].snext = n
			break
		}
	}
}

// Generate a CFG from AST (wiring successors in AST)
func ast_to_cfg(root *node) {
	walk(root, nil, func(n *node) {
		switch x := (*n.anode).(type) {
		case *ast.BlockStmt:
			wire_child(n)
			// FIXME: could bypass this node at CFG and wire directly last child
			n.isnop = true
			n.run = nop
			n.val = n.child[len(n.child)-1].val
			fmt.Println("block", n.index, n.start, n.snext)
		case *ast.IncDecStmt:
			wire_child(n)
			switch x.Tok {
			case token.INC:
				n.run = inc
			}
		case *ast.AssignStmt:
			n.run = assign
			wire_child(n)
		case *ast.ExprStmt:
			wire_child(n)
			// FIXME: could bypass this node at CFG and wire directly last child
			n.isnop = true
			n.run = nop
			n.val = n.child[len(n.child)-1].val
		case *ast.ParenExpr:
			wire_child(n)
			// FIXME: could bypass this node at CFG and wire directly last child
			n.isnop = true
			n.run = nop
			n.val = n.child[len(n.child)-1].val
		case *ast.BinaryExpr:
			wire_child(n)
			switch x.Op {
			case token.AND:
				n.run = and
			case token.EQL:
				n.run = equal
			case token.LSS:
				n.run = lower
			}
		case *ast.CallExpr:
			wire_child(n)
			n.run = call
		case *ast.IfStmt:
			n.isnop = true
			n.run = nop
			n.start = n.child[0].start
			n.child[1].snext = n
			println("if nchild:", len(n.child))
			if len(n.child) == 3 {
				n.child[2].snext = n
			}
			n.child[0].next[1] = n.child[1].start
			if len(n.child) == 3 {
				n.child[0].next[0] = n.child[2].start
			} else {
				n.child[0].next[0] = n
			}
		case *ast.ForStmt:
			n.isnop = true
			n.run = nop
			// FIXME: works only if for node has 4 children
			n.start = n.child[0].start
			n.child[0].snext = n.child[1].start
			n.child[1].next[0] = n
			n.child[1].next[1] = n.child[3].start
			n.child[3].snext = n.child[2].start
			n.child[2].snext = n.child[1].start
		case *ast.BasicLit:
			// FIXME: values must be converted to int or float if possible
			if v, err := strconv.ParseInt(x.Value, 0, 0); err == nil {
				*n.val = v
			} else {
				*n.val = x.Value
			}
		case *ast.Ident:
			n.ident = x.Name
		default:
			println("unknown type:", reflect.TypeOf(*n.anode).String())
		}
	})
}

// optimisation: rewire CFG to skip nop nodes
func optim_cfg(root *node) {
	walk(root, nil, func(n *node) {
		for s := n.snext; s != nil && s.snext != nil; s = s.snext {
			n.snext = s
		}
	})
}

// For debug: display an AST in graphviz dot(1) format using dotty(1) co-process
func astdot(root *node) {
	cmd := exec.Command("dotty", "-")
	dotin, err := cmd.StdinPipe()
	if err != nil {
		panic("dotty stdin error")
	}
	cmd.Start()
	fmt.Fprintf(dotin, "digraph ast {\n")
	walk(root, func(n *node) {
		var label string
		switch x := (*n.anode).(type) {
		case *ast.BasicLit:
			label = x.Value
		case *ast.Ident:
			label = x.Name
		case *ast.BinaryExpr:
			label = x.Op.String()
		case *ast.IncDecStmt:
			label = x.Tok.String()
		case *ast.AssignStmt:
			label = x.Tok.String()
		default:
			label = reflect.TypeOf(*n.anode).String()
		}
		fmt.Fprintf(dotin, "%d [label=\"%d: %s\"]\n", n.index, n.index, label)
		if n.anc != nil {
			fmt.Fprintf(dotin, "%d -> %d\n", n.anc.index, n.index)
		}
		//fmt.Printf("%v : %v\n", reflect.TypeOf(*n.anode), reflect.ValueOf(*n.anode))
	}, nil)
	fmt.Fprintf(dotin, "}")
}

// For debug: display a CFG in graphviz dot(1) format using dotty(1) co-process
func cfgdot(root *node) {
	cmd := exec.Command("dotty", "-")
	dotin, err := cmd.StdinPipe()
	if err != nil {
		panic("dotty stdin error")
	}
	cmd.Start()
	fmt.Fprintf(dotin, "digraph cfg {\n")
	walk(root, nil, func(n *node) {
		switch (*n.anode).(type) {
		case *ast.BasicLit:
			return
		case *ast.Ident:
			return
		}
		fmt.Fprintf(dotin, "%d [label=\"%d\"]\n", n.index, n.index)
		if n.next[1] != nil {
			fmt.Fprintf(dotin, "%d -> %d [color=green]\n", n.index, n.next[1].index)
		}
		if n.next[0] != nil {
			fmt.Fprintf(dotin, "%d -> %d [color=red]\n", n.index, n.next[0].index)
		}
		if n.next[0] == nil && n.next[1] == nil && n.snext != nil {
			fmt.Fprintf(dotin, "%d -> %d [color=purple]\n", n.index, n.snext.index)
		}
	})
	fmt.Fprintf(dotin, "}")
}

type nodestack []*node

func (s *nodestack) push(v *node) {
	*s = append(*s, v)
}

func (s *nodestack) pop() *node {
	l := len(*s) - 1
	res := (*s)[l]
	*s = (*s)[:l]
	return res
}

func (s *nodestack) top() *node {
	l := len(*s)
	if l > 0 {
		return (*s)[l-1]
	}
	return nil
}

// Functions run during execution of CFG
func assign(n *node) {
	name := n.child[0].ident   // symbol name is in the expr LHS
	sym[name] = n.child[1].val // Set symbol value
	n.child[0].val = sym[name]
	n.val = sym[name]
	fmt.Println(name, "=", *n.child[1].val, ":", *n.val)
}

func cond_branch(n *node) {
	if (*n.val).(bool) {
		n.snext = n.next[1]
	} else {
		n.snext = n.next[0]
	}
}

func and(n *node) {
	for _, child := range n.child {
		if child.ident != "" {
			child.val = sym[child.ident]
		}
	}
	*n.val = (*n.child[0].val).(int64) & (*n.child[1].val).(int64)
}

func printa(n []*node) {
	for _, m := range n {
		fmt.Printf("%v", *m.val)
	}
	fmt.Println("")
}

func call(n *node) {
	for _, child := range n.child {
		if child.ident != "" {
			child.val = sym[child.ident]
		}
	}
	switch n.child[0].ident {
	case "println":
		printa(n.child[1:])
	default:
		panic("function not implemented")
	}
}

func equal(n *node) {
	for _, child := range n.child {
		if child.ident != "" {
			child.val = sym[child.ident]
		}
	}
	*n.val = (*n.child[0].val).(int64) == (*n.child[1].val).(int64)
}

func inc(n *node) {
	n.child[0].val = sym[n.child[0].ident]
	*n.child[0].val = (*n.child[0].val).(int64) + 1
	*n.val = *n.child[0].val
}

func lower(n *node) {
	for _, child := range n.child {
		if child.ident != "" {
			child.val = sym[child.ident]
		}
	}
	*n.val = (*n.child[0].val).(int64) < (*n.child[1].val).(int64)
}

func nop(n *node) {}

// Parse src string containing go code and generate AST. Returns the root node
func src_to_ast(src string) *node {
	fset := token.NewFileSet() // positions are relative to fset
	f, err := parser.ParseFile(fset, "sample.go", src, 0)
	if err != nil {
		panic(err)
	}
	//ast.Print(fset, f)
	index := 0
	var root *node
	var anc *node
	var st nodestack
	// Populate our own private ast from go ast. A stack of ancestor nodes
	// is used to keep track of curent ancestor for each depth level
	ast.Inspect(f, func(n ast.Node) bool {
		anc = st.top()
		switch n.(type) {
		case nil:
			anc = st.pop()
		default:
			index++
			var i interface{}
			nod := &node{anc: anc, index: index, anode: &n, val: &i}
			if anc == nil {
				root = nod
			} else {
				anc.child = append(anc.child, nod)
			}
			st.push(nod)
		}
		return true
	})
	return root
}

func run_cfg(entry *node) {
	for n := entry; n != nil; {
		n.run(n)
		if n.snext != nil {
			n = n.snext
		} else if n.next[1] == nil && n.next[0] == nil {
			break
		} else if (*n.val).(bool) {
			n = n.next[1]
		} else {
			n = n.next[0]
		}
	}
}

// Symbol table (aka variables), just a global one to start.
// It should be organized in hierarchical scopes and frames
// and belong to an interpreter context.
var sym map[string]*interface{}

func main() {
	const src = `
package main

func main() {
	for a := 0; a < 20000000; a++ {
	//for a := 0; a < 20000; a++ {
		if (a & 0x8ffff) == 0x80000 {
		//if (a & 0x8ff) == 0x800 {
			println(a)
		}
	}
} `

	sym = make(map[string]*interface{})
	root := src_to_ast(src)
	cfg_entry := root.child[1].child[2] // FIXME: entry point should be resolved from 'main' name
	//astdot(root)
	ast_to_cfg(cfg_entry)
	//cfgdot(cfg_entry)
	optim_cfg(cfg_entry)
	//cfgdot(cfg_entry)
	run_cfg(cfg_entry.start)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/xml"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"text/tabwriter"
	"time"

	"github.com/fatih/color"
)

type Reporter interface {
	Init()

	Report(result []TestResult)

	Flush()
}

type ConsoleReporter struct {
	ExitCode int

	execFrame *TimeFrame

	total   int
	failed  int
	skipped int
}

func (r *ConsoleReporter) Init() {
	r.execFrame = &TimeFrame{Start: time.Now()}
}

func (r *ConsoleReporter) Report(results []TestResult) {

	for _, result := range results {
		r.total = r.total + 1

		if result.Skipped {
			r.reportSkipped(result)
			r.skipped = r.skipped + 1
			return
		}

		if result.Error != nil {
			r.failed = r.failed + 1
			r.reportError(result)
		} else {
			r.reportSuccess(result)
		}
	}
}

func (r ConsoleReporter) reportSuccess(result TestResult) {
	c := color.New(color.FgGreen).Add(color.Bold)
	fmt.Printf("[")
	c.Print("PASSED")
	fmt.Printf("]  %s - %s \t%s\n", result.Suite.FullName(), result.Case.Name, result.ExecFrame.Duration())
}

func (r ConsoleReporter) reportSkipped(result TestResult) {
	c := color.New(color.FgYellow).Add(color.Bold)
	fmt.Printf("[")
	c.Print("SKIPPED")
	fmt.Printf("] %s - %s", result.Suite.FullName(), result.Case.Name)
	if result.SkippedMsg != "" {
		reasonColor := color.New(color.FgMagenta)
		reasonColor.Printf("\t (%s)", result.SkippedMsg)
	}

	fmt.Printf("\n")
}

func (r ConsoleReporter) reportError(result TestResult) {
	c := color.New(color.FgRed).Add(color.Bold)
	fmt.Printf("[")
	c.Print("FAILED")
	fmt.Printf("]  %s - %s \n", result.Suite.FullName(), result.Case.Name)
	lines := strings.Split(result.Error.Cause.Error(), "\n")

	for _, line := range lines {
		fmt.Printf("\t\t%s \n", line)
	}
}

func (r ConsoleReporter) Flush() {
	r.execFrame.End = time.Now()

	overall := "PASSED"
	if r.failed != 0 {
		overall = "FAILED"
	}

	fmt.Println()
	fmt.Println("Test Run Summary")
	fmt.Println("-------------------------------")

	w := tabwriter.NewWriter(os.Stdout, 4, 2, 1, ' ', tabwriter.AlignRight)

	fmt.Fprintf(w, "Overall result:\t %s\n", overall)

	fmt.Fprintf(w, "Test count:\t %d\n", r.total)

	fmt.Fprintf(w, "Passed:\t %d \n", r.total-r.failed-r.skipped)
	fmt.Fprintf(w, "Failed:\t %d \n", r.failed)
	fmt.Fprintf(w, "Skipped:\t %d \n", r.skipped)

	start := r.execFrame.Start
	end := r.execFrame.End

	fmt.Fprintf(w, "Start time:\t %s\n", start)
	fmt.Fprintf(w, "End time:\t %s\n", end)
	fmt.Fprintf(w, "Duration:\t %s\n", end.Sub(start).String())

	w.Flush()
	fmt.Println()
}

// NewConsoleReporter returns new instance of console reporter
func NewConsoleReporter() Reporter {
	return &ConsoleReporter{ExitCode: 0}
}

// JUnitXMLReporter produces separate xml file for each test sute
type JUnitXMLReporter struct {
	// output directory
	OutPath string
}

func (r *JUnitXMLReporter) Init() {
	// nothing to do here
}

type suite struct {
	XMLName     string  `xml:"testsuite"`
	ID          int     `xml:"id,attr"`
	Name        string  `xml:"name,attr"`
	PackageName string  `xml:"package,attr"`
	TimeStamp   string  `xml:"timestamp,attr"`
	Time        float64 `xml:"time,attr"`
	HostName    string  `xml:"hostname,attr"`

	Tests    int `xml:"tests,attr"`
	Failures int `xml:"failures,attr"`
	Errors   int `xml:"errors,attr"`
	Skipped  int `xml:"skipped,attr"`

	Properties properties `xml:"properties"`
	Cases      []tc       `xml:"testcase"`

	SystemOut string `xml:"system-out"`
	SystemErr string `xml:"system-err"`

	fullName string
}

type properties struct {
}

type tc struct {
	Name      string   `xml:"name,attr"`
	ClassName string   `xml:"classname,attr"`
	Time      float64  `xml:"time,attr"`
	Failure   *failure `xml:"failure,omitempty"`
	Skipped   *skipped `xml:"skipped,omitempty"`
}

type failure struct {
	// not clear what type is but it's required
	Type    string `xml:"type,attr"`
	Message string `xml:"message,attr"`
	Details string `xml:",chardata"`
}

type skipped struct {
	Message string `xml:"message,attr"`
}

func (reporter *JUnitXMLReporter) Report(results []TestResult) {

	var suiteResult *suite
	var suiteTimeFrame TimeFrame
	for _, result := range results {

		if suiteResult == nil {
			suiteResult = &suite{
				ID:          0,
				Name:        result.Suite.Name,
				PackageName: result.Suite.PackageName(),
				TimeStamp:   time.Now().UTC().Format("2006-01-02T15:04:05.000Z"),
				fullName:    result.Suite.FullName(),
				HostName:    "localhost",
			}

			suiteTimeFrame = result.ExecFrame
		}

		testCase := tc{Name: result.Case.Name, ClassName: suiteResult.fullName, Time: result.ExecFrame.Duration().Seconds()}
		if result.Error != nil {
			testCase.Failure = &failure{Type: "FailedExpectation", Message: result.Error.Cause.Error()}
			testCase.Failure.Details = result.Error.Resp.ToString()
			suiteResult.Failures = suiteResult.Failures + 1
		}

		if result.Skipped {
			suiteResult.Skipped = suiteResult.Skipped + 1
			testCase.Skipped = &skipped{Message: result.SkippedMsg}
		}

		suiteResult.Tests = suiteResult.Tests + 1
		suiteResult.ID = suiteResult.ID + 1
		suiteResult.Cases = append(suiteResult.Cases, testCase)

		suiteTimeFrame.Extend(result.ExecFrame)
		suiteResult.Time = suiteTimeFrame.Duration().Seconds()
	}

	reporter.flushSuite(suiteResult)
}

func (r JUnitXMLReporter) flushSuite(suite *suite) {
	if suite == nil {
		return
	}

	fileName := suite.fullName + ".xml"
	fp := filepath.Join(r.OutPath, fileName)
	err := os.MkdirAll(r.OutPath, 0777)
	if err != nil {
		panic(err)
	}
	f, err := os.Create(fp)
	if err != nil {
		panic(err)
	}

	data, err := xml.Marshal(suite)
	if err != nil {
		panic(err)
	}

	f.Write(data)
}

func (r JUnitXMLReporter) Flush() {

}

func NewJUnitReporter(outdir string) Reporter {
	return &JUnitXMLReporter{OutPath: outdir}
}

// MultiReporter broadcasts events to another reporters.
type MultiReporter struct {
	Reporters []Reporter
}

func (r MultiReporter) Report(results []TestResult) {
	for _, reporter := range r.Reporters {
		reporter.Report(results)
	}
}

func (r MultiReporter) Init() {
	for _, reporter := range r.Reporters {
		reporter.Init()
	}
}

func (r MultiReporter) Flush() {
	for _, reporter := range r.Reporters {
		reporter.Flush()
	}
}

// NewMultiReporter creates new reporter that broadcasts events to another reporters.
func NewMultiReporter(reporters ...Reporter) Reporter {
	return &MultiReporter{Reporters: reporters}
}
<commit_msg>fix console reporter for skipped tests<commit_after>package main

import (
	"encoding/xml"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"text/tabwriter"
	"time"

	"github.com/fatih/color"
)

type Reporter interface {
	Init()

	Report(result []TestResult)

	Flush()
}

type ConsoleReporter struct {
	ExitCode int

	execFrame *TimeFrame

	total   int
	failed  int
	skipped int
}

func (r *ConsoleReporter) Init() {
	r.execFrame = &TimeFrame{Start: time.Now()}
}

func (r *ConsoleReporter) Report(results []TestResult) {

	for _, result := range results {
		r.total = r.total + 1

		if result.Skipped {
			r.reportSkipped(result)
			r.skipped = r.skipped + 1
			continue
		}

		if result.Error != nil {
			r.failed = r.failed + 1
			r.reportError(result)
		} else {
			r.reportSuccess(result)
		}
	}
}

func (r ConsoleReporter) reportSuccess(result TestResult) {
	c := color.New(color.FgGreen).Add(color.Bold)
	fmt.Printf("[")
	c.Print("PASSED")
	fmt.Printf("]  %s - %s \t%s\n", result.Suite.FullName(), result.Case.Name, result.ExecFrame.Duration())
}

func (r ConsoleReporter) reportSkipped(result TestResult) {
	c := color.New(color.FgYellow).Add(color.Bold)
	fmt.Printf("[")
	c.Print("SKIPPED")
	fmt.Printf("] %s - %s", result.Suite.FullName(), result.Case.Name)
	if result.SkippedMsg != "" {
		reasonColor := color.New(color.FgMagenta)
		reasonColor.Printf("\t (%s)", result.SkippedMsg)
	}

	fmt.Printf("\n")
}

func (r ConsoleReporter) reportError(result TestResult) {
	c := color.New(color.FgRed).Add(color.Bold)
	fmt.Printf("[")
	c.Print("FAILED")
	fmt.Printf("]  %s - %s \n", result.Suite.FullName(), result.Case.Name)
	lines := strings.Split(result.Error.Cause.Error(), "\n")

	for _, line := range lines {
		fmt.Printf("\t\t%s \n", line)
	}
}

func (r ConsoleReporter) Flush() {
	r.execFrame.End = time.Now()

	overall := "PASSED"
	if r.failed != 0 {
		overall = "FAILED"
	}

	fmt.Println()
	fmt.Println("Test Run Summary")
	fmt.Println("-------------------------------")

	w := tabwriter.NewWriter(os.Stdout, 4, 2, 1, ' ', tabwriter.AlignRight)

	fmt.Fprintf(w, "Overall result:\t %s\n", overall)

	fmt.Fprintf(w, "Test count:\t %d\n", r.total)

	fmt.Fprintf(w, "Passed:\t %d \n", r.total-r.failed-r.skipped)
	fmt.Fprintf(w, "Failed:\t %d \n", r.failed)
	fmt.Fprintf(w, "Skipped:\t %d \n", r.skipped)

	start := r.execFrame.Start
	end := r.execFrame.End

	fmt.Fprintf(w, "Start time:\t %s\n", start)
	fmt.Fprintf(w, "End time:\t %s\n", end)
	fmt.Fprintf(w, "Duration:\t %s\n", end.Sub(start).String())

	w.Flush()
	fmt.Println()
}

// NewConsoleReporter returns new instance of console reporter
func NewConsoleReporter() Reporter {
	return &ConsoleReporter{ExitCode: 0}
}

// JUnitXMLReporter produces separate xml file for each test sute
type JUnitXMLReporter struct {
	// output directory
	OutPath string
}

func (r *JUnitXMLReporter) Init() {
	// nothing to do here
}

type suite struct {
	XMLName     string  `xml:"testsuite"`
	ID          int     `xml:"id,attr"`
	Name        string  `xml:"name,attr"`
	PackageName string  `xml:"package,attr"`
	TimeStamp   string  `xml:"timestamp,attr"`
	Time        float64 `xml:"time,attr"`
	HostName    string  `xml:"hostname,attr"`

	Tests    int `xml:"tests,attr"`
	Failures int `xml:"failures,attr"`
	Errors   int `xml:"errors,attr"`
	Skipped  int `xml:"skipped,attr"`

	Properties properties `xml:"properties"`
	Cases      []tc       `xml:"testcase"`

	SystemOut string `xml:"system-out"`
	SystemErr string `xml:"system-err"`

	fullName string
}

type properties struct {
}

type tc struct {
	Name      string   `xml:"name,attr"`
	ClassName string   `xml:"classname,attr"`
	Time      float64  `xml:"time,attr"`
	Failure   *failure `xml:"failure,omitempty"`
	Skipped   *skipped `xml:"skipped,omitempty"`
}

type failure struct {
	// not clear what type is but it's required
	Type    string `xml:"type,attr"`
	Message string `xml:"message,attr"`
	Details string `xml:",chardata"`
}

type skipped struct {
	Message string `xml:"message,attr"`
}

func (reporter *JUnitXMLReporter) Report(results []TestResult) {

	var suiteResult *suite
	var suiteTimeFrame TimeFrame
	for _, result := range results {

		if suiteResult == nil {
			suiteResult = &suite{
				ID:          0,
				Name:        result.Suite.Name,
				PackageName: result.Suite.PackageName(),
				TimeStamp:   time.Now().UTC().Format("2006-01-02T15:04:05.000Z"),
				fullName:    result.Suite.FullName(),
				HostName:    "localhost",
			}

			suiteTimeFrame = result.ExecFrame
		}

		testCase := tc{Name: result.Case.Name, ClassName: suiteResult.fullName, Time: result.ExecFrame.Duration().Seconds()}
		if result.Error != nil {
			testCase.Failure = &failure{Type: "FailedExpectation", Message: result.Error.Cause.Error()}
			testCase.Failure.Details = result.Error.Resp.ToString()
			suiteResult.Failures = suiteResult.Failures + 1
		}

		if result.Skipped {
			suiteResult.Skipped = suiteResult.Skipped + 1
			testCase.Skipped = &skipped{Message: result.SkippedMsg}
		}

		suiteResult.Tests = suiteResult.Tests + 1
		suiteResult.ID = suiteResult.ID + 1
		suiteResult.Cases = append(suiteResult.Cases, testCase)

		suiteTimeFrame.Extend(result.ExecFrame)
		suiteResult.Time = suiteTimeFrame.Duration().Seconds()
	}

	reporter.flushSuite(suiteResult)
}

func (r JUnitXMLReporter) flushSuite(suite *suite) {
	if suite == nil {
		return
	}

	fileName := suite.fullName + ".xml"
	fp := filepath.Join(r.OutPath, fileName)
	err := os.MkdirAll(r.OutPath, 0777)
	if err != nil {
		panic(err)
	}
	f, err := os.Create(fp)
	if err != nil {
		panic(err)
	}

	data, err := xml.Marshal(suite)
	if err != nil {
		panic(err)
	}

	f.Write(data)
}

func (r JUnitXMLReporter) Flush() {

}

func NewJUnitReporter(outdir string) Reporter {
	return &JUnitXMLReporter{OutPath: outdir}
}

// MultiReporter broadcasts events to another reporters.
type MultiReporter struct {
	Reporters []Reporter
}

func (r MultiReporter) Report(results []TestResult) {
	for _, reporter := range r.Reporters {
		reporter.Report(results)
	}
}

func (r MultiReporter) Init() {
	for _, reporter := range r.Reporters {
		reporter.Init()
	}
}

func (r MultiReporter) Flush() {
	for _, reporter := range r.Reporters {
		reporter.Flush()
	}
}

// NewMultiReporter creates new reporter that broadcasts events to another reporters.
func NewMultiReporter(reporters ...Reporter) Reporter {
	return &MultiReporter{Reporters: reporters}
}
<|endoftext|>


<commit_before>package vizzini_test

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

	"github.com/onsi/say"
	"github.com/pivotal-golang/clock"
	"github.com/pivotal-golang/lager"
	"github.com/pivotal-golang/lager/lagertest"

	"github.com/nu7hatch/gouuid"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"testing"
	"time"

	"github.com/cloudfoundry-incubator/bbs"
	"github.com/cloudfoundry-incubator/bbs/models"
	"github.com/cloudfoundry-incubator/consuladapter"
)

var bbsClient bbs.Client
var serviceClient bbs.ServiceClient
var domain string
var otherDomain string
var defaultRootFS string
var guid string
var startTime time.Time

var bbsAddress string
var bbsCA string
var bbsClientCert string
var bbsClientKey string
var consulAddress string
var routableDomainSuffix string
var hostAddress string
var logger lager.Logger

var timeout time.Duration
var dockerTimeout time.Duration

func init() {
	flag.StringVar(&bbsAddress, "bbs-address", "http://10.244.16.130:8889", "http address for the bbs (required)")
	flag.StringVar(&bbsCA, "bbs-ca", "", "bbs ca cert")
	flag.StringVar(&bbsClientCert, "bbs-client-cert", "", "bbs client ssl certificate")
	flag.StringVar(&bbsClientKey, "bbs-client-key", "", "bbs client ssl key")
	flag.StringVar(&consulAddress, "consul-address", "http://127.0.0.1:8500", "http address for the consul agent (required)")
	flag.StringVar(&routableDomainSuffix, "routable-domain-suffix", "bosh-lite.com", "suffix to use when constructing FQDN")
	flag.StringVar(&hostAddress, "host-address", "10.0.2.2", "address that a process running in a container on Diego can use to reach the machine running this test.  Typically the gateway on the vagrant VM.")
	flag.Parse()

	if bbsAddress == "" {
		log.Fatal("i need a bbs address to talk to Diego...")
	}

	if consulAddress == "" {
		log.Fatal("i need a consul address to talk to Diego...")
	}
}

func TestVizziniSuite(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Vizzini Suite")
}

func NewGuid() string {
	u, err := uuid.NewV4()
	Ω(err).ShouldNot(HaveOccurred())
	return domain + "-" + u.String()[:8]
}

var _ = BeforeSuite(func() {
	timeout = 10 * time.Second
	dockerTimeout = 120 * time.Second

	timeoutArg := os.Getenv("DEFAULT_EVENTUALLY_TIMEOUT")
	if timeoutArg != "" {
		timeout, err := time.ParseDuration(timeoutArg)
		Ω(err).ShouldNot(HaveOccurred(), "invalid value '"+timeoutArg+"' for DEFAULT_EVENTUALLY_TIMEOUT")
		fmt.Printf("Setting Default Eventually Timeout to %s\n", timeout)
	}

	SetDefaultEventuallyTimeout(timeout)
	SetDefaultEventuallyPollingInterval(500 * time.Millisecond)
	SetDefaultConsistentlyPollingInterval(200 * time.Millisecond)
	domain = fmt.Sprintf("vizzini-%d", GinkgoParallelNode())
	otherDomain = fmt.Sprintf("vizzini-other-%d", GinkgoParallelNode())
	defaultRootFS = models.PreloadedRootFS("cflinuxfs2")

	var err error
	bbsClient = initializeBBSClient()

	consulClient, err := consuladapter.NewClient(consulAddress)
	Ω(err).ShouldNot(HaveOccurred())

	sessionMgr := consuladapter.NewSessionManager(consulClient)
	consulSession, err := consuladapter.NewSession("vizzini", 10*time.Second, consulClient, sessionMgr)
	Ω(err).ShouldNot(HaveOccurred())

	logger = lagertest.NewTestLogger("vizzini")

	serviceClient = bbs.NewServiceClient(consulSession, clock.NewClock())
})

var _ = BeforeEach(func() {
	startTime = time.Now()
	guid = NewGuid()
})

var _ = AfterEach(func() {
	defer func() {
		endTime := time.Now()
		fmt.Fprint(GinkgoWriter, say.Cyan("\n%s\nThis test referenced GUID %s\nStart time: %s (%d)\nEnd time: %s (%d)\n", CurrentGinkgoTestDescription().FullTestText, guid, startTime, startTime.Unix(), endTime, endTime.Unix()))
	}()

	for _, domain := range []string{domain, otherDomain} {
		ClearOutTasksInDomain(domain)
		ClearOutDesiredLRPsInDomain(domain)
	}
})

var _ = AfterSuite(func() {
	for _, domain := range []string{domain, otherDomain} {
		bbsClient.UpsertDomain(domain, 5*time.Minute) //leave the domain around forever so that Diego cleans up if need be
	}

	for _, domain := range []string{domain, otherDomain} {
		ClearOutDesiredLRPsInDomain(domain)
		ClearOutTasksInDomain(domain)
	}
})

func initializeBBSClient() bbs.Client {
	bbsURL, err := url.Parse(bbsAddress)
	Ω(err).ShouldNot(HaveOccurred())

	if bbsURL.Scheme != "https" {
		return bbs.NewClient(bbsAddress)
	}

	bbsClient, err := bbs.NewSecureClient(bbsAddress, bbsCA, bbsClientCert, bbsClientKey, 0, 0)
	Ω(err).ShouldNot(HaveOccurred())
	return bbsClient
}
<commit_msg>Default bbs-address flag to latest default BOSH-Lite database IP<commit_after>package vizzini_test

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

	"github.com/onsi/say"
	"github.com/pivotal-golang/clock"
	"github.com/pivotal-golang/lager"
	"github.com/pivotal-golang/lager/lagertest"

	"github.com/nu7hatch/gouuid"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"testing"
	"time"

	"github.com/cloudfoundry-incubator/bbs"
	"github.com/cloudfoundry-incubator/bbs/models"
	"github.com/cloudfoundry-incubator/consuladapter"
)

var bbsClient bbs.Client
var serviceClient bbs.ServiceClient
var domain string
var otherDomain string
var defaultRootFS string
var guid string
var startTime time.Time

var bbsAddress string
var bbsCA string
var bbsClientCert string
var bbsClientKey string
var consulAddress string
var routableDomainSuffix string
var hostAddress string
var logger lager.Logger

var timeout time.Duration
var dockerTimeout time.Duration

func init() {
	flag.StringVar(&bbsAddress, "bbs-address", "http://10.244.16.2:8889", "http address for the bbs (required)")
	flag.StringVar(&bbsCA, "bbs-ca", "", "bbs ca cert")
	flag.StringVar(&bbsClientCert, "bbs-client-cert", "", "bbs client ssl certificate")
	flag.StringVar(&bbsClientKey, "bbs-client-key", "", "bbs client ssl key")
	flag.StringVar(&consulAddress, "consul-address", "http://127.0.0.1:8500", "http address for the consul agent (required)")
	flag.StringVar(&routableDomainSuffix, "routable-domain-suffix", "bosh-lite.com", "suffix to use when constructing FQDN")
	flag.StringVar(&hostAddress, "host-address", "10.0.2.2", "address that a process running in a container on Diego can use to reach the machine running this test.  Typically the gateway on the vagrant VM.")
	flag.Parse()

	if bbsAddress == "" {
		log.Fatal("i need a bbs address to talk to Diego...")
	}

	if consulAddress == "" {
		log.Fatal("i need a consul address to talk to Diego...")
	}
}

func TestVizziniSuite(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Vizzini Suite")
}

func NewGuid() string {
	u, err := uuid.NewV4()
	Ω(err).ShouldNot(HaveOccurred())
	return domain + "-" + u.String()[:8]
}

var _ = BeforeSuite(func() {
	timeout = 10 * time.Second
	dockerTimeout = 120 * time.Second

	timeoutArg := os.Getenv("DEFAULT_EVENTUALLY_TIMEOUT")
	if timeoutArg != "" {
		timeout, err := time.ParseDuration(timeoutArg)
		Ω(err).ShouldNot(HaveOccurred(), "invalid value '"+timeoutArg+"' for DEFAULT_EVENTUALLY_TIMEOUT")
		fmt.Printf("Setting Default Eventually Timeout to %s\n", timeout)
	}

	SetDefaultEventuallyTimeout(timeout)
	SetDefaultEventuallyPollingInterval(500 * time.Millisecond)
	SetDefaultConsistentlyPollingInterval(200 * time.Millisecond)
	domain = fmt.Sprintf("vizzini-%d", GinkgoParallelNode())
	otherDomain = fmt.Sprintf("vizzini-other-%d", GinkgoParallelNode())
	defaultRootFS = models.PreloadedRootFS("cflinuxfs2")

	var err error
	bbsClient = initializeBBSClient()

	consulClient, err := consuladapter.NewClient(consulAddress)
	Ω(err).ShouldNot(HaveOccurred())

	sessionMgr := consuladapter.NewSessionManager(consulClient)
	consulSession, err := consuladapter.NewSession("vizzini", 10*time.Second, consulClient, sessionMgr)
	Ω(err).ShouldNot(HaveOccurred())

	logger = lagertest.NewTestLogger("vizzini")

	serviceClient = bbs.NewServiceClient(consulSession, clock.NewClock())
})

var _ = BeforeEach(func() {
	startTime = time.Now()
	guid = NewGuid()
})

var _ = AfterEach(func() {
	defer func() {
		endTime := time.Now()
		fmt.Fprint(GinkgoWriter, say.Cyan("\n%s\nThis test referenced GUID %s\nStart time: %s (%d)\nEnd time: %s (%d)\n", CurrentGinkgoTestDescription().FullTestText, guid, startTime, startTime.Unix(), endTime, endTime.Unix()))
	}()

	for _, domain := range []string{domain, otherDomain} {
		ClearOutTasksInDomain(domain)
		ClearOutDesiredLRPsInDomain(domain)
	}
})

var _ = AfterSuite(func() {
	for _, domain := range []string{domain, otherDomain} {
		bbsClient.UpsertDomain(domain, 5*time.Minute) //leave the domain around forever so that Diego cleans up if need be
	}

	for _, domain := range []string{domain, otherDomain} {
		ClearOutDesiredLRPsInDomain(domain)
		ClearOutTasksInDomain(domain)
	}
})

func initializeBBSClient() bbs.Client {
	bbsURL, err := url.Parse(bbsAddress)
	Ω(err).ShouldNot(HaveOccurred())

	if bbsURL.Scheme != "https" {
		return bbs.NewClient(bbsAddress)
	}

	bbsClient, err := bbs.NewSecureClient(bbsAddress, bbsCA, bbsClientCert, bbsClientKey, 0, 0)
	Ω(err).ShouldNot(HaveOccurred())
	return bbsClient
}
<|endoftext|>


<commit_before>package goalfred

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

// Arguments just wrappes the call to os.Args for better readability
func Arguments() []string {
	return os.Args[1:]
}

// NormalizedArguments re-normalizes the user arguments provided via Alfred.
// This isn't necessary for every workflow, specifically only when you're working with special characters.
// For more info on this topic, please refer to this thread: http://www.alfredforum.com/topic/2015-encoding-issue/
func NormalizedArguments() (normalizedArgs []string, err error) {
	for _, e := range Arguments() {
		var normalizedElement string
		normalizedElement, err = Normalize(e)
		if err != nil {
			return
		}
		normalizedArgs = append(normalizedArgs, normalizedElement)
	}
	return
}

// Response is the top level domain object.
// Create a new instance by calling NewResponse()
// Add items by calling AddItem on the response object
type Response struct {
	Items []Item `json:"items"`
}

// NewResponse initializes a new instance of Response
func NewResponse() *Response {
	r := new(Response)
	r.Items = []Item{}
	return r
}

// Print should be called last to output the result of the workflow to stdout.
func (r *Response) Print() {
	bytes, _ := json.Marshal(r)
	fmt.Println(string(bytes))
}

// AddItem adds a new Item to the response.
// The order in Alfred will be in the order how you add them.
func (r *Response) AddItem(item AlfredItem) *Response {
	i := item.Item()
	r.Items = append(r.Items, *i)
	return r
}
<commit_msg>Using continue instead of return<commit_after>package goalfred

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

// Arguments just wrappes the call to os.Args for better readability
func Arguments() []string {
	return os.Args[1:]
}

// NormalizedArguments re-normalizes the user arguments provided via Alfred.
// This isn't necessary for every workflow, specifically only when you're working with special characters.
// For more info on this topic, please refer to this thread: http://www.alfredforum.com/topic/2015-encoding-issue/
// Arguments that couldn't get normalized are not part of the return value!
func NormalizedArguments() (normalizedArgs []string, err error) {
	for _, e := range Arguments() {
		var normalizedElement string
		normalizedElement, err = Normalize(e)
		if err != nil {
			continue
		}
		normalizedArgs = append(normalizedArgs, normalizedElement)
	}
	return
}

// Response is the top level domain object.
// Create a new instance by calling NewResponse()
// Add items by calling AddItem on the response object
type Response struct {
	Items []Item `json:"items"`
}

// NewResponse initializes a new instance of Response
func NewResponse() *Response {
	r := new(Response)
	r.Items = []Item{}
	return r
}

// Print should be called last to output the result of the workflow to stdout.
func (r *Response) Print() {
	bytes, _ := json.Marshal(r)
	fmt.Println(string(bytes))
}

// AddItem adds a new Item to the response.
// The order in Alfred will be in the order how you add them.
func (r *Response) AddItem(item AlfredItem) *Response {
	i := item.Item()
	r.Items = append(r.Items, *i)
	return r
}
<|endoftext|>


<commit_before>package rest

import (
	"fmt"
	"github.com/golang/glog"
	"net/http"
	"sync"
)

func (this *engine) StreamServerEvents(resp http.ResponseWriter, req *http.Request,
	contentType, eventType, key string, source <-chan interface{}) error {

	sc, new := this.getSseChannel(contentType, eventType, key)
	if new {
		go func() {
			// connect the source
			for {
				if m, open := <-source; !open {
					glog.V(100).Infoln("Closing channel:", sc.Key)
					sc.Stop()
					this.deleteSseChannel(key)
					return
				} else {
					sc.messages <- m
				}
			}
		}()
	}
	sc.ServeHTTP(resp, req)
	return nil
}

func (this *engine) Stop() {
	for _, s := range this.sseChannels {
		s.stop <- 1
	}
}

func (this *engine) deleteSseChannel(key string) {
	this.lock.Lock()
	defer this.lock.Unlock()
	delete(this.sseChannels, key)
	glog.Infoln("Removed sse channel", key, "count=", len(this.sseChannels))
}

func (this *engine) getSseChannel(contentType, eventType, key string) (*sseChannel, bool) {
	this.lock.Lock()
	defer this.lock.Unlock()

	if c, has := this.sseChannels[key]; has {
		return c, false
	} else {
		c = &sseChannel{
			Key:         key,
			ContentType: contentType,
			EventType:   eventType,
			engine:      this,
		}
		c.Init().Start()
		this.sseChannels[key] = c
		return c, true
	}
}

type event_client chan interface{}

type sseChannel struct {
	Key string

	ContentType string
	EventType   string

	engine *engine
	lock   sync.Mutex

	// Send to this to stop
	stop chan int

	clients map[event_client]int

	// Channel into which new clients can be pushed
	newClients chan event_client

	// Channel into which disconnected clients should be pushed
	defunctClients chan event_client

	// Channel into which messages are pushed to be broadcast out
	// to attahed clients.
	messages chan interface{}
}

func (this *sseChannel) Init() *sseChannel {
	this.stop = make(chan int)
	this.clients = make(map[event_client]int)
	this.newClients = make(chan event_client)
	this.defunctClients = make(chan event_client)
	this.messages = make(chan interface{})
	return this
}

func (this *sseChannel) Stop() {
	glog.V(100).Infoln("Stopping channel", this.Key)

	if this.stop == nil {
		glog.V(100).Infoln("Stopped.")
		return
	}

	this.lock.Lock()
	defer this.lock.Unlock()

	glog.V(100).Infoln("Closing stop")
	close(this.stop)
	this.stop = nil

	glog.V(100).Infoln("Closing messages")
	close(this.messages)
	// stop all clients
	for c, _ := range this.clients {
		glog.V(100).Infoln("Closing event client", c)
		close(c)
	}
	this.engine.deleteSseChannel(this.Key)
}

func (this *sseChannel) Start() *sseChannel {
	go func() {
		defer glog.Infoln("Channel", this.Key, "Stopped.")
		for {
			select {

			case s := <-this.newClients:
				this.lock.Lock()
				this.clients[s] = 1
				this.lock.Unlock()
				glog.V(100).Infoln("Added new client:", s)

			case s := <-this.defunctClients:
				this.lock.Lock()
				delete(this.clients, s)
				this.lock.Unlock()
				close(s)
				glog.V(100).Infoln("Removed client:", s)

			case _, open := <-this.stop:
				if open {
					glog.V(100).Infoln("Received stop.", this.Key)
					this.Stop()
				} else {
					glog.V(100).Infoln("Stopping channel loop.", this.Key)
					return
				}
			default:
				msg, open := <-this.messages
				if !open || msg == nil {
					for s, _ := range this.clients {
						this.defunctClients <- s
					}
					this.stop <- 1
				} else {
					// There is a new message to send.  For each
					// attached client, push the new message
					// into the client's message channel.
					for s, _ := range this.clients {
						s <- msg
					}
				}
			}
		}
	}()
	return this
}

// TODO - return and disconnect client
func (this *sseChannel) ServeHTTP(w http.ResponseWriter, r *http.Request) {

	// Make sure that the writer supports flushing.
	f, ok := w.(http.Flusher)
	if !ok {
		http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
		return
	}

	// Create a new channel, over which the broker can
	// send this client messages.
	messageChan := make(event_client)

	// Add this client to the map of those that should
	// receive updates
	this.newClients <- messageChan

	// Listen to the closing of the http connection via the CloseNotifier
	notify := w.(http.CloseNotifier).CloseNotify()
	go func() {
		<-notify
		// Remove this client from the map of attached clients
		// when `EventHandler` exits.
		this.defunctClients <- messageChan
		glog.V(100).Infoln("HTTP connection just closed.")
	}()

	// Set the headers related to event streaming.
	w.Header().Set("Content-Type", "text/event-stream")
	w.Header().Set("Cache-Control", "no-cache")
	w.Header().Set("Connection", "keep-alive")

	for {

		// Read from our messageChan.
		msg, open := <-messageChan

		if !open || msg == nil {
			// If our messageChan was closed, this means that the client has
			// disconnected.
			glog.V(100).Infoln("Messages stopped.. Closing http connection")
			break
		}

		switch this.ContentType {
		case "application/json":
			fmt.Fprintf(w, "event: %s\n", this.EventType)
			fmt.Fprint(w, "data: ")
			json_marshaler(this.ContentType, w, &msg, no_header)
			fmt.Fprint(w, "\n\n")
		case "text/plain":
			fmt.Fprintf(w, "%s\n", msg)
		default:
			if m, ok := marshalers[this.ContentType]; ok {
				fmt.Fprintf(w, "event: %s\n", this.EventType)
				fmt.Fprint(w, "data: ")
				m(this.ContentType, w, &msg, no_header)
				fmt.Fprint(w, "\n\n")
			}
		}

		// Flush the response.  This is only possible if
		// the repsonse supports streaming.
		f.Flush()
	}

	// Done.
	glog.V(100).Infoln("Finished HTTP request at ", r.URL.Path, "num_channels=", len(this.engine.sseChannels))
}
<commit_msg>Logging / stopping of channels for server sent events<commit_after>package rest

import (
	"fmt"
	"github.com/golang/glog"
	"net/http"
	"sync"
)

func (this *engine) StreamServerEvents(resp http.ResponseWriter, req *http.Request,
	contentType, eventType, key string, source <-chan interface{}) error {

	sc, new := this.getSseChannel(contentType, eventType, key)
	if new {
		go func() {
			// connect the source
			for {
				if m, open := <-source; !open {
					glog.V(100).Infoln("Closing channel:", sc.Key)
					sc.Stop()
					this.deleteSseChannel(key)
					return
				} else {
					sc.messages <- m
				}
			}
		}()
	}
	sc.ServeHTTP(resp, req)
	return nil
}

func (this *engine) Stop() {
	for _, s := range this.sseChannels {
		s.stop <- 1
	}
}

func (this *engine) deleteSseChannel(key string) {
	this.lock.Lock()
	defer this.lock.Unlock()
	delete(this.sseChannels, key)
	glog.Infoln("Removed sse channel", key, "count=", len(this.sseChannels))
}

func (this *engine) getSseChannel(contentType, eventType, key string) (*sseChannel, bool) {
	this.lock.Lock()
	defer this.lock.Unlock()

	if c, has := this.sseChannels[key]; has {
		return c, false
	} else {
		c = &sseChannel{
			Key:         key,
			ContentType: contentType,
			EventType:   eventType,
			engine:      this,
		}
		c.Init().Start()
		this.sseChannels[key] = c
		return c, true
	}
}

type event_client chan interface{}

type sseChannel struct {
	Key string

	ContentType string
	EventType   string

	engine *engine
	lock   sync.Mutex

	// Send to this to stop
	stop chan int

	clients map[event_client]int

	// Channel into which new clients can be pushed
	newClients chan event_client

	// Channel into which disconnected clients should be pushed
	defunctClients chan event_client

	// Channel into which messages are pushed to be broadcast out
	// to attahed clients.
	messages chan interface{}
}

func (this *sseChannel) Init() *sseChannel {
	this.stop = make(chan int)
	this.clients = make(map[event_client]int)
	this.newClients = make(chan event_client)
	this.defunctClients = make(chan event_client)
	this.messages = make(chan interface{})
	return this
}

func (this *sseChannel) Stop() {
	glog.V(100).Infoln("Stopping channel", this.Key)

	if this.stop == nil {
		glog.V(100).Infoln("Stopped.")
		return
	}

	this.lock.Lock()
	defer this.lock.Unlock()

	glog.V(100).Infoln("Closing stop", this.Key)
	close(this.stop)
	this.stop = nil

	glog.V(100).Infoln("Closing messages", this.Key)
	close(this.messages)
	// stop all clients
	for c, _ := range this.clients {
		glog.V(100).Infoln("Closing event client", c)
		close(c)
	}
	this.engine.deleteSseChannel(this.Key)
}

func (this *sseChannel) Start() *sseChannel {
	go func() {
		defer glog.Infoln("Channel", this.Key, "Stopped.")
		for {
			select {

			case s := <-this.newClients:
				this.lock.Lock()
				this.clients[s] = 1
				this.lock.Unlock()
				glog.V(100).Infoln("Added new client:", s)

			case s := <-this.defunctClients:
				this.lock.Lock()
				delete(this.clients, s)
				this.lock.Unlock()
				close(s)
				glog.V(100).Infoln("Removed client:", s)

			case _, open := <-this.stop:
				if open {
					glog.V(100).Infoln("Received stop.", this.Key)
					this.Stop()
				} else {
					glog.V(100).Infoln("Stopping channel loop.", this.Key)
					return
				}
			default:
				msg, open := <-this.messages
				if !open || msg == nil {
					for s, _ := range this.clients {
						this.defunctClients <- s
					}
					this.stop <- 1

					glog.V(100).Infoln("Channel loop stopped", this.Key)
					return // stop this
				} else {
					// There is a new message to send.  For each
					// attached client, push the new message
					// into the client's message channel.
					for s, _ := range this.clients {
						s <- msg
					}
				}
			}
		}
	}()
	return this
}

// TODO - return and disconnect client
func (this *sseChannel) ServeHTTP(w http.ResponseWriter, r *http.Request) {

	// Make sure that the writer supports flushing.
	f, ok := w.(http.Flusher)
	if !ok {
		http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
		return
	}

	// Create a new channel, over which the broker can
	// send this client messages.
	messageChan := make(event_client)

	// Add this client to the map of those that should
	// receive updates
	this.newClients <- messageChan

	// Listen to the closing of the http connection via the CloseNotifier
	notify := w.(http.CloseNotifier).CloseNotify()
	go func() {
		<-notify
		// Remove this client from the map of attached clients
		// when `EventHandler` exits.
		this.defunctClients <- messageChan
		glog.V(100).Infoln("HTTP connection just closed.")
	}()

	// Set the headers related to event streaming.
	w.Header().Set("Content-Type", "text/event-stream")
	w.Header().Set("Cache-Control", "no-cache")
	w.Header().Set("Connection", "keep-alive")

	for {

		// Read from our messageChan.
		msg, open := <-messageChan

		if !open || msg == nil {
			// If our messageChan was closed, this means that the client has
			// disconnected.
			glog.V(100).Infoln("Messages stopped.. Closing http connection")
			break
		}

		switch this.ContentType {
		case "application/json":
			fmt.Fprintf(w, "event: %s\n", this.EventType)
			fmt.Fprint(w, "data: ")
			json_marshaler(this.ContentType, w, &msg, no_header)
			fmt.Fprint(w, "\n\n")
		case "text/plain":
			fmt.Fprintf(w, "%s\n", msg)
		default:
			if m, ok := marshalers[this.ContentType]; ok {
				fmt.Fprintf(w, "event: %s\n", this.EventType)
				fmt.Fprint(w, "data: ")
				m(this.ContentType, w, &msg, no_header)
				fmt.Fprint(w, "\n\n")
			}
		}

		// Flush the response.  This is only possible if
		// the repsonse supports streaming.
		f.Flush()
	}

	// Done.
	glog.V(100).Infoln("Finished HTTP request at ", r.URL.Path, "num_channels=", len(this.engine.sseChannels))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
	"time"

	"github.com/DimShadoWWW/power-pg/proxy"
	"github.com/parnurzeal/gorequest"
)

var (
	localHost     = flag.String("l", ":9876", "Endereço e porta do listener local")
	remoteHost    = flag.String("r", "localhost:5432", "Endereço e porta do servidor PostgreSQL")
	remoteService = flag.String("s", "", "http://localhost:8080/query")
	messages      = []string{}
)

func main() {
	flag.Parse()
	msgs := make(chan string)
	msgCh := make(chan proxy.Pkg)
	if *remoteService != "" {
		go func() {
			time.Sleep(time.Second * 3)
			_, _, errs := gorequest.New().Get(*remoteService).End()
			if errs != nil {
				log.Fatalf("log failed: %v", errs)
			}
			log.Println("done")
			os.Exit(0)
		}()
	}

	go func() {
		for msg := range msgs {
			fmt.Println(msg)
		}
	}()

	go func() {
		temp := ""
		for msg := range msgCh {
			if msg.Type == 'P' && strings.Contains(string(msg.Content), "$1") {
				sep := []byte{0, 1, 0, 0}
				i := strings.Index(string(msg.Content), string(sep))
				temp = string(msg.Content[i : len(msg.Content)-4])
				fmt.Printf("SEP index ----->%v\n", i)
				fmt.Printf("SEP len   ----->%v\n", len(msg.Content))
				fmt.Printf("SEP CONT  ----->%v\n", msg.Content)
			} else {
				if msg.Type == 'B' && len(msg.Content) > 28 && temp != "" {
					messages = append(messages, strings.Replace(temp, "$1", fmt.Sprintf("'%s'", string(msg.Content[29:len(msg.Content)-4])), -1))
				}
				temp = ""
			}
			fmt.Printf("---------->%v\n", messages)
			fmt.Printf("---------->%#v\n", messages)
		}
	}()

	proxy.Start(localHost, remoteHost, getQueryModificada, msgs, msgCh)
}

func getQueryModificada(queryOriginal string) string {
	// log.Println("aa")
	// if queryOriginal[:5] != "power" {
	// 	return queryOriginal
	// }

	// log.Println(queryOriginal)
	fmt.Println(queryOriginal)
	return queryOriginal
}
<commit_msg>Update<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
	"time"

	"github.com/DimShadoWWW/power-pg/proxy"
	"github.com/parnurzeal/gorequest"
)

var (
	localHost     = flag.String("l", ":9876", "Endereço e porta do listener local")
	remoteHost    = flag.String("r", "localhost:5432", "Endereço e porta do servidor PostgreSQL")
	remoteService = flag.String("s", "", "http://localhost:8080/query")
	messages      = []string{}
)

func main() {
	flag.Parse()
	msgs := make(chan string)
	msgCh := make(chan proxy.Pkg)
	if *remoteService != "" {
		go func() {
			time.Sleep(time.Second * 3)
			_, _, errs := gorequest.New().Get(*remoteService).End()
			if errs != nil {
				log.Fatalf("log failed: %v", errs)
			}
			log.Println("done")
			os.Exit(0)
		}()
	}

	go func() {
		for msg := range msgs {
			fmt.Println(msg)
		}
	}()

	go func() {
		temp := ""
		for msg := range msgCh {
			if msg.Type == 'P' && strings.Contains(string(msg.Content), "$1") {
				selectIdx := strings.Index(string(msg.Content), string([]byte{83, 69, 76, 69, 67, 84, 32}))
				if selectIdx == -1 {
					selectIdx = 0
				}
				sepIdx := strings.Index(string(msg.Content), string([]byte{0, 1, 0, 0}))
				if sepIdx == -1 {
					sepIdx = len(msg.Content) - 4
				}
				temp = string(msg.Content[selectIdx:sepIdx])
				fmt.Printf("SEP index ----->%v\n", sepIdx)
				fmt.Printf("SEP len   ----->%v\n", len(msg.Content))
				fmt.Printf("SEP CONT  ----->%v\n", msg.Content)
			} else {
				if msg.Type == 'B' && len(msg.Content) > 28 && temp != "" {
					messages = append(messages, strings.Replace(temp, "$1", fmt.Sprintf("'%s'", string(msg.Content[29:len(msg.Content)-4])), -1))
				}
				temp = ""
			}
			fmt.Printf("---------->%v\n", messages)
			fmt.Printf("---------->%#v\n", messages)
		}
	}()

	proxy.Start(localHost, remoteHost, getQueryModificada, msgs, msgCh)
}

func getQueryModificada(queryOriginal string) string {
	// log.Println("aa")
	// if queryOriginal[:5] != "power" {
	// 	return queryOriginal
	// }

	// log.Println(queryOriginal)
	fmt.Println(queryOriginal)
	return queryOriginal
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
	"time"

	"github.com/DimShadoWWW/power-pg/proxy"
	"github.com/parnurzeal/gorequest"
)

var (
	localHost     = flag.String("l", ":9876", "Endereço e porta do listener local")
	remoteHost    = flag.String("r", "localhost:5432", "Endereço e porta do servidor PostgreSQL")
	remoteService = flag.String("s", "", "http://localhost:8080/query")
	messages      = []string{}
)

func main() {
	flag.Parse()
	msgs := make(chan string)
	msgCh := make(chan proxy.Pkg)
	if *remoteService != "" {
		go func() {
			time.Sleep(time.Second * 3)
			_, _, errs := gorequest.New().Get(*remoteService).End()
			if errs != nil {
				log.Fatalf("log failed: %v", errs)
			}
			log.Println("done")
			os.Exit(0)
		}()
	}

	go func() {
		for msg := range msgs {
			fmt.Println(msg)
		}
	}()

	go func() {
		temp := ""
		for msg := range msgCh {
			if msg.Type == 'P' {
				if strings.Contains(string(msg.Content), "$1") {
					selectIdx := strings.Index(string(msg.Content), string([]byte{83, 69, 76, 69, 67, 84, 32}))
					if selectIdx == -1 {
						selectIdx = 0
					}
					sepIdx := strings.Index(string(msg.Content), string([]byte{0, 1, 0, 0}))
					if sepIdx == -1 {
						sepIdx = len(msg.Content) - 4
					}
					temp = string(msg.Content[selectIdx:sepIdx])
					fmt.Printf("SEP index ----->%v\n", sepIdx)
					fmt.Printf("SEP len   ----->%v\n", len(msg.Content))
					fmt.Printf("SEP CONT  ----->%v\n", msg.Content)
				} else {
					temp = ""
					selectIdx := strings.Index(string(msg.Content), string([]byte{83, 69, 76, 69, 67, 84, 32}))
					if selectIdx == -1 {
						selectIdx = 0
					}
					sepIdx := strings.Index(string(msg.Content), string([]byte{0, 0, 1, 0, 0}))
					if sepIdx == -1 || sepIdx+5 > len(msg.Content) {
						sepIdx := strings.Index(string(msg.Content), string([]byte{0, 1, 0, 0}))
						if sepIdx == -1 || sepIdx+4 > len(msg.Content) {
							sepIdx = len(msg.Content) - 4
						} else {
							sepIdx = len(msg.Content)
						}
					}
					messages = append(messages, string(msg.Content[selectIdx:sepIdx]))
				}
			} else {
				if msg.Type == 'B' && len(msg.Content) > 28 && temp != "" {
					messages = append(messages, strings.Replace(temp, "$1", fmt.Sprintf("'%s'", string(msg.Content[29:len(msg.Content)-4])), -1))
				}
				temp = ""
			}
			fmt.Printf("---------->%v\n", messages)
			fmt.Printf("---------->%#v\n", messages)
		}
	}()

	proxy.Start(localHost, remoteHost, getQueryModificada, msgs, msgCh)
}

func getQueryModificada(queryOriginal string) string {
	// log.Println("aa")
	// if queryOriginal[:5] != "power" {
	// 	return queryOriginal
	// }

	// log.Println(queryOriginal)
	fmt.Println(queryOriginal)
	return queryOriginal
}
<commit_msg>Update<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
	"time"

	"github.com/DimShadoWWW/power-pg/proxy"
	"github.com/parnurzeal/gorequest"
)

var (
	localHost     = flag.String("l", ":9876", "Endereço e porta do listener local")
	remoteHost    = flag.String("r", "localhost:5432", "Endereço e porta do servidor PostgreSQL")
	remoteService = flag.String("s", "", "http://localhost:8080/query")
	messages      = []string{}
)

func main() {
	flag.Parse()
	msgs := make(chan string)
	msgCh := make(chan proxy.Pkg)
	if *remoteService != "" {
		go func() {
			time.Sleep(time.Second * 3)
			_, _, errs := gorequest.New().Get(*remoteService).End()
			if errs != nil {
				log.Fatalf("log failed: %v", errs)
			}
			log.Println("done")
			os.Exit(0)
		}()
	}

	go func() {
		for msg := range msgs {
			fmt.Println(msg)
		}
	}()

	go func() {
		temp := ""
		for msg := range msgCh {
			if msg.Type == 'P' {
				if strings.Contains(string(msg.Content), "$1") {
					selectIdx := strings.Index(string(msg.Content), string([]byte{83, 69, 76, 69, 67, 84, 32}))
					if selectIdx == -1 {
						selectIdx = 0
					}
					sepIdx := strings.Index(string(msg.Content), string([]byte{0, 1, 0, 0}))
					if sepIdx == -1 {
						sepIdx = len(msg.Content) - 4
					}
					temp = string(msg.Content[selectIdx:sepIdx])
					fmt.Printf("SEP index ----->%v\n", sepIdx)
					fmt.Printf("SEP len   ----->%v\n", len(msg.Content))
					fmt.Printf("SEP CONT  ----->%v\n", msg.Content)
				} else {
					temp = ""
					selectIdx := strings.Index(string(msg.Content), string([]byte{83, 69, 76, 69, 67, 84, 32}))
					if selectIdx == -1 {
						selectIdx = 0
					}
					sepIdx := strings.Index(string(msg.Content), string([]byte{0, 0, 1, 0, 0}))
					if sepIdx == -1 || sepIdx+5 > len(msg.Content) {
						sepIdx := strings.Index(string(msg.Content), string([]byte{0, 1, 0, 0}))
						if sepIdx == -1 || sepIdx+4 > len(msg.Content) {
							sepIdx = len(msg.Content) - 4
						} else {
							sepIdx = len(msg.Content) - 1
						}
					}
					messages = append(messages, string(msg.Content[selectIdx:sepIdx]))
				}
			} else {
				if msg.Type == 'B' && len(msg.Content) > 28 && temp != "" {
					messages = append(messages, strings.Replace(temp, "$1", fmt.Sprintf("'%s'", string(msg.Content[29:len(msg.Content)-4])), -1))
				}
				temp = ""
			}
			fmt.Printf("---------->%v\n", messages)
			fmt.Printf("---------->%#v\n", messages)
		}
	}()

	proxy.Start(localHost, remoteHost, getQueryModificada, msgs, msgCh)
}

func getQueryModificada(queryOriginal string) string {
	// log.Println("aa")
	// if queryOriginal[:5] != "power" {
	// 	return queryOriginal
	// }

	// log.Println(queryOriginal)
	fmt.Println(queryOriginal)
	return queryOriginal
}
<|endoftext|>


<commit_before>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package updater

import "time"

// Asset describes a downloadable file
type Asset struct {
	Name      string `codec:"name" json:"name"`
	URL       string `codec:"url" json:"url"`
	Digest    string `codec:"digest" json:"digest"`
	Signature string `codec:"signature" json:"signature"`
	LocalPath string `codec:"localPath" json:"localPath"`
}

// UpdateType is the update type.
// This is an int type for compatibility.
type UpdateType int

const (
	// UpdateTypeNormal is a normal update
	UpdateTypeNormal UpdateType = 0
	// UpdateTypeBugFix is a bugfix update
	UpdateTypeBugFix UpdateType = 1
	// UpdateTypeCritical is a critical update
	UpdateTypeCritical UpdateType = 2
)

// Update defines an update to apply
type Update struct {
	Version     string     `json:"version"`
	Name        string     `json:"name"`
	Description string     `json:"description"`
	InstallID   string     `json:"installId"`
	Type        UpdateType `json:"type"`
	PublishedAt Time       `json:"publishedAt"`
	Asset       *Asset     `json:"asset,omitempty"`
}

// UpdateOptions are options used to find an update
type UpdateOptions struct {
	// Version is the current version of the app
	Version string `json:"version"`
	// Platform is the os type (darwin, windows, linux)
	Platform string `json:"platform"`
	// DestinationPath is where to apply the update to
	DestinationPath string `json:"destinationPath"`
	// URL can override where the updater looks
	URL string `json:"URL"`
	// Channel is an alternative channel to get updates from (test, prerelease)
	Channel string `json:"channel"`
	// Env is an environment or run mode (prod, staging, devel)
	Env string `json:"env"`
	// InstallID is an identifier that the client can send with requests
	InstallID string `json:"installId"`
	// Arch is an architecure description (x64, i386, arm)
	Arch string `json:"arch"`
	// Force is whether to apply the update, even if older or same version
	Force bool `json:"force"`
	// OSVersion is the version of the OS
	OSVersion string `json:"osVersion"`
	// UpdaterVersion is the version of the updater service
	UpdaterVersion string `json:"updaterVersion"`
}

// UpdateAction is the update action requested by the user
type UpdateAction string

const (
	// UpdateActionApply means the user accepted and to perform update
	UpdateActionApply UpdateAction = "apply"
	// UpdateActionAuto means that auto update is set and to perform update
	UpdateActionAuto UpdateAction = "auto"
	// UpdateActionSnooze snoozes an update
	UpdateActionSnooze UpdateAction = "snooze"
	// UpdateActionCancel cancels an update
	UpdateActionCancel UpdateAction = "cancel"
	// UpdateActionError means an error occurred
	UpdateActionError UpdateAction = "error"
)

// String is a unique string label for the action
func (u UpdateAction) String() string {
	return string(u)
}

// UpdatePromptOptions are the options for UpdatePrompt
type UpdatePromptOptions struct {
	AutoUpdate bool `json:"autoUpdate"`
}

// UpdatePromptResponse is the result for UpdatePrompt
type UpdatePromptResponse struct {
	Action     UpdateAction `json:"action"`
	AutoUpdate bool         `json:"autoUpdate"`
}

// UpdateUI is a UI interface
type UpdateUI interface {
	// UpdatePrompt prompts for an update
	UpdatePrompt(Update, UpdateOptions, UpdatePromptOptions) (*UpdatePromptResponse, error)
}

// Time is milliseconds since epoch
type Time int64

// FromTime converts protocol time to golang Time
func FromTime(t Time) time.Time {
	if t == 0 {
		return time.Time{}
	}
	return time.Unix(0, int64(t)*1000000)
}

// ToTime converts golang Time to protocol Time
func ToTime(t time.Time) Time {
	// the result of calling UnixNano on the zero Time is undefined.
	// https://golang.org/pkg/time/#Time.UnixNano
	if t.IsZero() {
		return 0
	}
	return Time(t.UnixNano() / 1000000)
}
<commit_msg>Remove dead code<commit_after>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package updater

// Asset describes a downloadable file
type Asset struct {
	Name      string `codec:"name" json:"name"`
	URL       string `codec:"url" json:"url"`
	Digest    string `codec:"digest" json:"digest"`
	Signature string `codec:"signature" json:"signature"`
	LocalPath string `codec:"localPath" json:"localPath"`
}

// UpdateType is the update type.
// This is an int type for compatibility.
type UpdateType int

const (
	// UpdateTypeNormal is a normal update
	UpdateTypeNormal UpdateType = 0
	// UpdateTypeBugFix is a bugfix update
	UpdateTypeBugFix UpdateType = 1
	// UpdateTypeCritical is a critical update
	UpdateTypeCritical UpdateType = 2
)

// Update defines an update to apply
type Update struct {
	Version     string     `json:"version"`
	Name        string     `json:"name"`
	Description string     `json:"description"`
	InstallID   string     `json:"installId"`
	Type        UpdateType `json:"type"`
	PublishedAt int64      `json:"publishedAt"`
	Asset       *Asset     `json:"asset,omitempty"`
}

// UpdateOptions are options used to find an update
type UpdateOptions struct {
	// Version is the current version of the app
	Version string `json:"version"`
	// Platform is the os type (darwin, windows, linux)
	Platform string `json:"platform"`
	// DestinationPath is where to apply the update to
	DestinationPath string `json:"destinationPath"`
	// URL can override where the updater looks
	URL string `json:"URL"`
	// Channel is an alternative channel to get updates from (test, prerelease)
	Channel string `json:"channel"`
	// Env is an environment or run mode (prod, staging, devel)
	Env string `json:"env"`
	// InstallID is an identifier that the client can send with requests
	InstallID string `json:"installId"`
	// Arch is an architecure description (x64, i386, arm)
	Arch string `json:"arch"`
	// Force is whether to apply the update, even if older or same version
	Force bool `json:"force"`
	// OSVersion is the version of the OS
	OSVersion string `json:"osVersion"`
	// UpdaterVersion is the version of the updater service
	UpdaterVersion string `json:"updaterVersion"`
}

// UpdateAction is the update action requested by the user
type UpdateAction string

const (
	// UpdateActionApply means the user accepted and to perform update
	UpdateActionApply UpdateAction = "apply"
	// UpdateActionAuto means that auto update is set and to perform update
	UpdateActionAuto UpdateAction = "auto"
	// UpdateActionSnooze snoozes an update
	UpdateActionSnooze UpdateAction = "snooze"
	// UpdateActionCancel cancels an update
	UpdateActionCancel UpdateAction = "cancel"
	// UpdateActionError means an error occurred
	UpdateActionError UpdateAction = "error"
)

// String is a unique string label for the action
func (u UpdateAction) String() string {
	return string(u)
}

// UpdatePromptOptions are the options for UpdatePrompt
type UpdatePromptOptions struct {
	AutoUpdate bool `json:"autoUpdate"`
}

// UpdatePromptResponse is the result for UpdatePrompt
type UpdatePromptResponse struct {
	Action     UpdateAction `json:"action"`
	AutoUpdate bool         `json:"autoUpdate"`
}

// UpdateUI is a UI interface
type UpdateUI interface {
	// UpdatePrompt prompts for an update
	UpdatePrompt(Update, UpdateOptions, UpdatePromptOptions) (*UpdatePromptResponse, error)
}
<|endoftext|>


<commit_before>package snd

import "strings"

// {
// 	"kind": "track",
// 	"id": 152514285,
// 	"created_at": "2014/06/02 22:04:29 +0000",
// 	"user_id": 2511,
// 	"duration": 4199289,
// 	"commentable": true,
// 	"state": "finished",
// 	"original_content_size": 167959022,
// 	"sharing": "public",
// 	"tag_list": "Gomma Discotexas \"Love Magnetic\"",
// 	"permalink": "discobelle-mix-041-moullinex",
// 	"streamable": true,
// 	"embeddable_by": "all",
// 	"downloadable": false,
// 	"purchase_url": null,
// 	"label_id": null,
// 	"purchase_title": null,
// 	"genre": "Mixtape",
// 	"title": "Discobelle Mix 041: Moullinex",
// 	"description": "A new mixtape, long overdue!\r\n'Love Magnetic' EP out June 13 on Gomma Records",
// 	"label_name": "",
// 	"release": "",
// 	"track_type": "podcast",
// 	"key_signature": "",
// 	"isrc": "",
// 	"video_url": null,
// 	"bpm": null,
// 	"release_year": null,
// 	"release_month": null,
// 	"release_day": null,
// 	"original_format": "mp3",
// 	"license": "all-rights-reserved",
// 	"uri": "http://api.soundcloud.com/tracks/152514285",
// 	"user": {},
// 	"permalink_url": "http://soundcloud.com/moullinex/discobelle-mix-041-moullinex",
// 	"artwork_url": "http://i1.sndcdn.com/artworks-000081264242-cftxc0-large.jpg?2aaad5e",
// 	"waveform_url": "http://w1.sndcdn.com/WYAiN8pZW7Bv_m.png",
// 	"stream_url": "http://api.soundcloud.com/tracks/152514285/stream",
// 	"playback_count": 24556,
// 	"download_count": 0,
// 	"favoritings_count": 1387,
// 	"comment_count": 128,
// 	"attachments_uri": "http://api.soundcloud.com/tracks/152514285/attachments"
// }
type Sound struct {
	Id                  int64  `json:"id"`
	Kind                string `json:"kind"` // could be "track", ...
	UserId              int64  `json:"user_id"`
	Title               string `json:"title"`
	Description         string `json:"description"`
	Uri                 string `json:"uri"`
	Duration            int64  `json:"duration"`
	Commentable         bool   `json:"commentable"`
	Streamable          bool   `json:"streamable"`
	Downloadable        bool   `json:"downloadable"`
	EmbeddableBy        string `json:"embeddable_by"` // could be "all"
	TagList             string `json:"tag_list"`
	Permalink           string `json:"permalink"`
	PermalinkUrl        string `json:"permalink_url"`
	StreamUrl           string `json:"stream_url"`
	DownloadUrl         string `json:"download_url"`
	AttachmentsUri      string `json:"attachments_uri"`
	State               string `json:"state"`   // could be "finished", ...
	Sharing             string `json:"sharing"` // could be "public"
	OriginalContentSize int64  `json:"original_content_size"`
	OriginalFormat      string `json:"original_format"` // could be "mp3"
	CreatedAt           Time   `json:"created_at"`

	// statistics
	PlaybackCount    int64 `json:"playback_count"`
	DownloadCount    int64 `json:"download_count"`
	FavoritingsCount int64 `json:"favoritings_count"`
	CommentCount     int64 `json:"comment_count"`

	// user sub-object
	User User `json:"user"`
}

func (s *Sound) Filename() string {
	// TODO: the user is not always the artist, find a better heuristic...
	artist := strings.Replace(s.User.Username, "/", "-", -1)
	title := strings.Replace(s.Title, "/", "-", -1)
	return artist + " - " + title
}
<commit_msg>api/sound: normalize filenames<commit_after>package snd

import "strings"

// {
// 	"kind": "track",
// 	"id": 152514285,
// 	"created_at": "2014/06/02 22:04:29 +0000",
// 	"user_id": 2511,
// 	"duration": 4199289,
// 	"commentable": true,
// 	"state": "finished",
// 	"original_content_size": 167959022,
// 	"sharing": "public",
// 	"tag_list": "Gomma Discotexas \"Love Magnetic\"",
// 	"permalink": "discobelle-mix-041-moullinex",
// 	"streamable": true,
// 	"embeddable_by": "all",
// 	"downloadable": false,
// 	"purchase_url": null,
// 	"label_id": null,
// 	"purchase_title": null,
// 	"genre": "Mixtape",
// 	"title": "Discobelle Mix 041: Moullinex",
// 	"description": "A new mixtape, long overdue!\r\n'Love Magnetic' EP out June 13 on Gomma Records",
// 	"label_name": "",
// 	"release": "",
// 	"track_type": "podcast",
// 	"key_signature": "",
// 	"isrc": "",
// 	"video_url": null,
// 	"bpm": null,
// 	"release_year": null,
// 	"release_month": null,
// 	"release_day": null,
// 	"original_format": "mp3",
// 	"license": "all-rights-reserved",
// 	"uri": "http://api.soundcloud.com/tracks/152514285",
// 	"user": {},
// 	"permalink_url": "http://soundcloud.com/moullinex/discobelle-mix-041-moullinex",
// 	"artwork_url": "http://i1.sndcdn.com/artworks-000081264242-cftxc0-large.jpg?2aaad5e",
// 	"waveform_url": "http://w1.sndcdn.com/WYAiN8pZW7Bv_m.png",
// 	"stream_url": "http://api.soundcloud.com/tracks/152514285/stream",
// 	"playback_count": 24556,
// 	"download_count": 0,
// 	"favoritings_count": 1387,
// 	"comment_count": 128,
// 	"attachments_uri": "http://api.soundcloud.com/tracks/152514285/attachments"
// }
type Sound struct {
	Id                  int64  `json:"id"`
	Kind                string `json:"kind"` // could be "track", ...
	UserId              int64  `json:"user_id"`
	Title               string `json:"title"`
	Description         string `json:"description"`
	Uri                 string `json:"uri"`
	Duration            int64  `json:"duration"`
	Commentable         bool   `json:"commentable"`
	Streamable          bool   `json:"streamable"`
	Downloadable        bool   `json:"downloadable"`
	EmbeddableBy        string `json:"embeddable_by"` // could be "all"
	TagList             string `json:"tag_list"`
	Permalink           string `json:"permalink"`
	PermalinkUrl        string `json:"permalink_url"`
	StreamUrl           string `json:"stream_url"`
	DownloadUrl         string `json:"download_url"`
	AttachmentsUri      string `json:"attachments_uri"`
	State               string `json:"state"`   // could be "finished", ...
	Sharing             string `json:"sharing"` // could be "public"
	OriginalContentSize int64  `json:"original_content_size"`
	OriginalFormat      string `json:"original_format"` // could be "mp3"
	CreatedAt           Time   `json:"created_at"`

	// statistics
	PlaybackCount    int64 `json:"playback_count"`
	DownloadCount    int64 `json:"download_count"`
	FavoritingsCount int64 `json:"favoritings_count"`
	CommentCount     int64 `json:"comment_count"`

	// user sub-object
	User User `json:"user"`
}

func (s *Sound) Filename() string {
	// TODO: the user is not always the artist, find a better heuristic...
	title := strings.Replace(s.Title, "/", "-", -1)
	artist := strings.Replace(s.User.Username, "/", "-", -1)

	// strip the string "free download" from the title if it is found
	title = strings.Replace(title, "free download", "", -1)

	// strip some special characters
	title = stripRunes(title, "*")

	// now there's possibly some trailing space
	title = strings.TrimSpace(title)

	// don't prepend the artist name if the title already starts with the
	// artist name (some uploaders do this)
	if strings.HasPrefix(title, artist) {
		return title
	}

	return artist + " - " + title
}

func stripRunes(str, chr string) string {
	return strings.Map(func(r rune) rune {
		if strings.IndexRune(chr, r) < 0 {
			return r
		}
		return -1
	}, str)
}
<|endoftext|>


<commit_before>package bitmessage

import (
	"bytes"
	"crypto/rand"
	"encoding/binary"
	"time"

	encVarint "github.com/nictuku/guardian/encoding/varint"
	encVarstring "github.com/spearson78/guardian/encoding/varstring"
)

const (
	protocolVersion = 1
	streamOne       = 1
	// Using same value from PyBitmessage, which was originally added to avoid memory blowups.
	// The protocol itself doesn't restrict it. This should certainly be removed
	maxPayloadLength = 180000000
	id               = "bitz"
	prefix           = "bitmessage"

	nodeConnectionRetryPeriod            = time.Minute * 30
	connectionTimeout                    = time.Second * 30
	numNodesForMainStream                = 15
	maxInventoryEntries                  = 50000
	payloadLengthExtraBytes              = 14000
	averageProofOfWorkNonceTrialsPerByte = 320

	// This is a normal network node.
	ConnectionServiceNodeNetwork = 1
)

var (
	// PortNumber can be safely changed before the call to node.Run().
	PortNumber = 9090

	// Magic value indicating message origin network, and used to seek to next
	// message when stream state is unknown.
	magicHeader      = uint32(0xE9BEB4D9)
	magicHeaderSlice = []byte{0xE9, 0xBE, 0xB4, 0xD9}

	// These values are initialzied by init() and should never be changed
	// after they are written for the first time.
	nonce         uint64                                 // Filled by init().
	services      = uint64(ConnectionServiceNodeNetwork) // Only one bit is used for now.
	streamNumbers = []byte{}                             // Only using stream 1 for now.
	userAgent     = []byte{}                             // Filled by init().

	bootstrapNodes = [][]string{
		// The only node that seems to be up:
		{"217.91.97.196", "8444"},

		// DNS nodes used by PyBitMessage for bootstrapping:
		{"bootstrap8080.bitmessage.org", "8080"},
		{"bootstrap8444.bitmessage.org", "8444"},

		// My test PyBitMessage.
		// {"192.168.11.8", "8444"},
	}
)

// init initializes package variables and constants.
func init() {
	// Flip the byte order for BitMessage, which is different than BitCoin.
	encVarint.ByteOrder = binary.BigEndian
	buf := new(bytes.Buffer)
	// Don't attract attention to this client just yet, use the vanilla client
	// user agent.
	// encVarstring.WriteVarString(userAgent, "/bitz:1/")
	encVarstring.WriteVarString(buf, "/PyBitmessage:0.2.8/")
	userAgent = buf.Bytes()

	buf = new(bytes.Buffer)
	putVarIntList(buf, []uint64{streamOne})
	streamNumbers = buf.Bytes()

	// TODO: rotate the nonce numbers.
	err := binary.Read(rand.Reader, binary.LittleEndian, &nonce)
	if err != nil {
		nonce = uint64(time.Now().UnixNano())
	}
}
<commit_msg>Move to protocol version 2.<commit_after>package bitmessage

import (
	"bytes"
	"crypto/rand"
	"encoding/binary"
	"time"

	encVarint "github.com/nictuku/guardian/encoding/varint"
	encVarstring "github.com/spearson78/guardian/encoding/varstring"
)

const (
	protocolVersion = 2
	streamOne       = 1
	// Using same value from PyBitmessage, which was originally added to avoid memory blowups.
	// The protocol itself doesn't restrict it. This should certainly be removed
	maxPayloadLength = 180000000
	id               = "bitz"
	prefix           = "bitmessage"

	nodeConnectionRetryPeriod            = time.Minute * 30
	connectionTimeout                    = time.Second * 30
	numNodesForMainStream                = 15
	maxInventoryEntries                  = 50000
	payloadLengthExtraBytes              = 14000
	averageProofOfWorkNonceTrialsPerByte = 320

	// This is a normal network node.
	ConnectionServiceNodeNetwork = 1
)

var (
	// PortNumber can be safely changed before the call to node.Run().
	PortNumber = 9090

	// Magic value indicating message origin network, and used to seek to next
	// message when stream state is unknown.
	magicHeader      = uint32(0xE9BEB4D9)
	magicHeaderSlice = []byte{0xE9, 0xBE, 0xB4, 0xD9}

	// These values are initialzied by init() and should never be changed
	// after they are written for the first time.
	nonce         uint64                                 // Filled by init().
	services      = uint64(ConnectionServiceNodeNetwork) // Only one bit is used for now.
	streamNumbers = []byte{}                             // Only using stream 1 for now.
	userAgent     = []byte{}                             // Filled by init().

	bootstrapNodes = [][]string{
		// The only node that seems to be up:
		{"217.91.97.196", "8444"},

		// DNS nodes used by PyBitMessage for bootstrapping:
		{"bootstrap8080.bitmessage.org", "8080"},
		{"bootstrap8444.bitmessage.org", "8444"},

		// My test PyBitMessage.
		// {"192.168.11.8", "8444"},
	}
)

// init initializes package variables and constants.
func init() {
	// Flip the byte order for BitMessage, which is different than BitCoin.
	encVarint.ByteOrder = binary.BigEndian
	buf := new(bytes.Buffer)
	// Don't attract attention to this client just yet, use the vanilla client
	// user agent.
	// encVarstring.WriteVarString(userAgent, "/bitz:1/")
	encVarstring.WriteVarString(buf, "/PyBitmessage:0.2.8/")
	userAgent = buf.Bytes()

	buf = new(bytes.Buffer)
	putVarIntList(buf, []uint64{streamOne})
	streamNumbers = buf.Bytes()

	// TODO: rotate the nonce numbers.
	err := binary.Read(rand.Reader, binary.LittleEndian, &nonce)
	if err != nil {
		nonce = uint64(time.Now().UnixNano())
	}
}
<|endoftext|>