<commit_before>// Copyright 2014 James McGuire. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import (
	"database/sql"
	"encoding/json"
	"html"
	"io"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"net/url"
	"os"
	"os/signal"
	"regexp"
	"runtime"
	"strings"
	"syscall"
	"time"
	"unicode/utf8"

	irc "github.com/fluffle/goirc/client"
	_ "github.com/go-sql-driver/mysql"
)

var (
	config   Config
	urlRegex = regexp.MustCompile(`(?i)\b((?:https?://|www\d{0,3}[.]|[` +
		`a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+` +
		`\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s` + "`" + `!()\[` +
		`\]{};:'".,<>?«»“”‘’]))`)
	httpRegex      = regexp.MustCompile(`https?://.*`)
	findWhiteSpace = regexp.MustCompile(`\s{1,}`)
	db             *sql.DB
	badWords       = make(map[string]*regexp.Regexp)
)

type Config struct {
	Channel       string
	DBConn        string
	Nick          string
	Ident         string
	FullName      string
	FlickrAPIKey  string
	WolframAPIKey string
	IRCPass       string
	RebuildWords  bool
	Commands      []struct {
		Name string
		Text string
	}
	BadWords []struct {
		Word  string
		Query string
	}
}

// Try and grab the title for any URL's posted in the channel
func sendUrl(channel, unparsedURL string, conn *irc.Conn) {
	if !httpRegex.MatchString(unparsedURL) {
		unparsedURL = `http://` + unparsedURL
	}
	postedUrl, err := url.Parse(unparsedURL)
	if err != nil {
		log.Println(err)
		return
	}
	log.Println("Fetching title for " + postedUrl.String() + " In channel " + channel)

	resp, err := http.Get(postedUrl.String())
	if err != nil {
		log.Println(err)
		return
	}
	defer resp.Body.Close()
	if resp.StatusCode >= 400 {
		log.Println("http server return error.")
		return
	}
	respbody := []byte{}
	if resp.Header.Get("Content-Type") == "" {
		buf := make([]byte, 512)
		bufsize, err := resp.Body.Read(buf)
		if err != nil {
			log.Println("adding content type failed")
		}
		resp.Header.Set("Content-Type", http.DetectContentType(buf[:bufsize]))
		respbody = append(respbody, buf[:bufsize]...)
	}

	if !strings.Contains(resp.Header.Get("Content-Type"), "text/html") {
		log.Println("content-type is not text/html")
		return
	}

	restofbody, err := ioutil.ReadAll(io.LimitReader(resp.Body, 50000))
	if err != nil {
		log.Println("error reading posted link")
		return
	}
	respbody = append(respbody, restofbody...)
	stringbody := string(respbody)
	titlestart := strings.Index(stringbody, "<title>")
	titleend := strings.Index(stringbody, "</title>")
	if titlestart != -1 && titlestart != -1 {
		title := string(respbody[titlestart+7 : titleend])
		title = strings.TrimSpace(title)
		if title != "" && utf8.ValidString(title) {
			// Example:
			// Title: sadbox . org (at sadbox.org)
			title = html.UnescapeString(title)
			title = findWhiteSpace.ReplaceAllString(title, " ")
			title = "Title: " + title + " (at " + postedUrl.Host + ")"
			log.Println(title)
			conn.Privmsg(channel, title)
		}
	}
}

func logMessage(line *irc.Line, channel, message string) {
	_, err := db.Exec("insert into messages (Nick, Ident, Host, Src, Cmd, Channel,"+
		" Message, Time) values (?, ?, ?, ?, ?, ?, ?, ?)", line.Nick, line.Ident,
		line.Host, line.Src, line.Cmd, channel, message, line.Time)
	if err != nil {
		log.Println(err)
	}
	err = updateWords(line.Nick, message)
	if err != nil {
		log.Println(err)
	}
}

func checkForUrl(channel string, splitmessage []string, conn *irc.Conn) {
	urllist := []string{}
	numlinks := 0
NextWord:
	for _, word := range splitmessage {
		word = strings.TrimSpace(word)
		if urlRegex.MatchString(word) {
			for _, subUrl := range urllist {
				if subUrl == word {
					continue NextWord
				}
			}
			numlinks++
			if numlinks > 3 {
				break
			}
			urllist = append(urllist, word)
			go sendUrl(channel, word, conn)
		}
	}
}

// This function does all the dispatching for various commands
// as well as logging each message to the database
func handleMessage(conn *irc.Conn, line *irc.Line) {
	// This is so that the bot can properly respond to pm's
	var channel string
	if conn.Me.Nick == line.Args[0] {
		channel = line.Nick
	} else {
		channel = line.Args[0]
	}
	message := line.Args[1]
	splitmessage := strings.Split(message, " ")

	// Special commands
	switch strings.TrimSpace(splitmessage[0]) {
	case "!dance":
		if line.Nick == "sadbox" {
			go dance(channel, conn)
		}
	case "!audio":
		if line.Nick == "sadbox" {
			go conn.Privmsg(channel, "https://sadbox.org/static/stuff/audiophile.html")
		}
	case "!cst":
		if line.Nick == "sadbox" {
			go conn.Privmsg(channel, "\u00039,13#CSTMASTERRACE")
		}
	case "!haata":
		go haata(channel, conn)
	case "!search":
		go googSearch(channel, message, conn)
	case "!chatter":
		if line.Nick == "sadbox" {
			go markov(channel, conn)
		}
	case "!ask":
		go wolfram(channel, message, line.Nick, conn)
	case "!meebcast":
		var command string
		if len(splitmessage) >= 2 {
			command = strings.TrimSpace(splitmessage[1])
		}
		go meeba(channel, line.Nick, command, conn)
	}

	// Commands that are read in from the config file
	for _, command := range config.Commands {
		if strings.TrimSpace(splitmessage[0]) == command.Name {
			go conn.Privmsg(channel, command.Text)
		}
	}

	// This is what looks at each word and tries to figure out if it's a URL
	go checkForUrl(channel, splitmessage, conn)

	// Shove that shit in the database!
	go logMessage(line, channel, message)
}

func init() {
	log.Println("Starting sadbot")

	runtime.GOMAXPROCS(runtime.NumCPU())

	rand.Seed(time.Now().UTC().UnixNano())

	configfile, err := os.Open("config.json")
	if err != nil {
		log.Fatal(err)
	}
	err = json.NewDecoder(configfile).Decode(&config)
	if err != nil {
		log.Fatal(err)
	}

	for _, word := range config.BadWords {
		badWords[word.Word] = regexp.MustCompile(word.Query)
	}

	log.Println("Loaded config file!")
	log.Printf("Joining channel %s", config.Channel)
	log.Printf("Nick: %s", config.Nick)
	log.Printf("Ident: %s", config.Ident)
	log.Printf("FullName: %s", config.FullName)

	log.Printf("Found %d commands", len(config.Commands))
	for index, command := range config.Commands {
		log.Printf("%d %s: %s", index+1, command.Name, command.Text)
	}
}

func main() {
	var err error
	db, err = sql.Open("mysql", config.DBConn)
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	db.SetMaxIdleConns(100)
	db.SetMaxOpenConns(200)

	go makeMarkov()

	buildchan := make(chan os.Signal, 1)
	signal.Notify(buildchan, syscall.SIGUSR1)
	go func() {
		for _ = range buildchan {
			genTables()
		}
	}()

	c := irc.SimpleClient(config.Nick, config.Ident, config.FullName)

	c.SSL = true

	c.AddHandler(irc.CONNECTED,
		func(conn *irc.Conn, line *irc.Line) {
			conn.Join(config.Channel)
			log.Println("Connected!")
		})

	quit := make(chan bool)

	c.AddHandler(irc.DISCONNECTED,
		func(conn *irc.Conn, line *irc.Line) { quit <- true })

	c.AddHandler("PRIVMSG", handleMessage)
	c.AddHandler("ACTION", handleMessage)

	if err := c.Connect("irc.freenode.net", config.Nick+":"+config.IRCPass); err != nil {
		log.Fatalln("Connection error: %s\n", err)
	}

	<-quit
}
<commit_msg>use fmt.Sprintf instead of +s<commit_after>// Copyright 2014 James McGuire. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"html"
	"io"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"net/url"
	"os"
	"os/signal"
	"regexp"
	"runtime"
	"strings"
	"syscall"
	"time"
	"unicode/utf8"

	irc "github.com/fluffle/goirc/client"
	_ "github.com/go-sql-driver/mysql"
)

var (
	config   Config
	urlRegex = regexp.MustCompile(`(?i)\b((?:https?://|www\d{0,3}[.]|[` +
		`a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+` +
		`\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s` + "`" + `!()\[` +
		`\]{};:'".,<>?«»“”‘’]))`)
	httpRegex      = regexp.MustCompile(`https?://.*`)
	findWhiteSpace = regexp.MustCompile(`\s{1,}`)
	db             *sql.DB
	badWords       = make(map[string]*regexp.Regexp)
)

type Config struct {
	Channel       string
	DBConn        string
	Nick          string
	Ident         string
	FullName      string
	FlickrAPIKey  string
	WolframAPIKey string
	IRCPass       string
	RebuildWords  bool
	Commands      []struct {
		Name string
		Text string
	}
	BadWords []struct {
		Word  string
		Query string
	}
}

// Try and grab the title for any URL's posted in the channel
func sendUrl(channel, unparsedURL string, conn *irc.Conn) {
	if !httpRegex.MatchString(unparsedURL) {
		unparsedURL = `http://` + unparsedURL
	}
	postedUrl, err := url.Parse(unparsedURL)
	if err != nil {
		log.Println(err)
		return
	}
	log.Println("Fetching title for " + postedUrl.String() + " In channel " + channel)

	resp, err := http.Get(postedUrl.String())
	if err != nil {
		log.Println(err)
		return
	}
	defer resp.Body.Close()
	if resp.StatusCode >= 400 {
		log.Println("http server return error.")
		return
	}
	respbody := []byte{}
	if resp.Header.Get("Content-Type") == "" {
		buf := make([]byte, 512)
		bufsize, err := resp.Body.Read(buf)
		if err != nil {
			log.Println("adding content type failed")
		}
		resp.Header.Set("Content-Type", http.DetectContentType(buf[:bufsize]))
		respbody = append(respbody, buf[:bufsize]...)
	}

	if !strings.Contains(resp.Header.Get("Content-Type"), "text/html") {
		log.Println("content-type is not text/html")
		return
	}

	restofbody, err := ioutil.ReadAll(io.LimitReader(resp.Body, 50000))
	if err != nil {
		log.Println("error reading posted link")
		return
	}
	respbody = append(respbody, restofbody...)
	stringbody := string(respbody)
	titlestart := strings.Index(stringbody, "<title>")
	titleend := strings.Index(stringbody, "</title>")
	if titlestart != -1 && titlestart != -1 {
		title := string(respbody[titlestart+7 : titleend])
		title = strings.TrimSpace(title)
		if title != "" && utf8.ValidString(title) {
			// Example:
			// Title: sadbox . org (at sadbox.org)
			title = html.UnescapeString(title)
			title = findWhiteSpace.ReplaceAllString(title, " ")
			title = fmt.Sprintf("Title: %s (at %s)", title, postedUrl.Host)
			log.Println(title)
			conn.Privmsg(channel, title)
		}
	}
}

func logMessage(line *irc.Line, channel, message string) {
	_, err := db.Exec("insert into messages (Nick, Ident, Host, Src, Cmd, Channel,"+
		" Message, Time) values (?, ?, ?, ?, ?, ?, ?, ?)", line.Nick, line.Ident,
		line.Host, line.Src, line.Cmd, channel, message, line.Time)
	if err != nil {
		log.Println(err)
	}
	err = updateWords(line.Nick, message)
	if err != nil {
		log.Println(err)
	}
}

func checkForUrl(channel string, splitmessage []string, conn *irc.Conn) {
	urllist := []string{}
	numlinks := 0
NextWord:
	for _, word := range splitmessage {
		word = strings.TrimSpace(word)
		if urlRegex.MatchString(word) {
			for _, subUrl := range urllist {
				if subUrl == word {
					continue NextWord
				}
			}
			numlinks++
			if numlinks > 3 {
				break
			}
			urllist = append(urllist, word)
			go sendUrl(channel, word, conn)
		}
	}
}

// This function does all the dispatching for various commands
// as well as logging each message to the database
func handleMessage(conn *irc.Conn, line *irc.Line) {
	// This is so that the bot can properly respond to pm's
	var channel string
	if conn.Me.Nick == line.Args[0] {
		channel = line.Nick
	} else {
		channel = line.Args[0]
	}
	message := line.Args[1]
	splitmessage := strings.Split(message, " ")

	// Special commands
	switch strings.TrimSpace(splitmessage[0]) {
	case "!dance":
		if line.Nick == "sadbox" {
			go dance(channel, conn)
		}
	case "!audio":
		if line.Nick == "sadbox" {
			go conn.Privmsg(channel, "https://sadbox.org/static/stuff/audiophile.html")
		}
	case "!cst":
		if line.Nick == "sadbox" {
			go conn.Privmsg(channel, "\u00039,13#CSTMASTERRACE")
		}
	case "!haata":
		go haata(channel, conn)
	case "!search":
		go googSearch(channel, message, conn)
	case "!chatter":
		if line.Nick == "sadbox" {
			go markov(channel, conn)
		}
	case "!ask":
		go wolfram(channel, message, line.Nick, conn)
	case "!meebcast":
		var command string
		if len(splitmessage) >= 2 {
			command = strings.TrimSpace(splitmessage[1])
		}
		go meeba(channel, line.Nick, command, conn)
	}

	// Commands that are read in from the config file
	for _, command := range config.Commands {
		if strings.TrimSpace(splitmessage[0]) == command.Name {
			go conn.Privmsg(channel, command.Text)
		}
	}

	// This is what looks at each word and tries to figure out if it's a URL
	go checkForUrl(channel, splitmessage, conn)

	// Shove that shit in the database!
	go logMessage(line, channel, message)
}

func init() {
	log.Println("Starting sadbot")

	runtime.GOMAXPROCS(runtime.NumCPU())

	rand.Seed(time.Now().UTC().UnixNano())

	configfile, err := os.Open("config.json")
	if err != nil {
		log.Fatal(err)
	}
	err = json.NewDecoder(configfile).Decode(&config)
	if err != nil {
		log.Fatal(err)
	}

	for _, word := range config.BadWords {
		badWords[word.Word] = regexp.MustCompile(word.Query)
	}

	log.Println("Loaded config file!")
	log.Printf("Joining channel %s", config.Channel)
	log.Printf("Nick: %s", config.Nick)
	log.Printf("Ident: %s", config.Ident)
	log.Printf("FullName: %s", config.FullName)

	log.Printf("Found %d commands", len(config.Commands))
	for index, command := range config.Commands {
		log.Printf("%d %s: %s", index+1, command.Name, command.Text)
	}
}

func main() {
	var err error
	db, err = sql.Open("mysql", config.DBConn)
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	db.SetMaxIdleConns(100)
	db.SetMaxOpenConns(200)

	go makeMarkov()

	buildchan := make(chan os.Signal, 1)
	signal.Notify(buildchan, syscall.SIGUSR1)
	go func() {
		for _ = range buildchan {
			genTables()
		}
	}()

	c := irc.SimpleClient(config.Nick, config.Ident, config.FullName)

	c.SSL = true

	c.AddHandler(irc.CONNECTED,
		func(conn *irc.Conn, line *irc.Line) {
			conn.Join(config.Channel)
			log.Println("Connected!")
		})

	quit := make(chan bool)

	c.AddHandler(irc.DISCONNECTED,
		func(conn *irc.Conn, line *irc.Line) { quit <- true })

	c.AddHandler("PRIVMSG", handleMessage)
	c.AddHandler("ACTION", handleMessage)

	if err := c.Connect("irc.freenode.net", config.Nick+":"+config.IRCPass); err != nil {
		log.Fatalln("Connection error: %s\n", err)
	}

	<-quit
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/olekukonko/tablewriter"
	"go/ast"
	"go/types"
	"os"
	"sort"

	"golang.org/x/tools/go/loader"
)

func main() {
	var conf loader.Config

	conf.CreateFromFilenames(".", os.Args[1:]...)
	p, err := conf.Load()
	if err != nil {
		fmt.Println(err)
		return
	}

	w := NewWalker(p)

	// work only with top package for now.
	// TODO: work with all recursive sub-packages (optionally?)
	top := p.InitialPackages()[0]

	// find all selectors ('f.x') for imported packages
	selectors := make(map[string]Selector)
	counter := make(map[string]int)
	for _, f := range top.Files {
		ast.Inspect(f, func(n ast.Node) bool {
			switch x := n.(type) {
			case *ast.SelectorExpr:
				var (
					n   string // package name
					obj types.Object
				)

				// handle methods
				s, ok := top.Selections[x]
				if ok {
					// (pkg).pkgvar.Method()
					obj = s.Obj()
					if obj.Pkg() == nil {
						return false
					}
					n = s.Obj().Pkg().Name()
				} else {
					// pkg.Func()
					n = pkgName(x)
				}

				// if it's not a selector for external package, skip it
				pkg, ok := w.Packages[n]
				if !ok {
					break
				}

				sel := Selector{
					Pkg:  pkg,
					Name: x.Sel.Name,
				}

				// lookup this object in package
				dp := p.Package(pkg.Path)
				if obj == nil {
					obj = w.FindObject(dp, sel.Name)
					if obj == nil {
						return true
					}
				}
				if _, ok := obj.Type().(*types.Signature); ok {
					sel.Type = "func"

					node := w.FindFnNode(dp, x.Sel.Name)
					if node != nil {
						lines := w.LOC(node)
						_, depth, linesCum, depthInt := w.WalkExternal(node, dp)
						sel.LOC, sel.Depth = lines, depth
						sel.LOCCum, sel.DepthInternal = linesCum, depthInt
					}
				}
				selectors[sel.String()] = sel
				counter[sel.String()]++
			}
			return true
		})
	}

	// Print stats
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Name", "LOC", "Type", "Count", "Depth", "LOCCum", "DepthInt"})
	var results [][]string
	for name, count := range counter {
		sel := selectors[name]
		loc := fmt.Sprintf("%d", sel.LOC)
		depth := fmt.Sprintf("%d", sel.Depth)
		locCum := fmt.Sprintf("%d", sel.LOCCum)
		depthInt := fmt.Sprintf("%d", sel.DepthInternal)
		count := fmt.Sprintf("%d", count)
		results = append(results, []string{name, loc, sel.Type, count, depth, locCum, depthInt})
	}
	sort.Sort(ByName(results))
	for _, v := range results {
		table.Append(v)
	}
	table.Render() // Send output
}

type ByName [][]string

func (b ByName) Len() int           { return len(b) }
func (b ByName) Swap(i, j int)      { b[i], b[j] = b[j], b[i] }
func (b ByName) Less(i, j int) bool { return b[i][0] < b[j][0] }

// pkgName returns qualified package name from SelectorExpr.
func pkgName(x *ast.SelectorExpr) string {
	n, ok := x.X.(*ast.Ident)
	if !ok {
		return ""
	}

	return n.Name
}

type Walker struct {
	P          *loader.Program
	Packages   map[string]Package
	CacheLOC   map[*ast.FuncDecl]int
	CacheNodes map[string]*ast.FuncDecl

	Stdlib bool
}

func NewWalker(p *loader.Program) *Walker {
	// work only with top package for now.
	// TODO: work with all recursive sub-packages (optionally?)
	top := p.InitialPackages()[0]

	// prepare map of resolved imports
	packages := make(map[string]Package)
	for _, pkg := range top.Pkg.Imports() {
		if IsStdlib(pkg.Path()) {
			continue
		}
		packages[pkg.Name()] = Package{
			Name: pkg.Name(),
			Path: pkg.Path(),
		}
	}

	return &Walker{
		P:          p,
		Packages:   packages,
		CacheLOC:   make(map[*ast.FuncDecl]int),
		CacheNodes: make(map[string]*ast.FuncDecl),

		Stdlib: false,
	}
}

// WalkExternal walks through function body block,
// looking for external dependencies expressions.
func (w *Walker) WalkExternal(topNode ast.Node, parent *loader.PackageInfo) (lines, depth, locCum, depthInt int) {
	ast.Inspect(topNode, func(n ast.Node) bool {
		switch x := n.(type) {
		case *ast.CallExpr:
			expr, ok := x.Fun.(*ast.Ident)
			if !ok {
				break
			}
			name := expr.Name

			// lookup this object in package
			obj := w.FindObject(parent, name)
			if obj == nil {
				return false
			}

			if _, ok := obj.Type().(*types.Signature); ok {
				node := w.FindFnNode(parent, name)
				// skip recursive calls
				if node == topNode {
					return false
				}

				if node != nil {
					depthInt++
					loc := w.LOC(node)
					locCum += loc

					lines1, depth1, lines2, depth2 := w.WalkExternal(node, parent)
					lines = lines1
					depth += depth1
					locCum += lines2
					depthInt += depth2
				}
			}
		case *ast.SelectorExpr:
			var (
				n   string // package name
				obj types.Object
			)
			s, ok := parent.Selections[x]
			if ok {
				// (pkg).pkgvar.Method()
				obj = s.Obj()
				if obj.Pkg() == nil {
					return false
				}
				n = obj.Pkg().Name()
			} else {
				// pkg.Func()
				n = pkgName(x)
			}

			var pkg *loader.PackageInfo
			if n == parent.Pkg.Name() {
				pkg = parent
			} else {
				pkg = w.FindImport(parent, n)
				if pkg == nil {
					return false
				}
			}

			name := x.Sel.Name

			// lookup this object in package
			if obj == nil {
				obj = w.FindObject(pkg, name)
				if obj == nil {
					return false
				}
			}

			if _, ok := obj.Type().(*types.Signature); ok {
				node := w.FindFnNode(pkg, name)

				// skip recursive calls
				if node == topNode {
					return false
				}

				if node != nil {
					depth++
					lines1, depth1, lines2, depth2 := w.WalkExternal(node, pkg)
					lines = lines1
					depth += depth1
					locCum += lines2
					depthInt += depth2
				}
			}
		}
		return true
	})
	return
}

func (w *Walker) FindObject(pkg *loader.PackageInfo, name string) types.Object {
	scope := pkg.Pkg.Scope()
	return scope.Lookup(name)
}

func (w *Walker) FindFnNode(pkg *loader.PackageInfo, fnName string) *ast.FuncDecl {
	var (
		node *ast.FuncDecl
		ok   bool
	)
	qName := fmt.Sprintf("%s.%s", pkg.Pkg.Path(), fnName)
	node, ok = w.CacheNodes[qName]
	if ok {
		return node
	}
	for _, f := range pkg.Files {
		ast.Inspect(f, func(n ast.Node) bool {
			switch x := n.(type) {
			case *ast.FuncDecl:
				if x.Name.Name == fnName {
					if x.Body == nil {
						return false
						w.CacheNodes[qName] = nil
					}
					node = x
					w.CacheNodes[qName] = x
					return false
				}
			}
			return true
		})
		if node != nil {
			return node
		}
	}
	return nil
}

func (w *Walker) FindImport(parent *loader.PackageInfo, name string) *loader.PackageInfo {
	for _, p := range parent.Pkg.Imports() {
		if p.Name() == name {
			if !w.Stdlib {
				std := IsStdlib(p.Path())
				if std {
					return nil
				}
			}
			return w.P.Package(p.Path())
		}
	}
	return nil
}

// LOC calculates readl Lines Of Code for the given function node.
// node must be ast.FuncDecl, panics otherwise.
func (w *Walker) LOC(node *ast.FuncDecl) int {
	if lines, ok := w.CacheLOC[node]; ok {
		return lines
	}

	body := node.Body
	if body == nil {
		return 0
		w.CacheLOC[node] = 0
	}

	start := w.P.Fset.Position(body.Lbrace)
	end := w.P.Fset.Position(body.Rbrace)
	lines := end.Line - start.Line

	// for cases line 'func foo() { bar() }'
	// TODO: figure out how to calculate it smarter
	if lines == 0 {
		lines = 1
	}

	w.CacheLOC[node] = lines

	return lines
}
<commit_msg>Prepre refactor<commit_after>package main

import (
	"fmt"
	"github.com/olekukonko/tablewriter"
	"go/ast"
	"go/types"
	"os"
	"sort"

	"golang.org/x/tools/go/loader"
)

func main() {
	var conf loader.Config

	conf.CreateFromFilenames(".", os.Args[1:]...)
	p, err := conf.Load()
	if err != nil {
		fmt.Println(err)
		return
	}

	w := NewWalker(p)

	// work only with top package for now.
	// TODO: work with all recursive sub-packages (optionally?)
	top := p.InitialPackages()[0]

	for _, f := range top.Files {
		ast.Inspect(f, func(n ast.Node) bool {
			switch x := n.(type) {
			case *ast.SelectorExpr:
				var (
					n   string // package name
					obj types.Object
				)

				// handle methods
				s, ok := top.Selections[x]
				if ok {
					// (pkg).pkgvar.Method()
					obj = s.Obj()
					if obj.Pkg() == nil {
						return false
					}
					n = s.Obj().Pkg().Name()
				} else {
					// pkg.Func()
					n = pkgName(x)
				}

				// if it's not a selector for external package, skip it
				pkgInfo, ok := w.Packages[n]
				if !ok {
					break
				}

				sel := Selector{
					Pkg:  pkgInfo,
					Name: x.Sel.Name,
				}

				// lookup this object in package
				pkg := p.Package(pkgInfo.Path)
				if obj == nil {
					obj = w.FindObject(pkg, x.Sel.Name)
					if obj == nil {
						return true
					}
				}
				if _, ok := obj.Type().(*types.Signature); ok {
					sel.Type = "func"

					node := w.FindFnNode(pkg, x.Sel.Name)
					if node != nil {
						lines := w.LOC(node)
						_, depth, linesCum, depthInt := w.Walk(node, pkg, true)
						sel.LOC, sel.Depth = lines, depth
						sel.LOCCum, sel.DepthInternal = linesCum, depthInt
					}
				}
				w.Selectors[sel.String()] = sel
				w.Counter[sel.String()]++
			}
			return true
		})
	}

	// Print stats
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Name", "LOC", "Type", "Count", "Depth", "LOCCum", "DepthInt"})
	var results [][]string
	for name, count := range w.Counter {
		sel := w.Selectors[name]
		loc := fmt.Sprintf("%d", sel.LOC)
		depth := fmt.Sprintf("%d", sel.Depth)
		locCum := fmt.Sprintf("%d", sel.LOCCum)
		depthInt := fmt.Sprintf("%d", sel.DepthInternal)
		count := fmt.Sprintf("%d", count)
		results = append(results, []string{name, loc, sel.Type, count, depth, locCum, depthInt})
	}
	sort.Sort(ByName(results))
	for _, v := range results {
		table.Append(v)
	}
	table.Render() // Send output
}

type ByName [][]string

func (b ByName) Len() int           { return len(b) }
func (b ByName) Swap(i, j int)      { b[i], b[j] = b[j], b[i] }
func (b ByName) Less(i, j int) bool { return b[i][0] < b[j][0] }

// pkgName returns qualified package name from SelectorExpr.
func pkgName(x *ast.SelectorExpr) string {
	n, ok := x.X.(*ast.Ident)
	if !ok {
		return ""
	}

	return n.Name
}

type Walker struct {
	P          *loader.Program
	Packages   map[string]Package
	CacheLOC   map[*ast.FuncDecl]int
	CacheNodes map[string]*ast.FuncDecl

	Stdlib bool

	Selectors map[string]Selector
	Counter   map[string]int
}

func NewWalker(p *loader.Program) *Walker {
	// work only with top package for now.
	// TODO: work with all recursive sub-packages (optionally?)
	top := p.InitialPackages()[0]

	// prepare map of resolved imports
	packages := make(map[string]Package)
	for _, pkg := range top.Pkg.Imports() {
		if IsStdlib(pkg.Path()) {
			continue
		}
		packages[pkg.Name()] = Package{
			Name: pkg.Name(),
			Path: pkg.Path(),
		}
	}

	return &Walker{
		P:          p,
		Packages:   packages,
		CacheLOC:   make(map[*ast.FuncDecl]int),
		CacheNodes: make(map[string]*ast.FuncDecl),

		Stdlib: false,

		Selectors: make(map[string]Selector),
		Counter:   make(map[string]int),
	}
}

// Walk walks through function body block,
// looking for internal and external dependencies expressions.
func (w *Walker) Walk(topNode ast.Node, parent *loader.PackageInfo, internal bool) (lines, depth, locCum, depthInt int) {
	ast.Inspect(topNode, func(n ast.Node) bool {
		switch x := n.(type) {
		case *ast.CallExpr:
			if !internal {
				return false
			}
			expr, ok := x.Fun.(*ast.Ident)
			if !ok {
				break
			}
			name := expr.Name

			// lookup this object in package
			obj := w.FindObject(parent, name)
			if obj == nil {
				return false
			}

			if _, ok := obj.Type().(*types.Signature); ok {
				node := w.FindFnNode(parent, name)
				// skip recursive calls
				if node == topNode {
					return false
				}

				if node != nil {
					depthInt++
					loc := w.LOC(node)
					locCum += loc

					lines1, depth1, lines2, depth2 := w.Walk(node, parent, true)
					lines = lines1
					depth += depth1
					locCum += lines2
					depthInt += depth2
				}
			}
		case *ast.SelectorExpr:
			var (
				n   string // package name
				obj types.Object
			)

			s, ok := parent.Selections[x]
			if ok {
				// (pkg).pkgvar.Method()
				obj = s.Obj()
				if obj.Pkg() == nil {
					return false
				}
				n = obj.Pkg().Name()
			} else {
				// pkg.Func()
				n = pkgName(x)
			}

			var pkg *loader.PackageInfo
			if n == parent.Pkg.Name() {
				pkg = parent
			} else {
				pkg = w.FindImport(parent, n)
				if pkg == nil {
					return false
				}
			}

			name := x.Sel.Name

			// lookup this object in package
			if obj == nil {
				obj = w.FindObject(pkg, name)
				if obj == nil {
					return false
				}
			}

			if _, ok := obj.Type().(*types.Signature); ok {
				node := w.FindFnNode(pkg, name)

				// skip recursive calls
				if node == topNode {
					return false
				}

				if node != nil {
					depth++
					lines1, depth1, lines2, depth2 := w.Walk(node, pkg, true)
					lines = lines1
					depth += depth1
					locCum += lines2
					depthInt += depth2
				}
			}
		}
		return true
	})
	return
}

func (w *Walker) FindObject(pkg *loader.PackageInfo, name string) types.Object {
	scope := pkg.Pkg.Scope()
	return scope.Lookup(name)
}

func (w *Walker) FindFnNode(pkg *loader.PackageInfo, fnName string) *ast.FuncDecl {
	var (
		node *ast.FuncDecl
		ok   bool
	)
	qName := fmt.Sprintf("%s.%s", pkg.Pkg.Path(), fnName)
	node, ok = w.CacheNodes[qName]
	if ok {
		return node
	}
	for _, f := range pkg.Files {
		ast.Inspect(f, func(n ast.Node) bool {
			switch x := n.(type) {
			case *ast.FuncDecl:
				if x.Name.Name == fnName {
					if x.Body == nil {
						return false
						w.CacheNodes[qName] = nil
					}
					node = x
					w.CacheNodes[qName] = x
					return false
				}
			}
			return true
		})
		if node != nil {
			return node
		}
	}
	return nil
}

func (w *Walker) FindImport(parent *loader.PackageInfo, name string) *loader.PackageInfo {
	for _, p := range parent.Pkg.Imports() {
		if p.Name() == name {
			if !w.Stdlib {
				std := IsStdlib(p.Path())
				if std {
					return nil
				}
			}
			return w.P.Package(p.Path())
		}
	}
	return nil
}

// LOC calculates readl Lines Of Code for the given function node.
// node must be ast.FuncDecl, panics otherwise.
func (w *Walker) LOC(node *ast.FuncDecl) int {
	if lines, ok := w.CacheLOC[node]; ok {
		return lines
	}

	body := node.Body
	if body == nil {
		return 0
		w.CacheLOC[node] = 0
	}

	start := w.P.Fset.Position(body.Lbrace)
	end := w.P.Fset.Position(body.Rbrace)
	lines := end.Line - start.Line

	// for cases line 'func foo() { bar() }'
	// TODO: figure out how to calculate it smarter
	if lines == 0 {
		lines = 1
	}

	w.CacheLOC[node] = lines

	return lines
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"fmt"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/mkideal/cli"
	"github.com/shopspring/decimal"
	"log"
	"math"
	"os"
)

var conn *ethclient.Client

var GethLocation string
var UsePort string
var UseIP string
var version string = "v0.0.1"

var decimals uint8

var help = cli.HelpCommand("display help information")

func main() {

	if err := cli.Root(root,
		cli.Tree(help),
		cli.Tree(child),
		cli.Tree(versionCli),
	).Run(os.Args[1:]); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

}

type rootT struct {
	cli.Helper
}

var root = &cli.Command{
	Desc: "\n      #######################\n" +
		"           TokenBalance\n" +
		"      #######################\n\n" +
		"TokenBalance is an easy to use server that \n" +
		"give you your ERC20 token balance without \n" +
		"any troubles. Connects to your local geth \n" +
		"IPC and prints out a simple JSON response \n" +
		"for ethereum token balances.",
	// Argv is a factory function of argument object
	// ctx.Argv() is if Command.Argv == nil or Command.Argv() is nil
	Argv: func() interface{} { return new(rootT) },
	Fn: func(ctx *cli.Context) error {

		ctx.String("To start the tokenbalance server, use command:\ntokenbalance --geth \"/root/ethereum/geth.ipc\" --port 8080 --ip 0.0.0.0\n * replace geth location with your own *\n")
		return nil
	},
}

// child command
type childT struct {
	cli.Helper
}

var child = &cli.Command{
	Name: "start",
	Desc: "run the tokenbalance http server",
	Argv: func() interface{} { return new(argT) },
	Fn: func(ctx *cli.Context) error {
		argv := ctx.Argv().(*argT)
		GethLocation = argv.Geth
		UsePort = argv.Port
		UseIP = argv.IP
		ConnectGeth()
		StartServer()

		return nil
	},
}

var versionCli = &cli.Command{
	Name: "version",
	Desc: "get the version of tokenbalance server",
	Argv: func() interface{} { return new(argT) },
	Fn: func(ctx *cli.Context) error {
		ctx.String(version + "\n")
		return nil
	},
}

type argT struct {
	cli.Helper
	Geth string `cli:"*g,geth" usage:"geth IPC location"`
	IP   string `cli:"ip" usage:"Bind to IP Address" dft:"0.0.0.0"`
	Port string `cli:"p,port" usage:"HTTP port for JSON" dft:"8080"`
}

func ConnectGeth() {
	var err error
	conn, err = ethclient.Dial(GethLocation)
	if err != nil {
		log.Fatalln("Failed to connect to the Ethereum client: %v", err)
	} else {
		log.Println("Connected to Geth at: ", GethLocation)
	}
}

func GetAccount(contract string, wallet string) (string, string, string, uint8, string, uint64, error) {
	var err error

	token, err := NewTokenCaller(common.HexToAddress(contract), conn)
	if err != nil {
		log.Println("Failed to instantiate a Token contract: %v", err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}

	getBlock, err := conn.BlockByNumber(context.Background(), nil)
	if err != nil {
		log.Println("Failed to get current block number: ", err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}

	maxBlock := getBlock.NumberU64()

	address := common.HexToAddress(wallet)
	if err != nil {
		log.Println("Failed hex address: "+wallet, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}

	ethAmount, err := conn.BalanceAt(context.Background(), address, nil)
	if err != nil {
		log.Println("Failed to get ethereum balance from address: ", address, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}

	balance, err := token.BalanceOf(nil, address)
	if err != nil {
		log.Println("Failed to get balance from contract: "+contract, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}
	symbol, err := token.Symbol(nil)
	if err != nil {
		log.Println("Failed to get symbol from contract: "+contract, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}
	tokenDecimals, err := token.Decimals(nil)
	if err != nil {
		log.Println("Failed to get decimals from contract: "+contract, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}
	name, err := token.Name(nil)
	if err != nil {
		log.Println("Failed to retrieve token name from contract: "+contract, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}

	ethBalance, _ := decimal.NewFromString(ethAmount.String())
	ethFac, _ := decimal.NewFromString("0.000000000000000001")
	ethCorrected := ethBalance.Mul(ethFac)

	tokenBalance, _ := decimal.NewFromString(balance.String())
	tokenMul := decimal.NewFromFloat(float64(0.1)).Pow(decimal.NewFromFloat(float64(tokenDecimals)))
	tokenCorrected := tokenBalance.Mul(tokenMul)

	return name, tokenCorrected.String(), symbol, decimals, ethCorrected.String(), maxBlock, err

}

func round(num float64) int {
	return int(num + math.Copysign(0.5, num))
}

func toFixed(num float64, precision int) float64 {
	output := math.Pow(10, float64(precision))
	return float64(round(num*output)) / output
}
<commit_msg>updated startup script<commit_after>package main

import (
	"context"
	"fmt"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/mkideal/cli"
	"github.com/shopspring/decimal"
	"log"
	"math"
	"os"
)

var conn *ethclient.Client

var GethLocation string
var UsePort string
var UseIP string
var version string = "v0.0.1"

var decimals uint8

var help = cli.HelpCommand("display help information")

func main() {

	if err := cli.Root(root,
		cli.Tree(help),
		cli.Tree(child),
		cli.Tree(versionCli),
	).Run(os.Args[1:]); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

}

type rootT struct {
	cli.Helper
}

var root = &cli.Command{
	Desc: "\n      #######################\n" +
		"           TokenBalance\n" +
		"      #######################\n\n" +
		"TokenBalance is an easy to use server that \n" +
		"give you your ERC20 token balance without \n" +
		"any troubles. Connects to your local geth \n" +
		"IPC and prints out a simple JSON response \n" +
		"for ethereum token balances.",
	// Argv is a factory function of argument object
	// ctx.Argv() is if Command.Argv == nil or Command.Argv() is nil
	Argv: func() interface{} { return new(rootT) },
	Fn: func(ctx *cli.Context) error {

		ctx.String("To start the tokenbalance server, use command:\ntokenbalance start --geth \"/root/ethereum/geth.ipc\" --port 8080 --ip 0.0.0.0\n * replace geth location with your own *\n")
		return nil
	},
}

// child command
type childT struct {
	cli.Helper
}

var child = &cli.Command{
	Name: "start",
	Desc: "run the tokenbalance http server",
	Argv: func() interface{} { return new(argT) },
	Fn: func(ctx *cli.Context) error {
		argv := ctx.Argv().(*argT)
		GethLocation = argv.Geth
		UsePort = argv.Port
		UseIP = argv.IP
		ConnectGeth()
		StartServer()

		return nil
	},
}

var versionCli = &cli.Command{
	Name: "version",
	Desc: "get the version of tokenbalance server",
	Argv: func() interface{} { return new(argT) },
	Fn: func(ctx *cli.Context) error {
		ctx.String(version + "\n")
		return nil
	},
}

type argT struct {
	cli.Helper
	Geth string `cli:"*g,geth" usage:"geth IPC location"`
	IP   string `cli:"ip" usage:"Bind to IP Address" dft:"0.0.0.0"`
	Port string `cli:"p,port" usage:"HTTP port for JSON" dft:"8080"`
}

func ConnectGeth() {
	var err error
	conn, err = ethclient.Dial(GethLocation)
	if err != nil {
		log.Fatalln("Failed to connect to the Ethereum client: %v", err)
	} else {
		log.Println("Connected to Geth at: ", GethLocation)
	}
}

func GetAccount(contract string, wallet string) (string, string, string, uint8, string, uint64, error) {
	var err error

	token, err := NewTokenCaller(common.HexToAddress(contract), conn)
	if err != nil {
		log.Println("Failed to instantiate a Token contract: %v", err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}

	getBlock, err := conn.BlockByNumber(context.Background(), nil)
	if err != nil {
		log.Println("Failed to get current block number: ", err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}

	maxBlock := getBlock.NumberU64()

	address := common.HexToAddress(wallet)
	if err != nil {
		log.Println("Failed hex address: "+wallet, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}

	ethAmount, err := conn.BalanceAt(context.Background(), address, nil)
	if err != nil {
		log.Println("Failed to get ethereum balance from address: ", address, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}

	balance, err := token.BalanceOf(nil, address)
	if err != nil {
		log.Println("Failed to get balance from contract: "+contract, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}
	symbol, err := token.Symbol(nil)
	if err != nil {
		log.Println("Failed to get symbol from contract: "+contract, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}
	tokenDecimals, err := token.Decimals(nil)
	if err != nil {
		log.Println("Failed to get decimals from contract: "+contract, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}
	name, err := token.Name(nil)
	if err != nil {
		log.Println("Failed to retrieve token name from contract: "+contract, err)
		return "error", "0.0", "error", 0, "0.0", 0, err
	}

	ethBalance, _ := decimal.NewFromString(ethAmount.String())
	ethFac, _ := decimal.NewFromString("0.000000000000000001")
	ethCorrected := ethBalance.Mul(ethFac)

	tokenBalance, _ := decimal.NewFromString(balance.String())
	tokenMul := decimal.NewFromFloat(float64(0.1)).Pow(decimal.NewFromFloat(float64(tokenDecimals)))
	tokenCorrected := tokenBalance.Mul(tokenMul)

	return name, tokenCorrected.String(), symbol, decimals, ethCorrected.String(), maxBlock, err

}

func round(num float64) int {
	return int(num + math.Copysign(0.5, num))
}

func toFixed(num float64, precision int) float64 {
	output := math.Pow(10, float64(precision))
	return float64(round(num*output)) / output
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	// "strings"

	"github.com/cucumber/godog"
	"github.com/ii/xds-test-harness/internal/parser"
	"github.com/ii/xds-test-harness/internal/runner"
	"github.com/ii/xds-test-harness/internal/types"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	"github.com/spf13/pflag"
)

var (
	debug          = pflag.BoolP("debug", "D", false, "sets log level to debug")
	testWriting    = pflag.BoolP("testwriting", "W", false, "Sets a pretty output that doesn't write to file, for better feedback while writing tests.")
	config         = pflag.StringP("config", "C", "", "Path to optional config file. This file sets the adapter and target addresses and supported variants.")
	adapterAddress = pflag.StringP("adapter", "A", ":17000", "port of adapter on target")
	targetAddress  = pflag.StringP("target", "T", ":18000", "port of xds target to test")
	nodeID         = pflag.StringP("nodeID", "N", "test-id", "node id of target")
	variant        = pflag.StringArrayP("variant", "V", []string{"sotw non-aggregated", "sotw aggregated", "incremental non-aggregated", "incremental aggregated"}, "xDS protocol variant your server supports. Add a separate flag per each supported variant.\n Possibleariants are: sotw non-aggregated\n, sotw aggregated\n, incremental non-aggregated\n, incremental aggregated\n.")
	godogOpts      = godog.Options{}
)

func init() {
	godog.BindCommandLineFlags("godog.", &godogOpts)
	zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
	zerolog.SetGlobalLevel(zerolog.InfoLevel)
}

func main() {
	pflag.Parse()
	godogTags := godogOpts.Tags

	if *debug {
		zerolog.SetGlobalLevel(zerolog.DebugLevel)
	}

	// default to using CLI Flag for settings
	err, supportedVariants := parser.ParseSupportedVariants(*variant)
	if err != nil {
		log.Fatal().Msgf("Cannot parse variants from CLI: %v\n", err)
	}
	// If config present, use it for all non-debugging values
	if *config != "" {
		*targetAddress, *adapterAddress, *nodeID, supportedVariants = parser.ValuesFromConfig(*config)
	}

	var results types.Results
	for _, variant := range supportedVariants {
		log.Info().
			Msgf("Starting Tests for %v\n", string(variant))

		suite := runner.NewSuite(variant, *testWriting)
		err, variantResults := suite.Run(*adapterAddress, *targetAddress, *nodeID, godogTags)
		if err != nil {
			log.Fatal().
				Msgf("Error when attempting to run test suite: %v\n", err)
		}
		results = runner.UpdateResults(results, variantResults)
	}
	if !*testWriting {
		printResults(results)
		file, _ := json.MarshalIndent(results, "", "  ")
		_ = ioutil.WriteFile("results.json", file, 0644)
	}
	os.Exit(0)
}

func printResults(results types.Results) {

	divider := "-------------------"
	fmt.Println("\nTest Suite Finished\n" + divider)
	fmt.Printf("Ran %v tests across %v variants\n\n", results.Total, len(results.Variants))
	fmt.Println("Passed: ", results.Passed)
	if results.Failed > 0 {
	  fmt.Println("Failed: ", results.Failed)
	}
	if results.Skipped > 0 {
	  fmt.Println("Skipped: ", results.Skipped)
	}
	if results.Undefined > 0 {
	  fmt.Println("Undefined: ", results.Undefined)
	}
	if results.Pending > 0 {
	  fmt.Println("Pending: ", results.Pending)
	}
	fmt.Printf("\n\nResults broken down by Variant....\n\n")
	for _, variant := range results.ResultsByVariant {
		fmt.Println(variant.Name+"\n"+divider)
		fmt.Println(variantResults(variant))
	}
}

func variantResults(results types.VariantResults) string {
	total := fmt.Sprintf("Total tests: %v\n", results.Total)
	passed := fmt.Sprintf("Passed: %v\n", results.Passed)
	failed := fmt.Sprintf("Failed: %v\n", results.Failed)
	skipped := fmt.Sprintf("Skipped: %v\n", results.Skipped)
	undefined := fmt.Sprintf("Undefined: %v\n", results.Undefined)
	pending := fmt.Sprintf("Pending: %v\n", results.Pending)
	var failedTests string
	if len(results.FailedScenarios) > 0 {
		failedTests = "Failed Tests:\n"
		for _, test := range results.FailedScenarios {
			failedTests = failedTests + "  - " + test.Name + "\n"
		}
	}
	return total + passed + failed + failedTests + skipped + undefined + pending
}
<commit_msg>centralize error and logging when building suite<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	// "strings"

	"github.com/cucumber/godog"
	"github.com/ii/xds-test-harness/internal/parser"
	"github.com/ii/xds-test-harness/internal/runner"
	"github.com/ii/xds-test-harness/internal/types"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	"github.com/spf13/pflag"
)

var (
	debug          = pflag.BoolP("debug", "D", false, "sets log level to debug")
	testWriting    = pflag.BoolP("testwriting", "W", false, "Sets a pretty output that doesn't write to file, for better feedback while writing tests.")
	config         = pflag.StringP("config", "C", "", "Path to optional config file. This file sets the adapter and target addresses and supported variants.")
	adapterAddress = pflag.StringP("adapter", "A", ":17000", "port of adapter on target")
	targetAddress  = pflag.StringP("target", "T", ":18000", "port of xds target to test")
	nodeID         = pflag.StringP("nodeID", "N", "test-id", "node id of target")
	variant        = pflag.StringArrayP("variant", "V", []string{"sotw non-aggregated", "sotw aggregated", "incremental non-aggregated", "incremental aggregated"}, "xDS protocol variant your server supports. Add a separate flag per each supported variant.\n Possibleariants are: sotw non-aggregated\n, sotw aggregated\n, incremental non-aggregated\n, incremental aggregated\n.")
	godogOpts      = godog.Options{}
)

func init() {
	godog.BindCommandLineFlags("godog.", &godogOpts)
	zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
	zerolog.SetGlobalLevel(zerolog.InfoLevel)
}

func main() {
	pflag.Parse()
	godogTags := godogOpts.Tags

	if *debug {
		zerolog.SetGlobalLevel(zerolog.DebugLevel)
	}

	// default to using CLI Flag for settings
	err, supportedVariants := parser.ParseSupportedVariants(*variant)
	if err != nil {
		log.Fatal().Msgf("Cannot parse variants from CLI: %v\n", err)
	}
	// If config present, use it for all non-debugging values
	if *config != "" {
		*targetAddress, *adapterAddress, *nodeID, supportedVariants = parser.ValuesFromConfig(*config)
	}

	var results types.Results
	for _, variant := range supportedVariants {
		log.Info().
			Msgf("Starting Tests for %v\n", string(variant))

		suite := runner.NewSuite(variant, *testWriting)
		if err = suite.StartRunner(*nodeID, *adapterAddress, *targetAddress); err != nil {
			log.Fatal().
				Err(err).
				Msg("Could not start runner.")
		}
		if err = suite.SetTags(godogTags); err != nil {
			log.Fatal().
				Err(err).
				Msg("Could not set tags properly to start up test suite.")
		}
		suite.ConfigureSuite()

		variantResults, err := suite.Run()
		if err != nil {
			log.Fatal().
				Msgf("Error when attempting to run test suite: %v\n", err)
		}
		results = runner.UpdateResults(results, variantResults)
	}
	if !*testWriting {
		printResults(results)
		file, _ := json.MarshalIndent(results, "", "  ")
		_ = ioutil.WriteFile("results.json", file, 0644)
	}
	os.Exit(0)
}

func printResults(results types.Results) {

	divider := "-------------------"
	fmt.Println("\nTest Suite Finished\n" + divider)
	fmt.Printf("Ran %v tests across %v variants\n\n", results.Total, len(results.Variants))
	fmt.Println("Passed: ", results.Passed)
	if results.Failed > 0 {
		fmt.Println("Failed: ", results.Failed)
	}
	if results.Skipped > 0 {
		fmt.Println("Skipped: ", results.Skipped)
	}
	if results.Undefined > 0 {
		fmt.Println("Undefined: ", results.Undefined)
	}
	if results.Pending > 0 {
		fmt.Println("Pending: ", results.Pending)
	}
	fmt.Printf("\n\nResults broken down by Variant....\n\n")
	for _, variant := range results.ResultsByVariant {
		if variant.Total > 0 {
			fmt.Println(variant.Name + "\n" + divider)
			fmt.Println(variantResults(variant))
		}
	}
}

func variantResults(results types.VariantResults) string {
	total := fmt.Sprintf("Total tests: %v\n", results.Total)
	passed := fmt.Sprintf("Passed: %v\n", results.Passed)
	failed := fmt.Sprintf("Failed: %v\n", results.Failed)
	skipped := fmt.Sprintf("Skipped: %v\n", results.Skipped)
	undefined := fmt.Sprintf("Undefined: %v\n", results.Undefined)
	pending := fmt.Sprintf("Pending: %v\n", results.Pending)
	var failedTests string
	if len(results.FailedScenarios) > 0 {
		failedTests = "Failed Tests:\n"
		for _, test := range results.FailedScenarios {
			failedTests = failedTests + "  - " + test.Name + "\n"
		}
	}
	return total + passed + failed + failedTests + skipped + undefined + pending
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
	"github.com/aws/aws-sdk-go/aws/ec2metadata"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ssm"
	"log"
	"os"
	"os/exec"
	"strings"
	"syscall"
)

var verbose = os.Getenv("ENV_INJECTOR_VERBOSE") == "1"

func main() {
	injectEnviron()

	args := os.Args
	if len(args) <= 1 {
		log.Fatal("missing command")
	}

	path, err := exec.LookPath(args[1])
	if err != nil {
		log.Fatal(err)
	}
	err = syscall.Exec(path, args[1:], os.Environ())
	if err != nil {
		log.Fatal(err)
	}
}

func trace(v ...interface{}) {
	if verbose {
		log.Println(v...)
	}
}

func tracef(format string, v ...interface{}) {
	if verbose {
		log.Printf(format, v...)
	}
}

func injectEnviron() {
	prefix := os.Getenv("ENV_INJECTOR_PREFIX")
	if prefix == "" {
		trace("no parameter prefix specified, skipping injection")
		return
	}
	tracef("parameter prefix: %s", prefix)
	if !strings.HasSuffix(prefix, ".") {
		prefix += "."
	}

	names := []*string{}
	for _, env := range os.Environ() {
		parts := strings.SplitN(env, "=", 2)
		if len(parts) == 2 && parts[1] == "" {
			names = append(names, aws.String(prefix+parts[0]))
		}
	}
	if len(names) == 0 {
		trace("nothing to be injected")
		return
	}

	sess, err := session.NewSessionWithOptions(session.Options{
		SharedConfigState: session.SharedConfigEnable,
	})
	if err != nil {
		trace(err)
		trace("failed to create session")
		return
	}
	if *sess.Config.Region == "" {
		trace("no explict region configuration. So now retriving ec2metadata...")
		region, err := ec2metadata.New(sess).Region()
		if err != nil {
			trace(err)
			trace("could not find region configuration")
			return
		}
		sess.Config.Region = aws.String(region)
	}

	var svc *ssm.SSM
	if arn := os.Getenv("ENV_INJECTOR_ASSUME_ROLE_ARN"); arn != "" {
		creds := stscreds.NewCredentials(sess, arn)
		svc = ssm.New(sess, &aws.Config{Credentials: creds})
	} else {
		svc = ssm.New(sess)
	}

	result, err := svc.GetParameters(&ssm.GetParametersInput{
		Names:          names,
		WithDecryption: aws.Bool(true),
	})
	if err != nil {
		trace(err)
		return
	}

	for _, key := range result.InvalidParameters {
		tracef("invalid parameter: %s", *key)
	}
	for _, param := range result.Parameters {
		key := strings.TrimPrefix(*param.Name, prefix)
		os.Setenv(key, *param.Value)
		tracef("env injected: %s", key)
	}
}
<commit_msg>fix typo<commit_after>package main

import (
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
	"github.com/aws/aws-sdk-go/aws/ec2metadata"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ssm"
	"log"
	"os"
	"os/exec"
	"strings"
	"syscall"
)

var verbose = os.Getenv("ENV_INJECTOR_VERBOSE") == "1"

func main() {
	injectEnviron()

	args := os.Args
	if len(args) <= 1 {
		log.Fatal("missing command")
	}

	path, err := exec.LookPath(args[1])
	if err != nil {
		log.Fatal(err)
	}
	err = syscall.Exec(path, args[1:], os.Environ())
	if err != nil {
		log.Fatal(err)
	}
}

func trace(v ...interface{}) {
	if verbose {
		log.Println(v...)
	}
}

func tracef(format string, v ...interface{}) {
	if verbose {
		log.Printf(format, v...)
	}
}

func injectEnviron() {
	prefix := os.Getenv("ENV_INJECTOR_PREFIX")
	if prefix == "" {
		trace("no parameter prefix specified, skipping injection")
		return
	}
	tracef("parameter prefix: %s", prefix)
	if !strings.HasSuffix(prefix, ".") {
		prefix += "."
	}

	names := []*string{}
	for _, env := range os.Environ() {
		parts := strings.SplitN(env, "=", 2)
		if len(parts) == 2 && parts[1] == "" {
			names = append(names, aws.String(prefix+parts[0]))
		}
	}
	if len(names) == 0 {
		trace("nothing to be injected")
		return
	}

	sess, err := session.NewSessionWithOptions(session.Options{
		SharedConfigState: session.SharedConfigEnable,
	})
	if err != nil {
		trace(err)
		trace("failed to create session")
		return
	}
	if *sess.Config.Region == "" {
		trace("no explicit region configuration. So now retrieving ec2metadata...")
		region, err := ec2metadata.New(sess).Region()
		if err != nil {
			trace(err)
			trace("could not find region configuration")
			return
		}
		sess.Config.Region = aws.String(region)
	}

	var svc *ssm.SSM
	if arn := os.Getenv("ENV_INJECTOR_ASSUME_ROLE_ARN"); arn != "" {
		creds := stscreds.NewCredentials(sess, arn)
		svc = ssm.New(sess, &aws.Config{Credentials: creds})
	} else {
		svc = ssm.New(sess)
	}

	result, err := svc.GetParameters(&ssm.GetParametersInput{
		Names:          names,
		WithDecryption: aws.Bool(true),
	})
	if err != nil {
		trace(err)
		return
	}

	for _, key := range result.InvalidParameters {
		tracef("invalid parameter: %s", *key)
	}
	for _, param := range result.Parameters {
		key := strings.TrimPrefix(*param.Name, prefix)
		os.Setenv(key, *param.Value)
		tracef("env injected: %s", key)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"strings"
)

func main() {
	log.SetFlags(0)
	if len(os.Args) != 4 {
		log.Fatal("Usage: relup <user/repo> <tagname> <assetfile>\n  i.e. relup calmh/relup v1.0.0 relup-binary.tar.gz")
	}
	repo := os.Args[1]
	tag := os.Args[2]
	file := os.Args[3]
	token := os.Getenv("GITHUB_TOKEN")
	if token == "" {
		log.Fatal("Please export GITHUB_TOKEN=\"<your token here>\"")
	}

	req, err := http.NewRequest("GET", fmt.Sprintf("https://api.github.com/repos/%s/releases", repo), nil)
	req.Header.Set("Authorization", "token "+token)
	if err != nil {
		log.Fatal(err)
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	if resp.StatusCode != http.StatusOK {
		bs, _ := ioutil.ReadAll(resp.Body)
		log.Fatal(resp.Status + ":\n" + string(bs))
	}

	var res []map[string]interface{}
	dec := json.NewDecoder(resp.Body)
	dec.UseNumber()
	err = dec.Decode(&res)
	if err != nil {
		log.Fatal(err)
	}
	resp.Body.Close()

	var uploadURL string
	for _, rel := range res {
		if rel["tag_name"] == tag {
			uploadURL = rel["upload_url"].(string)
			break
		}
	}

	if uploadURL == "" {
		log.Fatalln("Found no release with that tag")
	}

	fd, err := os.Open(file)
	if err != nil {
		log.Fatal(err)
	}
	fi, _ := fd.Stat()

	info, _ := fd.Stat()
	size := info.Size()
	progr := &progressWriter{
		expected: size,
	}
	tee := io.TeeReader(fd, progr)

	log.Println("Uploading", path.Base(file))
	url := strings.Replace(uploadURL, "{?name,label}", "?name="+path.Base(file), 1)
	req, err = http.NewRequest("POST", url, tee)
	if err != nil {
		log.Fatal(err)
	}

	req.ContentLength = fi.Size()
	req.Header.Set("Content-Type", "application/octet-stream")
	req.Header.Set("Authorization", "token "+token)

	resp, err = http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}

	progr.Close()
	log.Println(resp.Status)
}

type progressWriter struct {
	expected int64
	current  int64
}

func (p *progressWriter) Write(data []byte) (int, error) {
	p.current += int64(len(data))
	p.printProgress()
	return len(data), nil
}

func (p *progressWriter) Close() error {
	fmt.Println()
	return nil
}

func (p *progressWriter) printProgress() {
	pct := float64(p.current) / float64(p.expected) * 100
	fmt.Printf("\r%d / %d (%5.01f%%)", p.current, p.expected, pct)
}
<commit_msg>Remove progress writer<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"strings"
)

func main() {
	log.SetFlags(0)
	if len(os.Args) != 4 {
		log.Fatal("Usage: relup <user/repo> <tagname> <assetfile>\n  i.e. relup calmh/relup v1.0.0 relup-binary.tar.gz")
	}
	repo := os.Args[1]
	tag := os.Args[2]
	file := os.Args[3]
	token := os.Getenv("GITHUB_TOKEN")
	if token == "" {
		log.Fatal("Please export GITHUB_TOKEN=\"<your token here>\"")
	}

	req, err := http.NewRequest("GET", fmt.Sprintf("https://api.github.com/repos/%s/releases", repo), nil)
	req.Header.Set("Authorization", "token "+token)
	if err != nil {
		log.Fatal(err)
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	if resp.StatusCode != http.StatusOK {
		bs, _ := ioutil.ReadAll(resp.Body)
		log.Fatal(resp.Status + ":\n" + string(bs))
	}

	var res []map[string]interface{}
	dec := json.NewDecoder(resp.Body)
	dec.UseNumber()
	err = dec.Decode(&res)
	if err != nil {
		log.Fatal(err)
	}
	resp.Body.Close()

	var uploadURL string
	for _, rel := range res {
		if rel["tag_name"] == tag {
			uploadURL = rel["upload_url"].(string)
			break
		}
	}

	if uploadURL == "" {
		log.Fatalln("Found no release with that tag")
	}

	fd, err := os.Open(file)
	if err != nil {
		log.Fatal(err)
	}

	info, _ := fd.Stat()
	size := info.Size()

	log.Println("Uploading", path.Base(file))
	url := strings.Replace(uploadURL, "{?name,label}", "?name="+path.Base(file), 1)
	req, err = http.NewRequest("POST", url, fd)
	if err != nil {
		log.Fatal(err)
	}

	req.ContentLength = size
	req.Header.Set("Content-Type", "application/octet-stream")
	req.Header.Set("Authorization", "token "+token)

	resp, err = http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("Completed %s: %v", path.Base(file), resp.Status)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"go/format"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/maxbrunsfeld/counterfeiter/arguments"
	"github.com/maxbrunsfeld/counterfeiter/generator"
	"github.com/maxbrunsfeld/counterfeiter/locator"
	"github.com/maxbrunsfeld/counterfeiter/model"
	"github.com/maxbrunsfeld/counterfeiter/terminal"
)

func main() {
	flag.Parse()
	args := flag.Args()

	if len(args) < 1 {
		fail("%s", usage)
		return
	}

	argumentParser := arguments.NewArgumentParser(
		fail,
		cwd,
		filepath.EvalSymlinks,
		os.Stat,
		terminal.NewUI(),
	)
	parsedArgs := argumentParser.ParseArguments(args...)

	outputPath := parsedArgs.OutputPath
	destinationPackage := parsedArgs.DestinationPackageName

	if parsedArgs.GenerateInterfaceAndShimFromPackageDirectory {
		generateInterfaceAndShim(parsedArgs.SourcePackageDir, outputPath, destinationPackage, parsedArgs.PrintToStdOut)
	} else {
		generateFake(parsedArgs.InterfaceName, parsedArgs.SourcePackageDir, parsedArgs.ImportPath, outputPath, destinationPackage, parsedArgs.FakeImplName, parsedArgs.PrintToStdOut)
	}
}

func generateFake(interfaceName, sourcePackageDir, importPath, outputPath, destinationPackage, fakeName string, printToStdOut bool) {
	var err error
	var iface *model.InterfaceToFake
	if sourcePackageDir == "" {
		iface, err = locator.GetInterfaceFromImportPath(interfaceName, importPath)
	} else {
		iface, err = locator.GetInterfaceFromFilePath(interfaceName, sourcePackageDir)
	}
	if err != nil {
		fail("%v", err)
	}

	var code string
	code, err = generator.CodeGenerator{
		Model:       *iface,
		StructName:  fakeName,
		PackageName: destinationPackage,
	}.GenerateFake()

	if err != nil {
		fail("%v", err)
	}

	printCode(code, outputPath, printToStdOut)
	reportDone(outputPath, fakeName)
}

func generateInterfaceAndShim(sourceDir string, outputPath string, outPackage string, printToStdOut bool) {
	var code string
	functions, err := locator.GetFunctionsFromDirectory(path.Base(sourceDir), sourceDir)
	if err != nil {
		fail("%v", err)
	}

	interfaceName := strings.ToUpper(path.Base(sourceDir))[:1] + path.Base(sourceDir)[1:]

	code, err = generator.InterfaceGenerator{
		Model:                  functions,
		Package:                sourceDir,
		DestinationInterface:   interfaceName,
		DestinationPackageName: outPackage,
	}.GenerateInterface()

	if err != nil {
		fail("%v", err)
	}
	interfacePath := path.Join(outputPath, path.Base(sourceDir)+".go")
	interfaceDir := path.Dir(interfacePath)

	printCode(code, interfacePath, printToStdOut)

	reportDone(interfacePath, interfaceName)

	sourcePackage := path.Base(sourceDir)

	iface, err := locator.GetInterfaceFromFilePath(interfaceName, interfaceDir)
	if err != nil {
		fail("%v", err)
	}

	code, err = generator.ShimGenerator{
		Model:         *iface,
		StructName:    interfaceName + "Shim",
		PackageName:   outPackage,
		SourcePackage: sourcePackage,
	}.GenerateReal()

	if err != nil {
		fail("%v", err)
	}

	realPath := path.Join(interfaceDir, outPackage+".go")

	printCode(code, realPath, printToStdOut)
	reportDone(realPath, interfaceName+"Shim")
}

func printCode(code, outputPath string, printToStdOut bool) {
	newCode, err := format.Source([]byte(code))
	if err != nil {
		fail("%v", err)
	}

	code = string(newCode)

	if printToStdOut {
		fmt.Println(code)
	} else {
		os.MkdirAll(filepath.Dir(outputPath), 0777)
		file, err := os.Create(outputPath)
		if err != nil {
			fail("Couldn't create fake file - %v", err)
		}

		_, err = file.WriteString(code)
		if err != nil {
			fail("Couldn't write to fake file - %v", err)
		}
	}
}

func reportDone(outputPath, fakeName string) {
	rel, err := filepath.Rel(cwd(), outputPath)
	if err != nil {
		fail("%v", err)
	}

	fmt.Printf("Wrote `%s` to `%s`\n", fakeName, rel)
}

func cwd() string {
	dir, err := os.Getwd()
	if err != nil {
		fail("Error - couldn't determine current working directory")
	}
	return dir
}

func fail(s string, args ...interface{}) {
	fmt.Printf(s+"\n", args...)
	os.Exit(1)
}

var usage = `
USAGE
	counterfeiter
		[-o <output-path>] [-p] [--fake-name <fake-name>]
		[<source-path>] <interface> [-]

ARGUMENTS
	source-path
		Path to the file or directory containing the interface to fake.
		In package mode (-p), source-path should instead specify the path
		of the input package; alternatively you can use the package name
		(e.g. "os") and the path will be inferred from your GOROOT.

	interface
		If source-path is specified: Name of the interface to fake.
		If no source-path is specified: Fully qualified interface path of the interface to fake.
    If -p is specified, this will be the name of the interface to generate.

	example:
		# writes "FakeStdInterface" to ./fakes/fake_std_interface.go
		counterfeiter package/subpackage.StdInterface

	'-' argument
		Write code to standard out instead of to a file

OPTIONS
	-o
		Path to the file or directory for the generated fakes.
		This also determines the package name that will be used.
		By default, the generated fakes will be generated in
		the package "xyzfakes" which is nested in package "xyz",
		where "xyz" is the name of referenced package.

	example:
		# writes "FakeMyInterface" to ./fakes/fake_my_interface.go
		counterfeiter -o ./fakes MyInterface ./mypackage

	-p
		Package mode:  When invoked in package mode, counterfeiter
		will generate an interface and shim implementation from a
		package in your GOPATH.  Counterfeiter finds the public methods
		in the package <source-path> and adds those method signatures
		to the generated interface <interface-name>.

	example:
		# generates os.go (interface) and osshim.go (shim) in ${PWD}/osshim
		counterfeiter -p os
		# now generate fake in ${PWD}/osshim/os_fake (fake_os.go)
		go generate osshim/...

	--fake-name
		Name of the fake struct to generate. By default, 'Fake' will
		be prepended to the name of the original interface. (ignored in
		-p mode)

	example:
		# writes "CoolThing" to ./fakes/cool_thing.go
		counterfeiter --fake-name CoolThing MyInterface ./mypackage
`
<commit_msg>Update examples in help output<commit_after>package main

import (
	"flag"
	"fmt"
	"go/format"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/maxbrunsfeld/counterfeiter/arguments"
	"github.com/maxbrunsfeld/counterfeiter/generator"
	"github.com/maxbrunsfeld/counterfeiter/locator"
	"github.com/maxbrunsfeld/counterfeiter/model"
	"github.com/maxbrunsfeld/counterfeiter/terminal"
)

func main() {
	flag.Parse()
	args := flag.Args()

	if len(args) < 1 {
		fail("%s", usage)
		return
	}

	argumentParser := arguments.NewArgumentParser(
		fail,
		cwd,
		filepath.EvalSymlinks,
		os.Stat,
		terminal.NewUI(),
	)
	parsedArgs := argumentParser.ParseArguments(args...)

	outputPath := parsedArgs.OutputPath
	destinationPackage := parsedArgs.DestinationPackageName

	if parsedArgs.GenerateInterfaceAndShimFromPackageDirectory {
		generateInterfaceAndShim(parsedArgs.SourcePackageDir, outputPath, destinationPackage, parsedArgs.PrintToStdOut)
	} else {
		generateFake(parsedArgs.InterfaceName, parsedArgs.SourcePackageDir, parsedArgs.ImportPath, outputPath, destinationPackage, parsedArgs.FakeImplName, parsedArgs.PrintToStdOut)
	}
}

func generateFake(interfaceName, sourcePackageDir, importPath, outputPath, destinationPackage, fakeName string, printToStdOut bool) {
	var err error
	var iface *model.InterfaceToFake
	if sourcePackageDir == "" {
		iface, err = locator.GetInterfaceFromImportPath(interfaceName, importPath)
	} else {
		iface, err = locator.GetInterfaceFromFilePath(interfaceName, sourcePackageDir)
	}
	if err != nil {
		fail("%v", err)
	}

	var code string
	code, err = generator.CodeGenerator{
		Model:       *iface,
		StructName:  fakeName,
		PackageName: destinationPackage,
	}.GenerateFake()

	if err != nil {
		fail("%v", err)
	}

	printCode(code, outputPath, printToStdOut)
	reportDone(outputPath, fakeName)
}

func generateInterfaceAndShim(sourceDir string, outputPath string, outPackage string, printToStdOut bool) {
	var code string
	functions, err := locator.GetFunctionsFromDirectory(path.Base(sourceDir), sourceDir)
	if err != nil {
		fail("%v", err)
	}

	interfaceName := strings.ToUpper(path.Base(sourceDir))[:1] + path.Base(sourceDir)[1:]

	code, err = generator.InterfaceGenerator{
		Model:                  functions,
		Package:                sourceDir,
		DestinationInterface:   interfaceName,
		DestinationPackageName: outPackage,
	}.GenerateInterface()

	if err != nil {
		fail("%v", err)
	}
	interfacePath := path.Join(outputPath, path.Base(sourceDir)+".go")
	interfaceDir := path.Dir(interfacePath)

	printCode(code, interfacePath, printToStdOut)

	reportDone(interfacePath, interfaceName)

	sourcePackage := path.Base(sourceDir)

	iface, err := locator.GetInterfaceFromFilePath(interfaceName, interfaceDir)
	if err != nil {
		fail("%v", err)
	}

	code, err = generator.ShimGenerator{
		Model:         *iface,
		StructName:    interfaceName + "Shim",
		PackageName:   outPackage,
		SourcePackage: sourcePackage,
	}.GenerateReal()

	if err != nil {
		fail("%v", err)
	}

	realPath := path.Join(interfaceDir, outPackage+".go")

	printCode(code, realPath, printToStdOut)
	reportDone(realPath, interfaceName+"Shim")
}

func printCode(code, outputPath string, printToStdOut bool) {
	newCode, err := format.Source([]byte(code))
	if err != nil {
		fail("%v", err)
	}

	code = string(newCode)

	if printToStdOut {
		fmt.Println(code)
	} else {
		os.MkdirAll(filepath.Dir(outputPath), 0777)
		file, err := os.Create(outputPath)
		if err != nil {
			fail("Couldn't create fake file - %v", err)
		}

		_, err = file.WriteString(code)
		if err != nil {
			fail("Couldn't write to fake file - %v", err)
		}
	}
}

func reportDone(outputPath, fakeName string) {
	rel, err := filepath.Rel(cwd(), outputPath)
	if err != nil {
		fail("%v", err)
	}

	fmt.Printf("Wrote `%s` to `%s`\n", fakeName, rel)
}

func cwd() string {
	dir, err := os.Getwd()
	if err != nil {
		fail("Error - couldn't determine current working directory")
	}
	return dir
}

func fail(s string, args ...interface{}) {
	fmt.Printf(s+"\n", args...)
	os.Exit(1)
}

var usage = `
USAGE
	counterfeiter
		[-o <output-path>] [-p] [--fake-name <fake-name>]
		[<source-path>] <interface> [-]

ARGUMENTS
	source-path
		Path to the file or directory containing the interface to fake.
		In package mode (-p), source-path should instead specify the path
		of the input package; alternatively you can use the package name
		(e.g. "os") and the path will be inferred from your GOROOT.

	interface
		If source-path is specified: Name of the interface to fake.
		If no source-path is specified: Fully qualified interface path of the interface to fake.
    If -p is specified, this will be the name of the interface to generate.

	example:
		# writes "FakeStdInterface" to ./packagefakes/fake_std_interface.go
		counterfeiter package/subpackage.StdInterface

	'-' argument
		Write code to standard out instead of to a file

OPTIONS
	-o
		Path to the file or directory for the generated fakes.
		This also determines the package name that will be used.
		By default, the generated fakes will be generated in
		the package "xyzfakes" which is nested in package "xyz",
		where "xyz" is the name of referenced package.

	example:
		# writes "FakeMyInterface" to ./mySpecialFakesDir/specialFake.go
		counterfeiter -o ./mySpecialFakesDir/specialFake.go ./mypackage MyInterface

	-p
		Package mode:  When invoked in package mode, counterfeiter
		will generate an interface and shim implementation from a
		package in your GOPATH.  Counterfeiter finds the public methods
		in the package <source-path> and adds those method signatures
		to the generated interface <interface-name>.

	example:
		# generates os.go (interface) and osshim.go (shim) in ${PWD}/osshim
		counterfeiter -p os
		# now generate fake in ${PWD}/osshim/os_fake (fake_os.go)
		go generate osshim/...

	--fake-name
		Name of the fake struct to generate. By default, 'Fake' will
		be prepended to the name of the original interface. (ignored in
		-p mode)

	example:
		# writes "CoolThing" to ./mypackagefakes/cool_thing.go
		counterfeiter --fake-name CoolThing ./mypackage MyInterface
`
<|endoftext|>


<commit_before>package main

import (
	"./core"
	"fmt"
	"io"
	"os"
)

func main() {
	if len(os.Args) != 2 {
		fmt.Printf("ARMv7-M Emulator\n")
		fmt.Printf("usage: %s binary\n", os.Args[0])
		os.Exit(1)
	}

	binary := os.Args[1]
	file, err := os.Open(binary)
	if err != nil {
		fmt.Printf("%s\n", err)
		os.Exit(1)
	}

	//regs := new(core.Registers)
	b := make([]byte, 2, 2)
	var upper *core.FetchedInstr16 = nil

	for {
		n, err := file.Read(b)
		if err == io.EOF {
			break
		} else if err != nil {
			fmt.Printf("%s\n", err)
			os.Exit(1)
		} else if n != len(b) {
			fmt.Printf("not enough bytes read\n")
			os.Exit(1)
		}

		var fetched core.FetchedInstr

		fetched16 := core.FetchedInstr16((uint16(b[1]) << 8) | uint16(b[0]))

		if upper != nil {
			fetched = upper.Extend(fetched16)
			upper = nil
		} else {
			fetched = fetched16
		}

		instr, err := fetched.Decode()
		if err == core.IncompleteInstruction {
			upper = &fetched16
			continue
		} else if err != nil {
			fmt.Printf("%s (instr = %v)\n", err, fetched)
			continue
		}

		fmt.Printf("%#v\n", instr)
	}

	file.Close()
}
<commit_msg>Print in objdump style<commit_after>package main

import (
	"./core"
	"fmt"
	"io"
	"os"
)

func main() {
	if len(os.Args) != 2 {
		fmt.Printf("ARMv7-M Emulator\n")
		fmt.Printf("usage: %s binary\n", os.Args[0])
		os.Exit(1)
	}

	binary := os.Args[1]
	file, err := os.Open(binary)
	if err != nil {
		fmt.Printf("%s\n", err)
		os.Exit(1)
	}

	//regs := new(core.Registers)
	b := make([]byte, 2, 2)
	addr := 0
	var upper *core.FetchedInstr16 = nil

	for {
		n, err := file.Read(b)
		if err == io.EOF {
			break
		} else if err != nil {
			fmt.Printf("%s\n", err)
			os.Exit(1)
		} else if n != len(b) {
			fmt.Printf("not enough bytes read\n")
			os.Exit(1)
		}

		var fetched core.FetchedInstr

		fetched16 := core.FetchedInstr16((uint16(b[1]) << 8) | uint16(b[0]))

		if upper != nil {
			fmt.Printf(" %v", fetched16)
			fetched = upper.Extend(fetched16)
			upper = nil
		} else {
			fetched = fetched16
			fmt.Printf("%x:\t%v", addr, fetched)
		}

		addr += len(b)

		instr, err := fetched.Decode()
		if err == core.IncompleteInstruction {
			upper = &fetched16
			continue
		} else if err != nil {
			fmt.Printf("\t%s\n", err)
			continue
		}

		fmt.Printf("\t%#v\n", instr)
	}

	file.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"io/ioutil"
	"os"

	"github.com/mithrandie/csvq/lib/action"
	"github.com/mithrandie/csvq/lib/cmd"
	"github.com/mithrandie/csvq/lib/query"

	"github.com/urfave/cli"
)

var version = "v0.8.0"

func main() {
	cli.AppHelpTemplate = appHHelpTemplate
	cli.CommandHelpTemplate = commandHelpTemplate

	app := cli.NewApp()

	app.Name = "csvq"
	app.Usage = "SQL like query language for csv"
	app.ArgsUsage = "[\"query\"|\"statements\"|argument]"
	app.Version = version

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "delimiter, d",
			Usage: "field delimiter. Default is \",\" for csv files, \"\\t\" for tsv files.",
		},
		cli.StringFlag{
			Name:  "encoding, e",
			Value: "UTF8",
			Usage: "file encoding. one of: UTF8|SJIS",
		},
		cli.StringFlag{
			Name:  "line-break, l",
			Value: "LF",
			Usage: "line break. one of: CRLF|LF|CR",
		},
		cli.StringFlag{
			Name:  "timezone, z",
			Value: "Local",
			Usage: "default timezone. \"Local\", \"UTC\" or a timezone name(e.g. \"America/Los_Angeles\")",
		},
		cli.StringFlag{
			Name:  "repository, r",
			Usage: "directory path where files are located",
		},
		cli.StringFlag{
			Name:  "source, s",
			Usage: "load query from `FILE`",
		},
		cli.StringFlag{
			Name:  "datetime-format, t",
			Usage: "set datetime format to parse strings",
		},
		cli.StringFlag{
			Name:  "wait-timeout, w",
			Value: "10",
			Usage: "limit of the waiting time in seconds to wait for locked files to be released",
		},
		cli.BoolFlag{
			Name:  "no-header, n",
			Usage: "import the first line as a record",
		},
		cli.BoolFlag{
			Name:  "without-null, a",
			Usage: "parse empty fields as empty strings",
		},
		cli.StringFlag{
			Name:  "write-encoding, E",
			Value: "UTF8",
			Usage: "file encoding. one of: UTF8|SJIS",
		},
		cli.StringFlag{
			Name:  "out, o",
			Usage: "write output to `FILE`",
		},
		cli.StringFlag{
			Name:  "format, f",
			Usage: "output format. one of: CSV|TSV|JSON|TEXT",
		},
		cli.StringFlag{
			Name:  "write-delimiter, D",
			Usage: "field delimiter for CSV",
		},
		cli.BoolFlag{
			Name:  "without-header, N",
			Usage: "when the file format is specified as CSV or TSV, write without the header line",
		},
		cli.BoolFlag{
			Name:  "quiet, q",
			Usage: "suppress operation log output",
		},
		cli.IntFlag{
			Name:  "cpu, p",
			Usage: "hint for the number of cpu cores to be used. 1 - number of cpu cores",
		},
		cli.BoolFlag{
			Name:  "stats, x",
			Usage: "show execution time and memory statistics",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "fields",
			Usage:     "Show fields in a file",
			ArgsUsage: "CSV_FILE_PATH",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					cli.ShowCommandHelp(c, "fields")
					return cli.NewExitError("table is not specified", 1)
				}

				table := c.Args().First()

				err := action.ShowFields(table)
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}

				return nil
			},
		},
		{
			Name:      "calc",
			Usage:     "Calculate a value from stdin",
			ArgsUsage: "\"expression\"",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					cli.ShowCommandHelp(c, "calc")
					return cli.NewExitError("expression is empty", 1)
				}

				expr := c.Args().First()
				err := action.Calc(expr)
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}

				return nil
			},
		},
	}

	app.Before = func(c *cli.Context) error {
		err := setFlags(c)
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}
		return nil
	}

	app.Action = func(c *cli.Context) error {
		queryString, err := readQuery(c)
		if err != nil {
			cli.ShowAppHelp(c)
			return cli.NewExitError(err.Error(), 1)
		}

		if len(queryString) < 1 {
			err = action.LaunchInteractiveShell()
		} else {
			err = action.Run(queryString, cmd.GetFlags().Source)
		}

		if err != nil {
			code := 1
			if apperr, ok := err.(query.AppError); ok {
				code = apperr.GetCode()
			} else if ex, ok := err.(*query.Exit); ok {
				code = ex.GetCode()
			}
			return cli.NewExitError(err.Error(), code)
		}

		return nil
	}

	app.Run(os.Args)
}

func readQuery(c *cli.Context) (string, error) {
	var queryString string

	flags := cmd.GetFlags()
	if 0 < len(flags.Source) {
		fp, err := os.Open(flags.Source)
		if err != nil {
			return queryString, err
		}
		defer fp.Close()

		buf, err := ioutil.ReadAll(fp)
		if err != nil {
			return queryString, err
		}
		queryString = string(buf)

	} else {
		if 1 < c.NArg() {
			return queryString, errors.New("multiple queries or statements were passed")
		}
		queryString = c.Args().First()
	}

	return queryString, nil
}

func setFlags(c *cli.Context) error {
	if err := cmd.SetDelimiter(c.GlobalString("delimiter")); err != nil {
		return err
	}
	if err := cmd.SetEncoding(c.GlobalString("encoding")); err != nil {
		return err
	}
	if err := cmd.SetLineBreak(c.String("line-break")); err != nil {
		return err
	}
	if err := cmd.SetLocation(c.String("timezone")); err != nil {
		return err
	}
	if err := cmd.SetRepository(c.GlobalString("repository")); err != nil {
		return err
	}
	if err := cmd.SetSource(c.GlobalString("source")); err != nil {
		return err
	}
	cmd.SetDatetimeFormat(c.GlobalString("datetime-format"))
	if err := cmd.SetWaitTimeout(c.GlobalString("wait-timeout")); err != nil {
		return err
	}
	cmd.SetNoHeader(c.GlobalBool("no-header"))
	cmd.SetWithoutNull(c.GlobalBool("without-null"))

	if err := cmd.SetWriteEncoding(c.GlobalString("write-encoding")); err != nil {
		return err
	}
	if err := cmd.SetOut(c.GlobalString("out")); err != nil {
		return err
	}
	if err := cmd.SetFormat(c.GlobalString("format")); err != nil {
		return err
	}
	if err := cmd.SetWriteDelimiter(c.GlobalString("write-delimiter")); err != nil {
		return err
	}
	cmd.SetWithoutHeader(c.GlobalBool("without-header"))

	cmd.SetQuiet(c.GlobalBool("quiet"))
	cmd.SetCPU(c.GlobalInt("cpu"))
	cmd.SetStats(c.GlobalBool("stats"))

	return nil
}
<commit_msg>Update version for Release v0.8.1<commit_after>package main

import (
	"errors"
	"io/ioutil"
	"os"

	"github.com/mithrandie/csvq/lib/action"
	"github.com/mithrandie/csvq/lib/cmd"
	"github.com/mithrandie/csvq/lib/query"

	"github.com/urfave/cli"
)

var version = "v0.8.1"

func main() {
	cli.AppHelpTemplate = appHHelpTemplate
	cli.CommandHelpTemplate = commandHelpTemplate

	app := cli.NewApp()

	app.Name = "csvq"
	app.Usage = "SQL like query language for csv"
	app.ArgsUsage = "[\"query\"|\"statements\"|argument]"
	app.Version = version

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "delimiter, d",
			Usage: "field delimiter. Default is \",\" for csv files, \"\\t\" for tsv files.",
		},
		cli.StringFlag{
			Name:  "encoding, e",
			Value: "UTF8",
			Usage: "file encoding. one of: UTF8|SJIS",
		},
		cli.StringFlag{
			Name:  "line-break, l",
			Value: "LF",
			Usage: "line break. one of: CRLF|LF|CR",
		},
		cli.StringFlag{
			Name:  "timezone, z",
			Value: "Local",
			Usage: "default timezone. \"Local\", \"UTC\" or a timezone name(e.g. \"America/Los_Angeles\")",
		},
		cli.StringFlag{
			Name:  "repository, r",
			Usage: "directory path where files are located",
		},
		cli.StringFlag{
			Name:  "source, s",
			Usage: "load query from `FILE`",
		},
		cli.StringFlag{
			Name:  "datetime-format, t",
			Usage: "set datetime format to parse strings",
		},
		cli.StringFlag{
			Name:  "wait-timeout, w",
			Value: "10",
			Usage: "limit of the waiting time in seconds to wait for locked files to be released",
		},
		cli.BoolFlag{
			Name:  "no-header, n",
			Usage: "import the first line as a record",
		},
		cli.BoolFlag{
			Name:  "without-null, a",
			Usage: "parse empty fields as empty strings",
		},
		cli.StringFlag{
			Name:  "write-encoding, E",
			Value: "UTF8",
			Usage: "file encoding. one of: UTF8|SJIS",
		},
		cli.StringFlag{
			Name:  "out, o",
			Usage: "write output to `FILE`",
		},
		cli.StringFlag{
			Name:  "format, f",
			Usage: "output format. one of: CSV|TSV|JSON|TEXT",
		},
		cli.StringFlag{
			Name:  "write-delimiter, D",
			Usage: "field delimiter for CSV",
		},
		cli.BoolFlag{
			Name:  "without-header, N",
			Usage: "when the file format is specified as CSV or TSV, write without the header line",
		},
		cli.BoolFlag{
			Name:  "quiet, q",
			Usage: "suppress operation log output",
		},
		cli.IntFlag{
			Name:  "cpu, p",
			Usage: "hint for the number of cpu cores to be used. 1 - number of cpu cores",
		},
		cli.BoolFlag{
			Name:  "stats, x",
			Usage: "show execution time and memory statistics",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "fields",
			Usage:     "Show fields in a file",
			ArgsUsage: "CSV_FILE_PATH",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					cli.ShowCommandHelp(c, "fields")
					return cli.NewExitError("table is not specified", 1)
				}

				table := c.Args().First()

				err := action.ShowFields(table)
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}

				return nil
			},
		},
		{
			Name:      "calc",
			Usage:     "Calculate a value from stdin",
			ArgsUsage: "\"expression\"",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					cli.ShowCommandHelp(c, "calc")
					return cli.NewExitError("expression is empty", 1)
				}

				expr := c.Args().First()
				err := action.Calc(expr)
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}

				return nil
			},
		},
	}

	app.Before = func(c *cli.Context) error {
		err := setFlags(c)
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}
		return nil
	}

	app.Action = func(c *cli.Context) error {
		queryString, err := readQuery(c)
		if err != nil {
			cli.ShowAppHelp(c)
			return cli.NewExitError(err.Error(), 1)
		}

		if len(queryString) < 1 {
			err = action.LaunchInteractiveShell()
		} else {
			err = action.Run(queryString, cmd.GetFlags().Source)
		}

		if err != nil {
			code := 1
			if apperr, ok := err.(query.AppError); ok {
				code = apperr.GetCode()
			} else if ex, ok := err.(*query.Exit); ok {
				code = ex.GetCode()
			}
			return cli.NewExitError(err.Error(), code)
		}

		return nil
	}

	app.Run(os.Args)
}

func readQuery(c *cli.Context) (string, error) {
	var queryString string

	flags := cmd.GetFlags()
	if 0 < len(flags.Source) {
		fp, err := os.Open(flags.Source)
		if err != nil {
			return queryString, err
		}
		defer fp.Close()

		buf, err := ioutil.ReadAll(fp)
		if err != nil {
			return queryString, err
		}
		queryString = string(buf)

	} else {
		if 1 < c.NArg() {
			return queryString, errors.New("multiple queries or statements were passed")
		}
		queryString = c.Args().First()
	}

	return queryString, nil
}

func setFlags(c *cli.Context) error {
	if err := cmd.SetDelimiter(c.GlobalString("delimiter")); err != nil {
		return err
	}
	if err := cmd.SetEncoding(c.GlobalString("encoding")); err != nil {
		return err
	}
	if err := cmd.SetLineBreak(c.String("line-break")); err != nil {
		return err
	}
	if err := cmd.SetLocation(c.String("timezone")); err != nil {
		return err
	}
	if err := cmd.SetRepository(c.GlobalString("repository")); err != nil {
		return err
	}
	if err := cmd.SetSource(c.GlobalString("source")); err != nil {
		return err
	}
	cmd.SetDatetimeFormat(c.GlobalString("datetime-format"))
	if err := cmd.SetWaitTimeout(c.GlobalString("wait-timeout")); err != nil {
		return err
	}
	cmd.SetNoHeader(c.GlobalBool("no-header"))
	cmd.SetWithoutNull(c.GlobalBool("without-null"))

	if err := cmd.SetWriteEncoding(c.GlobalString("write-encoding")); err != nil {
		return err
	}
	if err := cmd.SetOut(c.GlobalString("out")); err != nil {
		return err
	}
	if err := cmd.SetFormat(c.GlobalString("format")); err != nil {
		return err
	}
	if err := cmd.SetWriteDelimiter(c.GlobalString("write-delimiter")); err != nil {
		return err
	}
	cmd.SetWithoutHeader(c.GlobalBool("without-header"))

	cmd.SetQuiet(c.GlobalBool("quiet"))
	cmd.SetCPU(c.GlobalInt("cpu"))
	cmd.SetStats(c.GlobalBool("stats"))

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/alexcesaro/log"
	"github.com/alexcesaro/log/golog"
	"github.com/droundy/goopt"
	. "github.com/lkwg82/automatic-maven-pom-upgrade/lib"
	"os"
	"bytes"
	"runtime"
	"path"
	"strings"
)

var optQuiet = goopt.Flag([]string{"-q", "--quiet"}, nil, "suppress any output", "")
var optVersion = goopt.Flag([]string{"--version"}, nil, "show version", "")
var optType = goopt.Alternatives([]string{"-t", "--type"}, []string{"help", "parent"}, "type of upgrade")
var optVerbose = goopt.Flag([]string{"-v", "--verbose"}, nil, "output verbosely", "")

var logger golog.Logger

type funcErr func() error

func main() {
	git := NewGit(logger)

	maven := NewMaven(logger)

	parseParameter()

	if *optVersion {
		fmt.Printf("version %s\n", goopt.Version)
		os.Exit(0)
	}

	if *optType == "help" {
		fmt.Print(goopt.Usage())
		os.Exit(0)
	}

	exitOnError(git.CheckIsInstalled)
	exitOnError(git.CheckIsRepo)
	exitOnError(git.OptionalCheckIsDirty)

	git.Fetch()

	exitOnError(maven.DetermineCommand)
	exitOnError(maven.ParseCommandline)

	switch *optType {
	case "parent": updateParent(git, maven)
	default:
		panic("should never reach this point, wrong goopt config")
	}
}

func exitOnError(fun funcErr) {
	err := fun()
	if err != nil {
		logger.Emergency(err)
		os.Exit(1)
	}
}

func changeBranch(git *Git) {
	if branch := "autoupdate_" + *optType; git.BranchExists(branch) {
		git.BranchCheckoutExisting(branch)
	} else {
		git.BranchCheckoutNew(branch)
	}
}

func echo(format string, arg ...string) {
	if !*optQuiet {
		if len(arg) == 0 {
			fmt.Println(format)
		} else {
			fmt.Printf(format + "\n", arg)
		}
	}
}

func updateParent(git *Git, maven *Maven) {
	changeBranch(git)
	git.OptionalAutoMergeMaster()
	updated, message, err := maven.UpdateParent()
	if err != nil {
		logger.Errorf("parent update failed: %s", err)
		os.Exit(1)
	}

	if updated {
		echo("result: " + message)
		git.OptionalCommit(message, echo)
	} else {
		echo("update not needed: %s ", message)
	}
}

func version() string {
	exec := NewExec(logger, "git")
	output, err := exec.Command("log", "--format=#%h %ai", "-n1").Output()
	exec.DebugStdoutErr(output, err)
	if err != nil {
		logger.Error("have problems determining version")
		panic(err)
	}
	n := len(output)
	return strings.TrimSpace(string(output[:n]))
}

func parseParameter() {
	goopt.Version = version()
	goopt.Summary = "automatic upgrade maven projects, " + goopt.Version
	goopt.Parse(nil)

	if *optVerbose {
		logger = *golog.New(os.Stderr, log.Debug)
		//
		oldFormatter := logger.Formatter
		logger.Formatter = func(buf *bytes.Buffer, level log.Level, args ...interface{}) {
			_, file, line, _ := runtime.Caller(3)
			args[0] = fmt.Sprintf("%s:%d %s", path.Base(file), line, args[0])
			oldFormatter(buf, level, args)

			//_, file2, line2, _ := runtime.Caller(4)
			//args[0] = fmt.Sprintf(" %s:%d -> %s", path.Base(file2), line2, args[0])
			//oldFormatter(buf, level, args)
			//
			//_, file3, line3, _ := runtime.Caller(5)
			//if !strings.Contains(file3, "/runtime/") {
			//	args[0] = fmt.Sprintf("  %s:%d -> %s", path.Base(file3), line3, args[0])
			//	oldFormatter(buf, level, args)
			//}
		}
	} else {
		logger = *golog.New(os.Stderr, log.Warning)
	}
}
<commit_msg>revert version retrival (#15)<commit_after>package main

import (
	"fmt"
	"github.com/alexcesaro/log"
	"github.com/alexcesaro/log/golog"
	"github.com/droundy/goopt"
	. "github.com/lkwg82/automatic-maven-pom-upgrade/lib"
	"os"
	"bytes"
	"runtime"
	"path"
	"strings"
)

var optQuiet = goopt.Flag([]string{"-q", "--quiet"}, nil, "suppress any output", "")
var optVersion = goopt.Flag([]string{"--version"}, nil, "show version", "")
var optType = goopt.Alternatives([]string{"-t", "--type"}, []string{"help", "parent"}, "type of upgrade")
var optVerbose = goopt.Flag([]string{"-v", "--verbose"}, nil, "output verbosely", "")

var logger golog.Logger

type funcErr func() error

func main() {
	git := NewGit(logger)

	maven := NewMaven(logger)

	parseParameter()

	if *optVersion {
		fmt.Printf("version %s\n", goopt.Version)
		os.Exit(0)
	}

	if *optType == "help" {
		fmt.Print(goopt.Usage())
		os.Exit(0)
	}

	exitOnError(git.CheckIsInstalled)
	exitOnError(git.CheckIsRepo)
	exitOnError(git.OptionalCheckIsDirty)

	git.Fetch()

	exitOnError(maven.DetermineCommand)
	exitOnError(maven.ParseCommandline)

	switch *optType {
	case "parent": updateParent(git, maven)
	default:
		panic("should never reach this point, wrong goopt config")
	}
}

func exitOnError(fun funcErr) {
	err := fun()
	if err != nil {
		logger.Emergency(err)
		os.Exit(1)
	}
}

func changeBranch(git *Git) {
	if branch := "autoupdate_" + *optType; git.BranchExists(branch) {
		git.BranchCheckoutExisting(branch)
	} else {
		git.BranchCheckoutNew(branch)
	}
}

func echo(format string, arg ...string) {
	if !*optQuiet {
		if len(arg) == 0 {
			fmt.Println(format)
		} else {
			fmt.Printf(format + "\n", arg)
		}
	}
}

func updateParent(git *Git, maven *Maven) {
	changeBranch(git)
	git.OptionalAutoMergeMaster()
	updated, message, err := maven.UpdateParent()
	if err != nil {
		logger.Errorf("parent update failed: %s", err)
		os.Exit(1)
	}

	if updated {
		echo("result: " + message)
		git.OptionalCommit(message, echo)
	} else {
		echo("update not needed: %s ", message)
	}
}

func version() string {
	exec := NewExec(logger, "git")
	output, err := exec.Command("log", "--format=#%h %ai", "-n1").Output()
	exec.DebugStdoutErr(output, err)
	if err != nil {
		logger.Error("have problems determining version")
		panic(err)
	}
	n := len(output)
	return strings.TrimSpace(string(output[:n]))
}

func parseParameter() {
	goopt.Version = "0.1" //version()
	goopt.Summary = "automatic upgrade maven projects, " + goopt.Version
	goopt.Parse(nil)

	if *optVerbose {
		logger = *golog.New(os.Stderr, log.Debug)
		//
		oldFormatter := logger.Formatter
		logger.Formatter = func(buf *bytes.Buffer, level log.Level, args ...interface{}) {
			_, file, line, _ := runtime.Caller(3)
			args[0] = fmt.Sprintf("%s:%d %s", path.Base(file), line, args[0])
			oldFormatter(buf, level, args)

			//_, file2, line2, _ := runtime.Caller(4)
			//args[0] = fmt.Sprintf(" %s:%d -> %s", path.Base(file2), line2, args[0])
			//oldFormatter(buf, level, args)
			//
			//_, file3, line3, _ := runtime.Caller(5)
			//if !strings.Contains(file3, "/runtime/") {
			//	args[0] = fmt.Sprintf("  %s:%d -> %s", path.Base(file3), line3, args[0])
			//	oldFormatter(buf, level, args)
			//}
		}
	} else {
		logger = *golog.New(os.Stderr, log.Warning)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
)

var turn byte = 'o'
var computer byte = 'o'
var user byte = 'x'

func main() {
	var state = [3][3]byte{}
	fmt.Println(run(state))
}

func run(state [3][3]byte) int {
	if isWinningState(state, 'x') {
		fmt.Print("x wins ")
		fmt.Println(state)
		return 1
	} else if isWinningState(state, 'o') {
		fmt.Print("o wins ")
		fmt.Println(state)
		return -1
	} else {
		fmt.Println(state)
		if turn == computer {
			fs := getFutureStates(state, turn)
			switchTurn()
			for _, s := range fs {
				return run(s)
			}
		} else {
			state = getUserInput(state)
			switchTurn()
			run(state)
		}
	}

	return 0
}

func isWinningState(board [3][3]byte, t byte) bool {
	for i := 0; i < 3; i++ {
		if board[i][0] == t && board[i][1] == t && board[i][2] == t {
			return true
		}

		if board[0][i] == t && board[1][i] == t && board[2][i] == t {
			return true
		}
	}
	if (board[0][0] == t && board[1][1] == t && board[2][2] == t) ||
		(board[0][2] == t && board[1][1] == t && board[2][0] == t) {
		return true
	}

	return false
}

func getFutureStates(state [3][3]byte, turn byte) [9][3][3]byte {
	result := [9][3][3]byte{}
	k := 0

	for i := 0; i < 3; i++ {
		for j := 0; j < 3; j++ {
			if state[i][j] == 0 {
				state[i][j] = turn
				result[k] = state
				k++
				break
			}
		}
	}

	return result
}

func switchTurn() {
	if turn == 'x' {
		turn = 'o'
	} else {
		turn = 'x'
	}
}

func getUserInput(state [3][3]byte) [3][3]byte {
	var i, j int
	fmt.Print("Enter row: ")
	fmt.Scanf("%d", &i)
	fmt.Print("Enter column: ")
	fmt.Scanf("%d", &j)
	state[i][j] = user
	return state
}
<commit_msg>got it working<commit_after>package main

import (
	"fmt"
)

type State [3][3]byte

var computer byte = 'o'
var user byte = 'x'

func main() {
	var state = State{}

	for {
		ch := make(chan State, 9)
		run(state, 0, computer, ch)
		state = <-ch
		printState(state)
		if isWinningState(state, 'o') {
			fmt.Println("Computer Wins!!")
			break
		}

		state = getUserInput(state)
		printState(state)
		if isWinningState(state, 'x') {
			fmt.Println("You Win!!")
			break
		}
	}
}

func run(state State, level int, turn byte, ch chan State) int {
	if isWinningState(state, 'x') {
		return -1
	} else if isWinningState(state, 'o') {
		return 1
	} else {
		fs := getFutureStates(state, turn)
		for _, s := range fs {
			w := run(s, level+1, switchTurn(turn), ch)
			if w == 1 {
				//printState(s)
				if level == 0 {
					ch <- s
				} else {
					return 1
				}
			} else {
				return w
			}
		}
	}
	return 0
}

func isWinningState(state State, t byte) bool {
	for i := 0; i < 3; i++ {
		if state[i][0] == t && state[i][1] == t && state[i][2] == t {
			return true
		}

		if state[0][i] == t && state[1][i] == t && state[2][i] == t {
			return true
		}
	}
	if (state[0][0] == t && state[1][1] == t && state[2][2] == t) ||
		(state[0][2] == t && state[1][1] == t && state[2][0] == t) {
		return true
	}

	return false
}

func getFutureStates(state State, turn byte) []State {
	result := []State{}
	s := state

	for i := 0; i < 3; i++ {
		for j := 0; j < 3; j++ {
			if s[i][j] == 0 {
				s[i][j] = turn
				ts := state
				ts[i][j] = turn
				result = append(result, ts)
			}
		}
	}

	return result
}

func switchTurn(turn byte) byte {
	if turn == 'x' {
		return 'o'
	} else {
		return 'x'
	}
}

func getUserInput(state State) State {
	var i, j int
	fmt.Print("Enter row: ")
	fmt.Scanf("%d", &i)
	fmt.Print("Enter column: ")
	fmt.Scanf("%d", &j)
	state[i][j] = user
	return state
}

func printState(state State) {
	for i := 0; i < 3; i++ {
		for j := 0; j < 3; j++ {
			fmt.Printf("%c\t", state[i][j])
		}
		fmt.Println()
	}
	fmt.Println("==================")
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"log"
	"strings"
	"strconv"
	"math/rand"
	"time"
	"github.com/antonholmquist/jason"
	"github.com/bogdansolomykin/vk_wrapper/vk"
	"github.com/jasonlvhit/gocron"
)

var (
    InfoLogger = log.New(os.Stdout, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
)

func task() {
	InfoLogger.Println("===")

	InfoLogger.Println(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Local())

	var jasonObject *jason.Object
	var jasonValueArray []*jason.Value

	api := vk.Api{
		AccessToken: os.Getenv("VK_AUTH_TOKEN"),
		UserId: "",
		ExpiresIn: "",
	}

	profileUrl := os.Getenv("VK_PROFILE_URL")
	parts := strings.Split(profileUrl, "/")
	userName := parts[len(parts)-1]

	// Получить UID пользователя по nickname
	jasonObject, _ = jason.NewObjectFromBytes([]byte(api.Request(
		"users.get",
		map[string]string{
			"user_ids": userName,
		},
	)))

	jasonValueArray, _ = jasonObject.GetValueArray("response")
	jasonObject, _ = jasonValueArray[0].Object()
	userId, _ := jasonObject.GetInt64("uid")
	userIdString := strconv.FormatInt(userId, 10)

	InfoLogger.Println("userId:", userIdString)

	// Получить общее количество записей на стене
	jasonObject, _ = jason.NewObjectFromBytes([]byte(api.Request(
		"wall.get",
		map[string]string{
			"owner_id": userIdString,
			"count": "1",
		},
	)))

	jasonValueArray, _ = jasonObject.GetValueArray("response")
	numberOfPosts, _ := jasonValueArray[0].Int64()

	InfoLogger.Println("numberOfPosts:", numberOfPosts)

	// Получить случайный пост
	jasonObject, _ = jason.NewObjectFromBytes([]byte(api.Request(
		"wall.get",
		map[string]string{
			"owner_id": userIdString,
			"count": "1",
			"offset": strconv.Itoa(rand.Intn(int(numberOfPosts))),
		},
	)))

	jasonValueArray, _ = jasonObject.GetValueArray("response")
	jasonObject, _ = jasonValueArray[1].Object()
	postId, _ := jasonObject.GetInt64("id")
	postIdString := strconv.FormatInt(postId, 10)

	InfoLogger.Println("postId:", postIdString)

	// Закрепить пост
	api.Request(
		"wall.pin",
		map[string]string{
			"owner_id": userIdString,
			"post_id": postIdString,
		},
	)

	InfoLogger.Print("pinned post: ", profileUrl, "?w=wall", userIdString, "_", postIdString)
	InfoLogger.Println("===")
}

func main() {
	rand.Seed(time.Now().UTC().UnixNano())
	interval := strconv.Atoi(os.Getenv("VK_SCHEDULER_INTERVAL_SECONDS"))
	gocron.Every(interval).Seconds().Do(task)
	<-gocron.Start()
}
<commit_msg>Исправлена ошибка при strconv.Atoi.<commit_after>package main

import (
	"os"
	"log"
	"strings"
	"strconv"
	"math/rand"
	"time"
	"github.com/antonholmquist/jason"
	"github.com/bogdansolomykin/vk_wrapper/vk"
	"github.com/jasonlvhit/gocron"
)

var (
    InfoLogger = log.New(os.Stdout, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
)

func task() {
	InfoLogger.Println("===")

	InfoLogger.Println(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Local())

	var jasonObject *jason.Object
	var jasonValueArray []*jason.Value

	api := vk.Api{
		AccessToken: os.Getenv("VK_AUTH_TOKEN"),
		UserId: "",
		ExpiresIn: "",
	}

	profileUrl := os.Getenv("VK_PROFILE_URL")
	parts := strings.Split(profileUrl, "/")
	userName := parts[len(parts)-1]

	// Получить UID пользователя по nickname
	jasonObject, _ = jason.NewObjectFromBytes([]byte(api.Request(
		"users.get",
		map[string]string{
			"user_ids": userName,
		},
	)))

	jasonValueArray, _ = jasonObject.GetValueArray("response")
	jasonObject, _ = jasonValueArray[0].Object()
	userId, _ := jasonObject.GetInt64("uid")
	userIdString := strconv.FormatInt(userId, 10)

	InfoLogger.Println("userId:", userIdString)

	// Получить общее количество записей на стене
	jasonObject, _ = jason.NewObjectFromBytes([]byte(api.Request(
		"wall.get",
		map[string]string{
			"owner_id": userIdString,
			"count": "1",
		},
	)))

	jasonValueArray, _ = jasonObject.GetValueArray("response")
	numberOfPosts, _ := jasonValueArray[0].Int64()

	InfoLogger.Println("numberOfPosts:", numberOfPosts)

	// Получить случайный пост
	jasonObject, _ = jason.NewObjectFromBytes([]byte(api.Request(
		"wall.get",
		map[string]string{
			"owner_id": userIdString,
			"count": "1",
			"offset": strconv.Itoa(rand.Intn(int(numberOfPosts))),
		},
	)))

	jasonValueArray, _ = jasonObject.GetValueArray("response")
	jasonObject, _ = jasonValueArray[1].Object()
	postId, _ := jasonObject.GetInt64("id")
	postIdString := strconv.FormatInt(postId, 10)

	InfoLogger.Println("postId:", postIdString)

	// Закрепить пост
	api.Request(
		"wall.pin",
		map[string]string{
			"owner_id": userIdString,
			"post_id": postIdString,
		},
	)

	InfoLogger.Print("pinned post: ", profileUrl, "?w=wall", userIdString, "_", postIdString)
	InfoLogger.Println("===")
}

func main() {
	rand.Seed(time.Now().UTC().UnixNano())
	interval, _ := strconv.Atoi(os.Getenv("VK_SCHEDULER_INTERVAL_SECONDS"))
	gocron.Every(interval).Seconds().Do(task)
	<-gocron.Start()
}
<|endoftext|>