<commit_before>package ethui

import (
	"bytes"
	"fmt"
	"github.com/ethereum/eth-go"
	"github.com/ethereum/eth-go/ethchain"
	"github.com/ethereum/eth-go/ethdb"
	"github.com/ethereum/eth-go/ethpub"
	"github.com/ethereum/eth-go/ethutil"
	"github.com/go-qml/qml"
	"github.com/obscuren/mutan"
	"math/big"
	"strings"
)

type Gui struct {
	// The main application window
	win *qml.Window
	// QML Engine
	engine    *qml.Engine
	component *qml.Common
	// The ethereum interface
	eth *eth.Ethereum

	// The public Ethereum library
	lib   *EthLib
	uiLib *UiLib

	txDb *ethdb.LDBDatabase

	addr []byte

	pub *ethpub.PEthereum
}

// Create GUI, but doesn't start it
func New(ethereum *eth.Ethereum) *Gui {
	lib := &EthLib{stateManager: ethereum.StateManager(), blockChain: ethereum.BlockChain(), txPool: ethereum.TxPool()}
	db, err := ethdb.NewLDBDatabase("tx_database")
	if err != nil {
		panic(err)
	}

	// On first run we won't have any keys yet, so this would crash.
	// Therefor we check if we are ready to actually start this process
	var addr []byte
	if ethutil.GetKeyRing().Len() != 0 {
		addr = ethutil.GetKeyRing().Get(0).Address()
	}

	pub := ethpub.NewPEthereum(ethereum)

	return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr, pub: pub}
}

func (gui *Gui) Start(assetPath string) {
	const version = "0.5.0 RC6"

	defer gui.txDb.Close()

	// Register ethereum functions
	qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{
		Init: func(p *ethpub.PBlock, obj qml.Object) { p.Number = 0; p.Hash = "" },
	}, {
		Init: func(p *ethpub.PTx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" },
	}})

	ethutil.Config.SetClientString(fmt.Sprintf("/Ethereal v%s", version))
	ethutil.Config.Log.Infoln("[GUI] Starting GUI")
	// Create a new QML engine
	gui.engine = qml.NewEngine()
	context := gui.engine.Context()

	// Expose the eth library and the ui library to QML
	context.SetVar("eth", gui)
	gui.uiLib = NewUiLib(gui.engine, gui.eth, assetPath)
	context.SetVar("ui", gui.uiLib)

	// Load the main QML interface
	data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))

	var win *qml.Window
	var err error
	if len(data) == 0 {
		win, err = gui.showKeyImport(context)
	} else {
		win, err = gui.showWallet(context)
	}
	if err != nil {
		ethutil.Config.Log.Infoln("FATAL: asset not found: you can set an alternative asset path on on the command line using option 'asset_path'")

		panic(err)
	}

	win.Show()
	win.Wait()

	gui.eth.Stop()
}

func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) {
	component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/wallet.qml"))
	if err != nil {
		return nil, err
	}

	win := gui.createWindow(component)

	go gui.setInitialBlockChain()
	go gui.readPreviousTransactions()
	go gui.update()

	return win, nil
}

func (gui *Gui) showKeyImport(context *qml.Context) (*qml.Window, error) {
	context.SetVar("lib", gui.lib)
	component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/first_run.qml"))
	if err != nil {
		return nil, err
	}

	return gui.createWindow(component), nil
}

func (gui *Gui) createWindow(comp qml.Object) *qml.Window {
	win := comp.CreateWindow(nil)

	gui.win = win
	gui.uiLib.win = win

	db := &Debugger{gui.win, make(chan bool)}
	gui.lib.Db = db
	gui.uiLib.Db = db

	return gui.win
}

func (gui *Gui) setInitialBlockChain() {
	// Load previous 10 blocks
	chain := gui.eth.BlockChain().GetChain(gui.eth.BlockChain().CurrentBlock.Hash(), 10)
	for _, block := range chain {
		gui.processBlock(block)
	}

}

func (gui *Gui) readPreviousTransactions() {
	it := gui.txDb.Db().NewIterator(nil, nil)
	for it.Next() {
		tx := ethchain.NewTransactionFromBytes(it.Value())

		gui.win.Root().Call("addTx", ethpub.NewPTx(tx))
	}
	it.Release()
}

func (gui *Gui) processBlock(block *ethchain.Block) {
	gui.win.Root().Call("addBlock", ethpub.NewPBlock(block))
}

func (gui *Gui) setWalletValue(amount, unconfirmedFunds *big.Int) {
	var str string
	if unconfirmedFunds != nil {
		pos := "+"
		if unconfirmedFunds.Cmp(big.NewInt(0)) >= 0 {
			pos = "-"
		}
		val := ethutil.CurrencyToString(new(big.Int).Abs(ethutil.BigCopy(unconfirmedFunds)))
		str = fmt.Sprintf("%v (%s %v)", ethutil.CurrencyToString(amount), pos, val)
	} else {
		str = fmt.Sprintf("%v", ethutil.CurrencyToString(amount))
	}

	gui.win.Root().Call("setWalletValue", str)
}

// Simple go routine function that updates the list of peers in the GUI
func (gui *Gui) update() {
	reactor := gui.eth.Reactor()

	blockChan := make(chan ethutil.React, 1)
	txChan := make(chan ethutil.React, 1)

	reactor.Subscribe("newBlock", blockChan)
	reactor.Subscribe("newTx:pre", txChan)
	reactor.Subscribe("newTx:post", txChan)

	state := gui.eth.StateManager().TransState()

	unconfirmedFunds := new(big.Int)
	gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.addr).Amount)))

	for {
		select {
		case b := <-blockChan:
			block := b.Resource.(*ethchain.Block)
			if bytes.Compare(block.Coinbase, gui.addr) == 0 {
				gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.addr).Amount, nil)
			}

		case txMsg := <-txChan:
			tx := txMsg.Resource.(*ethchain.Transaction)

			if txMsg.Event == "newTx:pre" {
				object := state.GetAccount(gui.addr)

				if bytes.Compare(tx.Sender(), gui.addr) == 0 && object.Nonce <= tx.Nonce {
					gui.win.Root().Call("addTx", ethpub.NewPTx(tx))
					gui.txDb.Put(tx.Hash(), tx.RlpEncode())

					object.Nonce += 1
					state.SetStateObject(object)

					unconfirmedFunds.Sub(unconfirmedFunds, tx.Value)
				} else if bytes.Compare(tx.Recipient, gui.addr) == 0 {
					gui.win.Root().Call("addTx", ethpub.NewPTx(tx))
					gui.txDb.Put(tx.Hash(), tx.RlpEncode())

					unconfirmedFunds.Add(unconfirmedFunds, tx.Value)
				}

				gui.setWalletValue(object.Amount, unconfirmedFunds)
			} else {
				object := state.GetAccount(gui.addr)
				if bytes.Compare(tx.Sender(), gui.addr) == 0 {
					object.SubAmount(tx.Value)
				} else if bytes.Compare(tx.Recipient, gui.addr) == 0 {
					object.AddAmount(tx.Value)
				}

				gui.setWalletValue(object.Amount, nil)

				state.SetStateObject(object)
			}
		}
	}
}

// Logging functions that log directly to the GUI interface
func (gui *Gui) Println(v ...interface{}) {
	str := strings.TrimRight(fmt.Sprintln(v...), "\n")
	lines := strings.Split(str, "\n")
	for _, line := range lines {
		gui.win.Root().Call("addLog", line)
	}
}

func (gui *Gui) Printf(format string, v ...interface{}) {
	str := strings.TrimRight(fmt.Sprintf(format, v...), "\n")
	lines := strings.Split(str, "\n")
	for _, line := range lines {
		gui.win.Root().Call("addLog", line)
	}
}

func (gui *Gui) Transact(recipient, value, gas, gasPrice, data string) (*ethpub.PReceipt, error) {
	keyPair := ethutil.GetKeyRing().Get(0)

	return gui.pub.Transact(ethutil.Hex(keyPair.PrivateKey), recipient, value, gas, gasPrice, data)
}

func (gui *Gui) Create(recipient, value, gas, gasPrice, data string) (*ethpub.PReceipt, error) {
	keyPair := ethutil.GetKeyRing().Get(0)

	mainInput, initInput := mutan.PreParse(data)

	return gui.pub.Create(ethutil.Hex(keyPair.PrivateKey), value, gas, gasPrice, initInput, mainInput)
}
<commit_msg>Removed nonce incrementing<commit_after>package ethui

import (
	"bytes"
	"fmt"
	"github.com/ethereum/eth-go"
	"github.com/ethereum/eth-go/ethchain"
	"github.com/ethereum/eth-go/ethdb"
	"github.com/ethereum/eth-go/ethpub"
	"github.com/ethereum/eth-go/ethutil"
	"github.com/go-qml/qml"
	"github.com/obscuren/mutan"
	"math/big"
	"strings"
)

type Gui struct {
	// The main application window
	win *qml.Window
	// QML Engine
	engine    *qml.Engine
	component *qml.Common
	// The ethereum interface
	eth *eth.Ethereum

	// The public Ethereum library
	lib   *EthLib
	uiLib *UiLib

	txDb *ethdb.LDBDatabase

	addr []byte

	pub *ethpub.PEthereum
}

// Create GUI, but doesn't start it
func New(ethereum *eth.Ethereum) *Gui {
	lib := &EthLib{stateManager: ethereum.StateManager(), blockChain: ethereum.BlockChain(), txPool: ethereum.TxPool()}
	db, err := ethdb.NewLDBDatabase("tx_database")
	if err != nil {
		panic(err)
	}

	// On first run we won't have any keys yet, so this would crash.
	// Therefor we check if we are ready to actually start this process
	var addr []byte
	if ethutil.GetKeyRing().Len() != 0 {
		addr = ethutil.GetKeyRing().Get(0).Address()
	}

	pub := ethpub.NewPEthereum(ethereum)

	return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr, pub: pub}
}

func (gui *Gui) Start(assetPath string) {
	const version = "0.5.0 RC6"

	defer gui.txDb.Close()

	// Register ethereum functions
	qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{
		Init: func(p *ethpub.PBlock, obj qml.Object) { p.Number = 0; p.Hash = "" },
	}, {
		Init: func(p *ethpub.PTx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" },
	}})

	ethutil.Config.SetClientString(fmt.Sprintf("/Ethereal v%s", version))
	ethutil.Config.Log.Infoln("[GUI] Starting GUI")
	// Create a new QML engine
	gui.engine = qml.NewEngine()
	context := gui.engine.Context()

	// Expose the eth library and the ui library to QML
	context.SetVar("eth", gui)
	gui.uiLib = NewUiLib(gui.engine, gui.eth, assetPath)
	context.SetVar("ui", gui.uiLib)

	// Load the main QML interface
	data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))

	var win *qml.Window
	var err error
	if len(data) == 0 {
		win, err = gui.showKeyImport(context)
	} else {
		win, err = gui.showWallet(context)
	}
	if err != nil {
		ethutil.Config.Log.Infoln("FATAL: asset not found: you can set an alternative asset path on on the command line using option 'asset_path'")

		panic(err)
	}

	win.Show()
	win.Wait()

	gui.eth.Stop()
}

func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) {
	component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/wallet.qml"))
	if err != nil {
		return nil, err
	}

	win := gui.createWindow(component)

	go gui.setInitialBlockChain()
	go gui.readPreviousTransactions()
	go gui.update()

	return win, nil
}

func (gui *Gui) showKeyImport(context *qml.Context) (*qml.Window, error) {
	context.SetVar("lib", gui.lib)
	component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/first_run.qml"))
	if err != nil {
		return nil, err
	}

	return gui.createWindow(component), nil
}

func (gui *Gui) createWindow(comp qml.Object) *qml.Window {
	win := comp.CreateWindow(nil)

	gui.win = win
	gui.uiLib.win = win

	db := &Debugger{gui.win, make(chan bool)}
	gui.lib.Db = db
	gui.uiLib.Db = db

	return gui.win
}

func (gui *Gui) setInitialBlockChain() {
	// Load previous 10 blocks
	chain := gui.eth.BlockChain().GetChain(gui.eth.BlockChain().CurrentBlock.Hash(), 10)
	for _, block := range chain {
		gui.processBlock(block)
	}

}

func (gui *Gui) readPreviousTransactions() {
	it := gui.txDb.Db().NewIterator(nil, nil)
	for it.Next() {
		tx := ethchain.NewTransactionFromBytes(it.Value())

		gui.win.Root().Call("addTx", ethpub.NewPTx(tx))
	}
	it.Release()
}

func (gui *Gui) processBlock(block *ethchain.Block) {
	gui.win.Root().Call("addBlock", ethpub.NewPBlock(block))
}

func (gui *Gui) setWalletValue(amount, unconfirmedFunds *big.Int) {
	var str string
	if unconfirmedFunds != nil {
		pos := "+"
		if unconfirmedFunds.Cmp(big.NewInt(0)) >= 0 {
			pos = "-"
		}
		val := ethutil.CurrencyToString(new(big.Int).Abs(ethutil.BigCopy(unconfirmedFunds)))
		str = fmt.Sprintf("%v (%s %v)", ethutil.CurrencyToString(amount), pos, val)
	} else {
		str = fmt.Sprintf("%v", ethutil.CurrencyToString(amount))
	}

	gui.win.Root().Call("setWalletValue", str)
}

// Simple go routine function that updates the list of peers in the GUI
func (gui *Gui) update() {
	reactor := gui.eth.Reactor()

	blockChan := make(chan ethutil.React, 1)
	txChan := make(chan ethutil.React, 1)

	reactor.Subscribe("newBlock", blockChan)
	reactor.Subscribe("newTx:pre", txChan)
	reactor.Subscribe("newTx:post", txChan)

	state := gui.eth.StateManager().TransState()

	unconfirmedFunds := new(big.Int)
	gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.addr).Amount)))

	for {
		select {
		case b := <-blockChan:
			block := b.Resource.(*ethchain.Block)
			if bytes.Compare(block.Coinbase, gui.addr) == 0 {
				gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.addr).Amount, nil)
			}

		case txMsg := <-txChan:
			tx := txMsg.Resource.(*ethchain.Transaction)

			if txMsg.Event == "newTx:pre" {
				object := state.GetAccount(gui.addr)

				if bytes.Compare(tx.Sender(), gui.addr) == 0 && object.Nonce <= tx.Nonce {
					gui.win.Root().Call("addTx", ethpub.NewPTx(tx))
					gui.txDb.Put(tx.Hash(), tx.RlpEncode())

					/*
						object.Nonce += 1
						state.SetStateObject(object)
					*/

					unconfirmedFunds.Sub(unconfirmedFunds, tx.Value)
				} else if bytes.Compare(tx.Recipient, gui.addr) == 0 {
					gui.win.Root().Call("addTx", ethpub.NewPTx(tx))
					gui.txDb.Put(tx.Hash(), tx.RlpEncode())

					unconfirmedFunds.Add(unconfirmedFunds, tx.Value)
				}

				gui.setWalletValue(object.Amount, unconfirmedFunds)
			} else {
				object := state.GetAccount(gui.addr)
				if bytes.Compare(tx.Sender(), gui.addr) == 0 {
					object.SubAmount(tx.Value)
				} else if bytes.Compare(tx.Recipient, gui.addr) == 0 {
					object.AddAmount(tx.Value)
				}

				gui.setWalletValue(object.Amount, nil)

				state.SetStateObject(object)
			}
		}
	}
}

// Logging functions that log directly to the GUI interface
func (gui *Gui) Println(v ...interface{}) {
	str := strings.TrimRight(fmt.Sprintln(v...), "\n")
	lines := strings.Split(str, "\n")
	for _, line := range lines {
		gui.win.Root().Call("addLog", line)
	}
}

func (gui *Gui) Printf(format string, v ...interface{}) {
	str := strings.TrimRight(fmt.Sprintf(format, v...), "\n")
	lines := strings.Split(str, "\n")
	for _, line := range lines {
		gui.win.Root().Call("addLog", line)
	}
}

func (gui *Gui) Transact(recipient, value, gas, gasPrice, data string) (*ethpub.PReceipt, error) {
	keyPair := ethutil.GetKeyRing().Get(0)

	return gui.pub.Transact(ethutil.Hex(keyPair.PrivateKey), recipient, value, gas, gasPrice, data)
}

func (gui *Gui) Create(recipient, value, gas, gasPrice, data string) (*ethpub.PReceipt, error) {
	keyPair := ethutil.GetKeyRing().Get(0)

	mainInput, initInput := mutan.PreParse(data)

	return gui.pub.Create(ethutil.Hex(keyPair.PrivateKey), value, gas, gasPrice, initInput, mainInput)
}
<|endoftext|>


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

package main

import (
	"code.google.com/p/gordon-go/go/types"
	. "code.google.com/p/gordon-go/gui"
	"fmt"
)

type funcNode struct {
	*ViewBase
	AggregateMouser
	blk                     *block
	output                  *port
	funcblk                 *block
	inputsNode, outputsNode *portsNode
	focused                 bool

	obj     types.Object
	literal bool
	pkgRefs map[*types.Package]int
	done    func()

	animate blockchan
	stop    stopchan
}

func newFuncNode(obj types.Object, arranged blockchan) *funcNode {
	n := &funcNode{obj: obj, literal: obj == nil}
	n.ViewBase = NewView(n)
	n.AggregateMouser = AggregateMouser{NewClickFocuser(n), NewMover(n)}
	if n.literal {
		n.output = newOutput(n, newVar("", &types.Signature{}))
		MoveCenter(n.output, Pt(0, -portSize))
		n.Add(n.output)
	} else {
		n.pkgRefs = map[*types.Package]int{}
		n.animate = make(blockchan)
		n.stop = make(stopchan)
		arranged = n.animate
	}
	n.funcblk = newBlock(n, arranged)
	n.inputsNode = newInputsNode()
	n.inputsNode.editable = true
	n.funcblk.addNode(n.inputsNode)
	n.outputsNode = newOutputsNode()
	n.outputsNode.editable = true
	n.funcblk.addNode(n.outputsNode)
	return n
}

func (n *funcNode) Close() {
	if !n.literal {
		saveFunc(n)
		n.funcblk.close()
		n.stop.stop()
		n.done()
	}
	n.ViewBase.Close()
}

func (n *funcNode) sig() *types.Signature {
	obj := n.obj
	if obj == nil {
		obj = n.output.obj
	}
	return obj.GetType().(*types.Signature)
}

func (n funcNode) pkg() *types.Package {
	return n.obj.GetPkg()
}

func (n funcNode) imports() (x []*types.Package) {
	for p := range n.pkgRefs {
		x = append(x, p)
	}
	return
}

func (n *funcNode) addPkgRef(x interface{}) {
	switch x := x.(type) {
	case types.Object:
		if p := x.GetPkg(); p != n.pkg() && p != nil {
			n.pkgRefs[p]++
		}
	case types.Type:
		walkType(x, func(t *types.Named) { n.addPkgRef(t.Obj) })
	default:
		panic(fmt.Sprintf("can't addPkgRef for %#v\n", x))
	}
}
func (n *funcNode) subPkgRef(x interface{}) {
	switch x := x.(type) {
	case types.Object:
		p := x.GetPkg()
		n.pkgRefs[p]--
		if n.pkgRefs[p] <= 0 {
			delete(n.pkgRefs, p)
		}
	case types.Type:
		walkType(x, func(t *types.Named) { n.subPkgRef(t.Obj) })
	default:
		panic(fmt.Sprintf("can't subPkgRef for %#v\n", x))
	}
}

func (n funcNode) block() *block      { return n.blk }
func (n *funcNode) setBlock(b *block) { n.blk = b }
func (n funcNode) inputs() []*port    { return nil }
func (n funcNode) outputs() (p []*port) {
	if n.output != nil {
		p = append(p, n.output)
	}
	return
}
func (n funcNode) inConns() []*connection { return n.funcblk.inConns() }
func (n funcNode) outConns() []*connection {
	c := n.funcblk.outConns()
	if n.output != nil {
		c = append(c, n.output.conns...)
	}
	return c
}

func (n *funcNode) Move(p Point) {
	n.ViewBase.Move(p)
	nodeMoved(n)
}

func (n *funcNode) focusFrom(v View, pass bool) {
	if !pass {
		SetKeyFocus(n)
		return
	}

	switch v {
	case n.outputsNode:
		n.output.focusMiddle()
	case n.output:
		out := n.outputsNode
		if len(out.ins) > 0 {
			out.ins[(len(out.ins)-1)/2].focusMiddle()
		} else {
			SetKeyFocus(out)
		}
	}
}

func (n *funcNode) TookKeyFocus() {
	n.focused = true
	Repaint(n)
	panTo(n, ZP)
}

func (n *funcNode) LostKeyFocus() {
	n.focused = false
	Repaint(n)
}

func (n *funcNode) KeyPress(event KeyEvent) {
	if event.Command && event.Key == KeyS && !n.literal {
		saveFunc(n)
	} else if event.Key == KeyUp && n.literal {
		if out := n.outputsNode; len(out.ins) > 0 {
			out.ins[(len(out.ins)-1)/2].focusMiddle()
		} else {
			SetKeyFocus(out)
		}
	} else {
		n.ViewBase.KeyPress(event)
	}
}

func (n funcNode) Paint() {
	if n.literal {
		SetColor(lineColor)
		DrawLine(Pt(0, portSize/2), Pt(0, -portSize))
		if n.focused {
			SetPointSize(2 * portSize)
			SetColor(focusColor)
			DrawPoint(ZP)
		}
	}
}
<commit_msg>Flux:  Don't focus outermost funcNode.<commit_after>// Copyright 2014 Gordon Klaus. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"code.google.com/p/gordon-go/go/types"
	. "code.google.com/p/gordon-go/gui"
	"fmt"
)

type funcNode struct {
	*ViewBase
	AggregateMouser
	blk                     *block
	output                  *port
	funcblk                 *block
	inputsNode, outputsNode *portsNode
	focused                 bool

	obj     types.Object
	literal bool
	pkgRefs map[*types.Package]int
	done    func()

	animate blockchan
	stop    stopchan
}

func newFuncNode(obj types.Object, arranged blockchan) *funcNode {
	n := &funcNode{obj: obj, literal: obj == nil}
	n.ViewBase = NewView(n)
	n.AggregateMouser = AggregateMouser{NewClickFocuser(n), NewMover(n)}
	if n.literal {
		n.output = newOutput(n, newVar("", &types.Signature{}))
		MoveCenter(n.output, Pt(0, -portSize))
		n.Add(n.output)
	} else {
		n.pkgRefs = map[*types.Package]int{}
		n.animate = make(blockchan)
		n.stop = make(stopchan)
		arranged = n.animate
	}
	n.funcblk = newBlock(n, arranged)
	n.inputsNode = newInputsNode()
	n.inputsNode.editable = true
	n.funcblk.addNode(n.inputsNode)
	n.outputsNode = newOutputsNode()
	n.outputsNode.editable = true
	n.funcblk.addNode(n.outputsNode)
	return n
}

func (n *funcNode) Close() {
	if !n.literal {
		saveFunc(n)
		n.funcblk.close()
		n.stop.stop()
		n.done()
	}
	n.ViewBase.Close()
}

func (n *funcNode) sig() *types.Signature {
	obj := n.obj
	if obj == nil {
		obj = n.output.obj
	}
	return obj.GetType().(*types.Signature)
}

func (n funcNode) pkg() *types.Package {
	return n.obj.GetPkg()
}

func (n funcNode) imports() (x []*types.Package) {
	for p := range n.pkgRefs {
		x = append(x, p)
	}
	return
}

func (n *funcNode) addPkgRef(x interface{}) {
	switch x := x.(type) {
	case types.Object:
		if p := x.GetPkg(); p != n.pkg() && p != nil {
			n.pkgRefs[p]++
		}
	case types.Type:
		walkType(x, func(t *types.Named) { n.addPkgRef(t.Obj) })
	default:
		panic(fmt.Sprintf("can't addPkgRef for %#v\n", x))
	}
}
func (n *funcNode) subPkgRef(x interface{}) {
	switch x := x.(type) {
	case types.Object:
		p := x.GetPkg()
		n.pkgRefs[p]--
		if n.pkgRefs[p] <= 0 {
			delete(n.pkgRefs, p)
		}
	case types.Type:
		walkType(x, func(t *types.Named) { n.subPkgRef(t.Obj) })
	default:
		panic(fmt.Sprintf("can't subPkgRef for %#v\n", x))
	}
}

func (n funcNode) block() *block      { return n.blk }
func (n *funcNode) setBlock(b *block) { n.blk = b }
func (n funcNode) inputs() []*port    { return nil }
func (n funcNode) outputs() (p []*port) {
	if n.output != nil {
		p = append(p, n.output)
	}
	return
}
func (n funcNode) inConns() []*connection { return n.funcblk.inConns() }
func (n funcNode) outConns() []*connection {
	c := n.funcblk.outConns()
	if n.output != nil {
		c = append(c, n.output.conns...)
	}
	return c
}

func (n *funcNode) Move(p Point) {
	n.ViewBase.Move(p)
	nodeMoved(n)
}

func (n *funcNode) focusFrom(v View, pass bool) {
	if !n.literal {
		return
	}

	if !pass {
		SetKeyFocus(n)
		return
	}

	switch v {
	case n.outputsNode:
		n.output.focusMiddle()
	case n.output:
		out := n.outputsNode
		if len(out.ins) > 0 {
			out.ins[(len(out.ins)-1)/2].focusMiddle()
		} else {
			SetKeyFocus(out)
		}
	}
}

func (n *funcNode) TookKeyFocus() {
	n.focused = true
	Repaint(n)
	panTo(n, ZP)
}

func (n *funcNode) LostKeyFocus() {
	n.focused = false
	Repaint(n)
}

func (n *funcNode) KeyPress(event KeyEvent) {
	if event.Command && event.Key == KeyS && !n.literal {
		saveFunc(n)
	} else if event.Key == KeyUp && n.literal {
		if out := n.outputsNode; len(out.ins) > 0 {
			out.ins[(len(out.ins)-1)/2].focusMiddle()
		} else {
			SetKeyFocus(out)
		}
	} else {
		n.ViewBase.KeyPress(event)
	}
}

func (n funcNode) Paint() {
	if n.literal {
		SetColor(lineColor)
		DrawLine(Pt(0, portSize/2), Pt(0, -portSize))
		if n.focused {
			SetPointSize(2 * portSize)
			SetColor(focusColor)
			DrawPoint(ZP)
		}
	}
}
<|endoftext|>


<commit_before>package version

const (
	version = "0.1"
)

var gitVersion string

func GetVersion() string {
	return version + "-" + gitVersion
}
<commit_msg>Version 0.1.1 is coming earlier than expected<commit_after>package version

const (
	version = "0.1.1"
)

var gitVersion string

func GetVersion() string {
	return version + "-" + gitVersion
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"

	"github.com/constabulary/gb"
	"github.com/constabulary/gb/cmd"
	"github.com/constabulary/gb/cmd/gb/internal/match"
	"github.com/constabulary/gb/internal/debug"
)

var (
	fs  = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
	cwd string
)

const (
	// disable to keep working directory
	destroyContext = true
)

func init() {
	fs.StringVar(&cwd, "R", cmd.MustGetwd(), "set the project root") // actually the working directory to start the project root search
	fs.Usage = usage
}

var commands = make(map[string]*cmd.Command)

// registerCommand registers a command for main.
// registerCommand should only be called from init().
func registerCommand(command *cmd.Command) {
	setCommandDefaults(command)
	commands[command.Name] = command
}

// atExit functions are called in sequence at the exit of the program.
var atExit []func() error

// exit runs all atExit functions, then calls os.Exit(code).
func exit(code int) {
	for _, fn := range atExit {
		if err := fn(); err != nil {
			fmt.Fprintln(os.Stderr, "atExit:", err)
		}
	}
	os.Exit(code)
}

func fatalf(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "FATAL: "+format+"\n", args...)
	exit(1)
}

func main() {
	args := os.Args
	if len(args) < 2 || args[1] == "-h" {
		fs.Usage() // usage calles exit(2)
	}
	name := args[1]
	if name == "help" {
		help(args[2:])
		exit(0)
	}

	command := lookupCommand(name)

	// add extra flags if necessary
	command.AddFlags(fs)

	// parse 'em
	err := command.FlagParse(fs, args)
	if err != nil {
		fatalf("could not parse flags: %v", err)
	}

	// reset args to the leftovers from fs.Parse
	args = fs.Args()

	// if this is the plugin command, ensure the name of the
	// plugin is first in the list of arguments.
	if command == commands["plugin"] {
		args = append([]string{name}, args...)
	}

	// if cwd was passed in via -R, make sure it is absolute
	cwd, err := filepath.Abs(cwd)
	if err != nil {
		fatalf("could not make project root absolute: %v", err)
	}

	// construct a project context at the current working directory.
	ctx, err := newContext(cwd)
	if err != nil {
		fatalf("unable to construct context: %v", err)
	}

	// unless the command wants to handle its own arguments, process
	// arguments into import paths.
	if !command.SkipParseArgs {
		srcdir := filepath.Join(ctx.Projectdir(), "src")
		for _, a := range args {
			// support the "all" build alias. This used to be handled
			// in match.ImportPaths, but that's too messy, so if "all"
			// is present in the args, replace it with "..." and set cwd
			// to srcdir.
			if a == "all" {
				args = []string{"..."}
				cwd = srcdir
				break
			}
		}
		args = match.ImportPaths(srcdir, cwd, args)
	}

	debug.Debugf("args: %v", args)

	if destroyContext {
		atExit = append(atExit, ctx.Destroy)
	}

	if err := command.Run(ctx, args); err != nil {
		fatalf("command %q failed: %v", name, err)
	}
	exit(0)
}

func lookupCommand(name string) *cmd.Command {
	command, ok := commands[name]
	if (command != nil && !command.Runnable()) || !ok {
		plugin, err := lookupPlugin(name)
		if err != nil {
			fmt.Fprintf(os.Stderr, "FATAL: unknown command %q\n", name)
			fs.Usage() // usage calles exit(2)
		}
		command = &cmd.Command{
			Run: func(ctx *gb.Context, args []string) error {
				args = append([]string{plugin}, args...)

				env := cmd.MergeEnv(os.Environ(), map[string]string{
					"GB_PROJECT_DIR": ctx.Projectdir(),
				})

				cmd := exec.Cmd{
					Path: plugin,
					Args: args,
					Env:  env,

					Stdin:  os.Stdin,
					Stdout: os.Stdout,
					Stderr: os.Stderr,
				}

				return cmd.Run()
			},
			// plugin should not interpret arguments
			SkipParseArgs: true,
		}
	}
	setCommandDefaults(command)
	return command
}

func setCommandDefaults(command *cmd.Command) {

	// add a dummy default AddFlags field if none provided.
	if command.AddFlags == nil {
		command.AddFlags = func(*flag.FlagSet) {}
	}

	// add the default flag parsing if not overrriden.
	if command.FlagParse == nil {
		command.FlagParse = func(fs *flag.FlagSet, args []string) error {
			return fs.Parse(args[2:])
		}
	}
}

func newContext(cwd string) (*gb.Context, error) {
	return cmd.NewContext(
		cwd, // project root
		gb.GcToolchain(),
		gb.Gcflags(gcflags...),
		gb.Ldflags(ldflags...),
		gb.Tags(buildtags...),
		func(c *gb.Context) error {
			if !race {
				return nil
			}

			// check this is a supported platform
			if runtime.GOARCH != "amd64" {
				fatalf("race detector not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
			}
			switch runtime.GOOS {
			case "linux", "windows", "darwin", "freebsd":
				// supported
			default:
				fatalf("race detector not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
			}

			// check the race runtime is built
			_, err := os.Stat(filepath.Join(runtime.GOROOT(), "pkg", fmt.Sprintf("%s_%s_race", runtime.GOOS, runtime.GOARCH), "runtime.a"))
			if os.IsNotExist(err) || err != nil {
				fatalf("go installation at %s is missing race support. See https://getgb.io/faq/#missing-race-support", runtime.GOROOT())
			}

			return gb.WithRace(c)
		},
	)
}
<commit_msg>Remove a bunch of package level variables (#719)<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"

	"github.com/constabulary/gb"
	"github.com/constabulary/gb/cmd"
	"github.com/constabulary/gb/cmd/gb/internal/match"
	"github.com/constabulary/gb/internal/debug"
)

// disable to keep working directory
const destroyContext = true

var commands = make(map[string]*cmd.Command)

// registerCommand registers a command for main.
// registerCommand should only be called from init().
func registerCommand(command *cmd.Command) {
	setCommandDefaults(command)
	commands[command.Name] = command
}

// atExit functions are called in sequence at the exit of the program.
var atExit []func() error

// exit runs all atExit functions, then calls os.Exit(code).
func exit(code int) {
	for _, fn := range atExit {
		if err := fn(); err != nil {
			fmt.Fprintln(os.Stderr, "atExit:", err)
		}
	}
	os.Exit(code)
}

func fatalf(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "FATAL: "+format+"\n", args...)
	exit(1)
}

func main() {
	fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
	var cwd string
	fs.StringVar(&cwd, "R", cmd.MustGetwd(), "set the project root") // actually the working directory to start the project root search
	fs.Usage = usage

	args := os.Args
	if len(args) < 2 || args[1] == "-h" {
		fs.Usage() // usage calls exit(2)
	}

	name := args[1]
	if name == "help" {
		help(args[2:])
		exit(0)
	}

	command := lookupCommand(name)

	// add extra flags if necessary
	command.AddFlags(fs)

	// parse 'em
	if err := command.FlagParse(fs, args); err != nil {
		fatalf("could not parse flags: %v", err)
	}

	// reset args to the leftovers from fs.Parse
	args = fs.Args()

	// if this is the plugin command, ensure the name of the
	// plugin is first in the list of arguments.
	if command == commands["plugin"] {
		args = append([]string{name}, args...)
	}

	// if cwd was passed in via -R, make sure it is absolute
	cwd, err := filepath.Abs(cwd)
	if err != nil {
		fatalf("could not make project root absolute: %v", err)
	}

	// construct a project context at the current working directory.
	ctx, err := newContext(cwd)
	if err != nil {
		fatalf("unable to construct context: %v", err)
	}

	// unless the command wants to handle its own arguments, process
	// arguments into import paths.
	if !command.SkipParseArgs {
		srcdir := filepath.Join(ctx.Projectdir(), "src")
		for _, a := range args {
			// support the "all" build alias. This used to be handled
			// in match.ImportPaths, but that's too messy, so if "all"
			// is present in the args, replace it with "..." and set cwd
			// to srcdir.
			if a == "all" {
				args = []string{"..."}
				cwd = srcdir
				break
			}
		}
		args = match.ImportPaths(srcdir, cwd, args)
	}

	debug.Debugf("args: %v", args)

	if destroyContext {
		atExit = append(atExit, ctx.Destroy)
	}

	if err := command.Run(ctx, args); err != nil {
		fatalf("command %q failed: %v", name, err)
	}
	exit(0)
}

func lookupCommand(name string) *cmd.Command {
	command, ok := commands[name]
	if (command != nil && !command.Runnable()) || !ok {
		plugin, err := lookupPlugin(name)
		if err != nil {
			fmt.Fprintf(os.Stderr, "FATAL: unknown command %q\n", name)
			usage()
		}
		command = &cmd.Command{
			Run: func(ctx *gb.Context, args []string) error {
				args = append([]string{plugin}, args...)

				env := cmd.MergeEnv(os.Environ(), map[string]string{
					"GB_PROJECT_DIR": ctx.Projectdir(),
				})

				cmd := exec.Cmd{
					Path: plugin,
					Args: args,
					Env:  env,

					Stdin:  os.Stdin,
					Stdout: os.Stdout,
					Stderr: os.Stderr,
				}

				return cmd.Run()
			},
			// plugin should not interpret arguments
			SkipParseArgs: true,
		}
	}
	setCommandDefaults(command)
	return command
}

func setCommandDefaults(command *cmd.Command) {

	// add a dummy default AddFlags field if none provided.
	if command.AddFlags == nil {
		command.AddFlags = func(*flag.FlagSet) {}
	}

	// add the default flag parsing if not overrriden.
	if command.FlagParse == nil {
		command.FlagParse = func(fs *flag.FlagSet, args []string) error {
			return fs.Parse(args[2:])
		}
	}
}

func newContext(cwd string) (*gb.Context, error) {
	return cmd.NewContext(
		cwd, // project root
		gb.GcToolchain(),
		gb.Gcflags(gcflags...),
		gb.Ldflags(ldflags...),
		gb.Tags(buildtags...),
		func(c *gb.Context) error {
			if !race {
				return nil
			}

			// check this is a supported platform
			if runtime.GOARCH != "amd64" {
				fatalf("race detector not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
			}
			switch runtime.GOOS {
			case "linux", "windows", "darwin", "freebsd":
				// supported
			default:
				fatalf("race detector not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
			}

			// check the race runtime is built
			_, err := os.Stat(filepath.Join(runtime.GOROOT(), "pkg", fmt.Sprintf("%s_%s_race", runtime.GOOS, runtime.GOARCH), "runtime.a"))
			if os.IsNotExist(err) || err != nil {
				fatalf("go installation at %s is missing race support. See https://getgb.io/faq/#missing-race-support", runtime.GOROOT())
			}

			return gb.WithRace(c)
		},
	)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"runtime"
	"strings"
	"time"

	flags "github.com/jessevdk/go-flags"
	"github.com/monochromegane/terminal"
	pt "github.com/monochromegane/the_platinum_searcher"
)

const version = "1.7.2"

var opts pt.Option

func init() {
	if cpu := runtime.NumCPU(); cpu == 1 {
		runtime.GOMAXPROCS(2)
	} else {
		runtime.GOMAXPROCS(cpu)
	}
}

func main() {
	opts.Color = opts.SetEnableColor
	opts.NoColor = opts.SetDisableColor
	opts.EnableColor = true
	opts.SkipVcsIgnore = opts.SkipVcsIgnores

	parser := flags.NewParser(&opts, flags.Default)
	parser.Name = "pt"
	parser.Usage = "[OPTIONS] PATTERN [PATH]"

	args, err := parser.Parse()
	if err != nil {
		os.Exit(1)
	}

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

	if len(args) == 0 && opts.FilesWithRegexp == "" {
		parser.WriteHelp(os.Stdout)
		os.Exit(1)
	}

	opts.SearchStream = false
	if len(args) == 1 {
		if !terminal.IsTerminal(os.Stdin) {
			opts.SearchStream = true
			opts.NoGroup = true
		}
	}

	var root = "."
	if len(args) == 2 {
		root = strings.TrimRight(args[1], "\"")
		_, err := os.Lstat(root)
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s\n", err)
			os.Exit(1)
		}
	}

	opts.Proc = runtime.NumCPU()

	if !terminal.IsTerminal(os.Stdout) {
		if !opts.ForceColor {
			opts.EnableColor = false
		}
		opts.NoGroup = true
	}

	if opts.Context > 0 {
		opts.Before = opts.Context
		opts.After = opts.Context
	}

	pattern := ""
	if len(args) > 0 {
		pattern = args[0]
	}

	if opts.WordRegexp {
		opts.Regexp = true
		pattern = "\\b" + pattern + "\\b"
	}

	start := time.Now()

	searcher := pt.PlatinumSearcher{root, pattern, &opts}
	err = searcher.Search()
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err)
		os.Exit(1)
	}
	if opts.Stats {
		elapsed := time.Since(start)
		fmt.Printf("%d Files Searched\n", pt.FilesSearched)
		fmt.Printf("%s Elapsed\n", elapsed)
	}

	if pt.FileMatchCount == 0 {
		os.Exit(1)
	}
}
<commit_msg>Bumped version to 1.7.3.<commit_after>package main

import (
	"fmt"
	"os"
	"runtime"
	"strings"
	"time"

	flags "github.com/jessevdk/go-flags"
	"github.com/monochromegane/terminal"
	pt "github.com/monochromegane/the_platinum_searcher"
)

const version = "1.7.3"

var opts pt.Option

func init() {
	if cpu := runtime.NumCPU(); cpu == 1 {
		runtime.GOMAXPROCS(2)
	} else {
		runtime.GOMAXPROCS(cpu)
	}
}

func main() {
	opts.Color = opts.SetEnableColor
	opts.NoColor = opts.SetDisableColor
	opts.EnableColor = true
	opts.SkipVcsIgnore = opts.SkipVcsIgnores

	parser := flags.NewParser(&opts, flags.Default)
	parser.Name = "pt"
	parser.Usage = "[OPTIONS] PATTERN [PATH]"

	args, err := parser.Parse()
	if err != nil {
		os.Exit(1)
	}

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

	if len(args) == 0 && opts.FilesWithRegexp == "" {
		parser.WriteHelp(os.Stdout)
		os.Exit(1)
	}

	opts.SearchStream = false
	if len(args) == 1 {
		if !terminal.IsTerminal(os.Stdin) {
			opts.SearchStream = true
			opts.NoGroup = true
		}
	}

	var root = "."
	if len(args) == 2 {
		root = strings.TrimRight(args[1], "\"")
		_, err := os.Lstat(root)
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s\n", err)
			os.Exit(1)
		}
	}

	opts.Proc = runtime.NumCPU()

	if !terminal.IsTerminal(os.Stdout) {
		if !opts.ForceColor {
			opts.EnableColor = false
		}
		opts.NoGroup = true
	}

	if opts.Context > 0 {
		opts.Before = opts.Context
		opts.After = opts.Context
	}

	pattern := ""
	if len(args) > 0 {
		pattern = args[0]
	}

	if opts.WordRegexp {
		opts.Regexp = true
		pattern = "\\b" + pattern + "\\b"
	}

	start := time.Now()

	searcher := pt.PlatinumSearcher{root, pattern, &opts}
	err = searcher.Search()
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err)
		os.Exit(1)
	}
	if opts.Stats {
		elapsed := time.Since(start)
		fmt.Printf("%d Files Searched\n", pt.FilesSearched)
		fmt.Printf("%s Elapsed\n", elapsed)
	}

	if pt.FileMatchCount == 0 {
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>// tb is my toolbox.
//
// This is an attempt to keep scattered dotfiles and scripts in one place.
package main

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"os/user"
	"regexp"
	"strings"
	"time"

	"github.com/serge-v/toolbox/acomplete"
)

var (
	version string
	date    string
	u       *user.User
)

var (
	newFeature      = flag.Bool("n", false, "for testing new features")
	autocomplete    = flag.Bool("c", false, "for bash autocomplete")
	rebuild         = flag.Bool("rebuild", false, "rebuild tb")
	showVer         = flag.Bool("version", false, "show version")
	showColors      = flag.Bool("colors-true", false, "show terminal true colors")
	showColorsTable = flag.Bool("colors-table", false, "print true colors table")
	regenXresources = flag.Bool("regen-xresources", false, "regenerate local .Xresources")
	startGodoc      = flag.Bool("start-godoc", false, "start go doc ~/go on :6001")
	setEnv          = flag.Bool("setenv", false, "setenv test")
	getTOC          = flag.String("toc", "", "generate TOC from MD file")
	dedupPath       = flag.String("dedup-path", "", "deduplicate colon separated paths list")
	rename          = flag.String("rename", "", "rename files. For help use -rename help")
	yes             = flag.Bool("y", false, "confirm rename")
	fontview        = flag.Bool("fontview", false, "start font viewer in browser")
)

func init() {
	var err error
	u, err = user.Current()
	if err != nil {
		panic(err)
	}
}

func printVersion() {
	fmt.Println("tb is my toolbox. Serge Voilokov (C) 2017.")
	fmt.Println("version:", version)
	fmt.Println("date:   ", date)
}

func rebuildToolbox() {
	gopath := u.HomeDir + "/go"
	tbpath := gopath + "/src/github.com/serge-v/toolbox"

	cmd := exec.Command("git", "describe", "--tags")
	cmd.Dir = tbpath
	out, err := cmd.CombinedOutput()
	if err != nil {
		println("error: git: ", string(out))
		return
	}
	ver := strings.TrimSpace(string(out))

	cmd = exec.Command("touch", "main.go")
	cmd.Dir = tbpath + "/cmd/tb"
	out, err = cmd.CombinedOutput()
	if err != nil {
		println("error: touch: ", string(out))
		return
	}

	args := []string{
		"install",
		"-ldflags",
		"-X main.date=" + time.Now().Format(time.RFC3339) + " -X main.version=" + ver,
		"github.com/serge-v/toolbox/..."}

	cmd = exec.Command("go", args...)
	cmd.Env = os.Environ()
	cmd.Env = append(cmd.Env, "GOPATH="+gopath)
	out, err = cmd.CombinedOutput()
	if err != nil {
		println("error: go: ", string(out))
		return
	}

	cmd = exec.Command("tb", "-version")
	out, err = cmd.CombinedOutput()
	if err != nil {
		println("error: tb -version: ", string(out))
		return
	}

	fmt.Print(string(out))
}

func startGodocServer() {
	gopath := u.HomeDir + "/go"
	cmd := exec.Command("sh", "-c", "godoc -http=:6060 2>/tmp/godoc.log 2>&1 &")
	cmd.Dir = gopath
	err := cmd.Start()
	if err != nil {
		println("error: go doc: ", err)
		return
	}
	fmt.Println("godoc:", "http://localhost:6060/pkg")
}

func setTestEnv() {
	os.Setenv("TESTVAR", "testvalue")
	for _, e := range os.Environ() {
		fmt.Println(e)
	}
}

func runcmd(cmdline string) {
	cmd := exec.Command("sh", "-c", cmdline)
	out, err := cmd.CombinedOutput()
	if err != nil {
		println("error:", cmdline, ":", string(out))
		return
	}
	fmt.Println(string(out))
}

func generateTOC(fname string) {
	runcmd(`grep -e "====" -B 1 "` + fname + `" | grep -v -e "===" -e "--"`)
}

func deduplicatePath(path string) {
	arr := strings.Split(path, ":")
	newarr := make([]string, 0, 10)
	chunks := make(map[string]bool, 20)
	for _, a := range arr {
		if _, ok := chunks[a]; ok {
			continue
		}
		newarr = append(newarr, a)
		chunks[a] = true
	}
	fmt.Println(strings.Join(newarr, ":"))
}

func visitFlags() {
	visitFunc := func(f *flag.Flag) {
		switch t := f.Value.(type) {
		default:
			fmt.Printf("%+v: %T\n", f.Name, t)
		}
	}
	flag.VisitAll(visitFunc)
}

var renameUsage = `tb -rename -- renames files in the current directory.
Usage:
  tb -rename /REGEX/REPL/  -- preview rename
  tb -rename /REGEX/REPL/ -y -- do rename`

func renameFiles() {
	if *rename == "help" {
		fmt.Println(renameUsage)
		return
	}

	p := strings.Split(*rename, "/")
	if len(p) != 4 {
		panic("invalid rename rule")
	}

	rex, err := regexp.Compile(p[1])
	if err != err {
		panic(err)
	}

	repl := p[2]

	dir, err := os.Open(".")
	if err != err {
		panic(err)
	}
	finfos, err := dir.Readdir(100)
	if err != nil {
		panic(err)
	}
	for _, fi := range finfos {
		s := rex.ReplaceAllString(fi.Name(), repl)
		fmt.Printf("%-60s %-60s\n", fi.Name(), s)
		if *yes {
			err = os.Rename(fi.Name(), s)
			if err != nil {
				panic(err)
			}
		}
	}
	fmt.Println(len(finfos), "renamed")
}

func main() {
	acomplete.Init("tb", true, []string{"-toc"})
	flag.Parse()

	if *autocomplete {
		acomplete.Complete()
		return
	}

	if flag.NFlag() == 0 {
		flag.Usage()
		return
	}

	if *newFeature {
		visitFlags()
		return
	}

	if *rebuild {
		rebuildToolbox()
		return
	}

	if *showVer {
		printVersion()
		return
	}

	if *showColors {
		printTerminalColors()
		return
	}

	if *showColorsTable {
		printTrueColorsTable()
	}

	if *regenXresources {
		regenerateXresources()
		return
	}

	if *startGodoc {
		startGodocServer()
		return
	}

	if *setEnv {
		setTestEnv()
		return
	}

	if *dedupPath != "" {
		deduplicatePath(*dedupPath)
		return
	}

	if *getTOC != "" {
		generateTOC(*getTOC)
		return
	}

	if *rename != "" {
		renameFiles()
		return
	}

	if *fontview {
		startFontViewer()
		return
	}
}
<commit_msg>Add aliases<commit_after>// tb is my toolbox.
//
// This is an attempt to keep scattered dotfiles and scripts in one place.
package main

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"os/user"
	"regexp"
	"strings"
	"time"

	"github.com/serge-v/toolbox/acomplete"
)

var (
	version string
	date    string
	u       *user.User
)

var (
	newFeature      = flag.Bool("n", false, "for testing new features")
	autocomplete    = flag.Bool("c", false, "for bash autocomplete")
	showVer         = flag.Bool("version", false, "show version")
	showColors      = flag.Bool("colors-true", false, "show terminal true colors")
	showColorsTable = flag.Bool("colors-table", false, "print true colors table")
	regenXresources = flag.Bool("regen-xresources", false, "regenerate local .Xresources")
	startGodoc      = flag.Bool("start-godoc", false, "start go doc ~/go on :6001")
	setEnv          = flag.Bool("setenv", false, "setenv test")
	getTOC          = flag.String("toc", "", "generate TOC from MD file")
	dedupPath       = flag.String("dedup-path", "", "deduplicate colon separated paths list")
	rename          = flag.String("rename", "", "rename files. For help use -rename help")
	yes             = flag.Bool("y", false, "confirm rename")
	fontview        = flag.Bool("fontview", false, "start font viewer in browser")
	browser         = flag.Bool("browser", false, "start browser")
	alias           = flag.Bool("alias", false, "print aliases")

	rebuild = flag.Bool("build", false, "rebuild tb from any dir")
)

func init() {
	var err error
	u, err = user.Current()
	if err != nil {
		panic(err)
	}
}

func printVersion() {
	fmt.Println("tb is my toolbox. Serge Voilokov (C) 2017.")
	fmt.Println("version:", version)
	fmt.Println("date:   ", date)
}

func rebuildToolbox() {
	gopath := u.HomeDir + "/go"
	tbpath := gopath + "/src/github.com/serge-v/toolbox"

	cmd := exec.Command("git", "describe", "--tags")
	cmd.Dir = tbpath
	out, err := cmd.CombinedOutput()
	if err != nil {
		println("error: git: ", string(out))
		return
	}
	ver := strings.TrimSpace(string(out))

	cmd = exec.Command("touch", "main.go")
	cmd.Dir = tbpath + "/cmd/tb"
	out, err = cmd.CombinedOutput()
	if err != nil {
		println("error: touch: ", string(out))
		return
	}

	args := []string{
		"install",
		"-ldflags",
		"-X main.date=" + time.Now().Format(time.RFC3339) + " -X main.version=" + ver,
		"github.com/serge-v/toolbox/..."}

	cmd = exec.Command("go", args...)
	cmd.Env = os.Environ()
	cmd.Env = append(cmd.Env, "GOPATH="+gopath)
	out, err = cmd.CombinedOutput()
	if err != nil {
		println("error: go: ", string(out))
		return
	}

	cmd = exec.Command("tb", "-version")
	out, err = cmd.CombinedOutput()
	if err != nil {
		println("error: tb -version: ", string(out))
		return
	}

	fmt.Print(string(out))
}

func startGodocServer() {
	gopath := u.HomeDir + "/go"
	cmd := exec.Command("sh", "-c", "godoc -http=:6060 2>/tmp/godoc.log 2>&1 &")
	cmd.Dir = gopath
	err := cmd.Start()
	if err != nil {
		println("error: go doc: ", err)
		return
	}
	fmt.Println("godoc:", "http://localhost:6060/pkg")
}

func setTestEnv() {
	os.Setenv("TESTVAR", "testvalue")
	for _, e := range os.Environ() {
		fmt.Println(e)
	}
}

func runcmd(cmdline string) {
	cmd := exec.Command("sh", "-c", cmdline)
	out, err := cmd.CombinedOutput()
	if err != nil {
		println("error:", cmdline, ":", string(out))
		return
	}
	fmt.Println(string(out))
}

func generateTOC(fname string) {
	runcmd(`grep -e "====" -B 1 "` + fname + `" | grep -v -e "===" -e "--"`)
}

func deduplicatePath(path string) {
	arr := strings.Split(path, ":")
	newarr := make([]string, 0, 10)
	chunks := make(map[string]bool, 20)
	for _, a := range arr {
		if _, ok := chunks[a]; ok {
			continue
		}
		newarr = append(newarr, a)
		chunks[a] = true
	}
	fmt.Println(strings.Join(newarr, ":"))
}

func visitFlags() {
	visitFunc := func(f *flag.Flag) {
		switch t := f.Value.(type) {
		default:
			fmt.Printf("%+v: %T\n", f.Name, t)
		}
	}
	flag.VisitAll(visitFunc)
}

var renameUsage = `tb -rename -- renames files in the current directory.
Usage:
  tb -rename /REGEX/REPL/  -- preview rename
  tb -rename /REGEX/REPL/ -y -- do rename`

func renameFiles() {
	if *rename == "help" {
		fmt.Println(renameUsage)
		return
	}

	p := strings.Split(*rename, "/")
	if len(p) != 4 {
		panic("invalid rename rule")
	}

	rex, err := regexp.Compile(p[1])
	if err != err {
		panic(err)
	}

	repl := p[2]

	dir, err := os.Open(".")
	if err != err {
		panic(err)
	}
	finfos, err := dir.Readdir(100)
	if err != nil {
		panic(err)
	}
	for _, fi := range finfos {
		s := rex.ReplaceAllString(fi.Name(), repl)
		fmt.Printf("%-60s %-60s\n", fi.Name(), s)
		if *yes {
			err = os.Rename(fi.Name(), s)
			if err != nil {
				panic(err)
			}
		}
	}
	fmt.Println(len(finfos), "renamed")
}

func main() {
	acomplete.Init("tb", true, []string{"-toc"})
	flag.Parse()

	if *autocomplete {
		acomplete.Complete()
		return
	}

	if flag.NFlag() == 0 {
		flag.Usage()
		return
	}

	if *newFeature {
		visitFlags()
		return
	}

	if *rebuild {
		rebuildToolbox()
		return
	}

	if *showVer {
		printVersion()
		return
	}

	if *showColors {
		printTerminalColors()
		return
	}

	if *showColorsTable {
		printTrueColorsTable()
	}

	if *regenXresources {
		regenerateXresources()
		return
	}

	if *startGodoc {
		startGodocServer()
		return
	}

	if *setEnv {
		setTestEnv()
		return
	}

	if *dedupPath != "" {
		deduplicatePath(*dedupPath)
		return
	}

	if *getTOC != "" {
		generateTOC(*getTOC)
		return
	}

	if *rename != "" {
		renameFiles()
		return
	}

	if *fontview {
		startFontViewer()
		return
	}

	if *browser {
		u := os.Getenv("USER")
		if u == "alarm" {
			cmd := exec.Command("chromium", "--process-per-tab", "https://duckduckgo.com")
			if err := cmd.Start(); err != nil {
				panic(err)
			}
		}
		return
	}

	if *alias {
		fmt.Println("alias ,sv='cd ~/go/src/github.com/serge-v/toolbox/cmd/tb'; pwd")
		fmt.Println("alias ,tbalias='. <(tb -alias); alias'")
		fmt.Println("alias ll='ls -l --color=auto'")
		fmt.Println("# run first time: . <(tb -alias)")
		return
	}
}
<|endoftext|>


<commit_before>// USL is a modeler for the Universal Scalability Law, which can be used in
// system testing and capacity planning.
//
// As an example, consider doing load testing and capacity planning for an HTTP
// server. To use USL, we must first gather a set of measurements of the system.
// These measurements will consist of pairs of simultaneous measurements of the
// independent and dependent variables. With an HTTP server, it might be tempting
// to use the rate as the independent variable, but this is a mistake. The rate
// of requests being handled by the server is actually itself a dependent
// variable of two other independent variables: the number of concurrent users
// and the rate at which users send requests.
//
// As we do our capacity planning, we make the observation that users of our
// system do ~10 req/sec. (Or, more commonly, we assume this based on a hunch.)
// By holding this constant, we leave the number of concurrent users as the
// single remaining independent variable.
//
// Our load testing, then, should consist of running a series of tests with an
// increasing number of simulated users, each performing ~10 req/sec. While the
// number of users to test with depends heavily on your system, you should be
// testing at least six different concurrency levels. You should do one test with
// a single user in order to determine the performance of an uncontended system.
//
// After our load testing is done, we should have a CSV file which consists of
// a series of (x, y) pairs of measurements:
//
//		1,4227
//		2,8382
//		4,16479
//		8,31856
//		16,59564
//		32,104462
//		64,162985
//
// We can then run the USL binary:
//
//		usl -in data.csv
//
// USL parses the given CSV file as a series of (x, y) points, calculates the
// USL parameters using quadratic regression, and then prints out the details of
// the model:
//
//		Model:
//				α:    0.008550 (constrained by contention effects)
//				β:    0.000030
//				peak: X=181, Y=217458.30
//
// Among the details here we see two things worth noting. First, the system
// appears to be constrained by contention, so optimization work should be
// focused mostly on removing locks, etc. Second, the peak throughput of the
// system is expected to occur at 181 concurrent users, at which point the system
// will be expected to handle ~217K req/sec.
//
// (These numbers are made up, so don't sweat them.)
//
// Finally, we can provide USL a series of additional data points to provide
// estimates for:
//
//		usl -in data.csv 128 256 512
//
// USL will output the data in CSV format on STDOUT.
//
// For more information, see http://www.perfdynamics.com/Manifesto/USLscalability.html.
package main

import (
	"encoding/csv"
	"flag"
	"fmt"
	"log"
	"os"
	"strconv"

	"github.com/codahale/usl"
)

var (
	input = flag.String("in", "", "input file")
)

func main() {
	log.SetFlags(0) // don't prefix the log statements
	log.SetOutput(os.Stderr)
	flag.Parse()

	if len(*input) == 0 {
		log.Fatal("No input files provided.")
	}

	measurements, err := parseCSV(*input)
	if err != nil {
		log.Fatal(err)
	}

	m, err := usl.Build(measurements)
	if err != nil {
		log.Fatal(err)
	}

	var a, b string
	if m.Alpha > m.Beta {
		a = " (constrained by contention effects)"
	} else if m.Alpha < m.Beta {
		b = " (constrained by coherency effects)"
	}

	log.Println("Model:")
	log.Printf("\tα:    %f%s\n", m.Alpha, a)
	log.Printf("\tβ:    %f%s\n", m.Beta, b)
	log.Printf("\tpeak: X=%.0f, Y=%2.2f\n", m.Peak, m.Predict(m.Peak))
	log.Println()

	for _, s := range flag.Args() {
		x, err := strconv.ParseFloat(s, 64)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%f,%f\n", x, m.Predict(x))
	}
}

func parseCSV(filename string) (usl.MeasurementSet, error) {
	measurements := make(usl.MeasurementSet, 0)

	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	r := csv.NewReader(f)
	lines, err := r.ReadAll()
	if err != nil {
		return nil, err
	}

	for i, line := range lines {
		m, err := parseLine(i, line)
		if err != nil {
			return nil, err
		}
		measurements = append(measurements, m)
	}

	return measurements, nil
}

func parseLine(i int, line []string) (m usl.Measurement, err error) {
	if len(line) != 2 {
		err = fmt.Errorf("invalid line at line %d", i+1)
		return
	}

	m.X, err = strconv.ParseFloat(line[0], 64)
	if err != nil {
		err = fmt.Errorf("%v at line %d, column 1", err, i+1)
		return
	}

	m.Y, err = strconv.ParseFloat(line[1], 64)
	if err != nil {
		err = fmt.Errorf("%v at line %d, column 2", err, i+1)
		return
	}

	return
}
<commit_msg>Simplified main func.<commit_after>// USL is a modeler for the Universal Scalability Law, which can be used in
// system testing and capacity planning.
//
// As an example, consider doing load testing and capacity planning for an HTTP
// server. To use USL, we must first gather a set of measurements of the system.
// These measurements will consist of pairs of simultaneous measurements of the
// independent and dependent variables. With an HTTP server, it might be tempting
// to use the rate as the independent variable, but this is a mistake. The rate
// of requests being handled by the server is actually itself a dependent
// variable of two other independent variables: the number of concurrent users
// and the rate at which users send requests.
//
// As we do our capacity planning, we make the observation that users of our
// system do ~10 req/sec. (Or, more commonly, we assume this based on a hunch.)
// By holding this constant, we leave the number of concurrent users as the
// single remaining independent variable.
//
// Our load testing, then, should consist of running a series of tests with an
// increasing number of simulated users, each performing ~10 req/sec. While the
// number of users to test with depends heavily on your system, you should be
// testing at least six different concurrency levels. You should do one test with
// a single user in order to determine the performance of an uncontended system.
//
// After our load testing is done, we should have a CSV file which consists of
// a series of (x, y) pairs of measurements:
//
//		1,4227
//		2,8382
//		4,16479
//		8,31856
//		16,59564
//		32,104462
//		64,162985
//
// We can then run the USL binary:
//
//		usl -in data.csv
//
// USL parses the given CSV file as a series of (x, y) points, calculates the
// USL parameters using quadratic regression, and then prints out the details of
// the model:
//
//		Model:
//				α:    0.008550 (constrained by contention effects)
//				β:    0.000030
//				peak: X=181, Y=217458.30
//
// Among the details here we see two things worth noting. First, the system
// appears to be constrained by contention, so optimization work should be
// focused mostly on removing locks, etc. Second, the peak throughput of the
// system is expected to occur at 181 concurrent users, at which point the system
// will be expected to handle ~217K req/sec.
//
// (These numbers are made up, so don't sweat them.)
//
// Finally, we can provide USL a series of additional data points to provide
// estimates for:
//
//		usl -in data.csv 128 256 512
//
// USL will output the data in CSV format on STDOUT.
//
// For more information, see http://www.perfdynamics.com/Manifesto/USLscalability.html.
package main

import (
	"encoding/csv"
	"flag"
	"fmt"
	"log"
	"os"
	"strconv"

	"github.com/codahale/usl"
)

var (
	input = flag.String("in", "", "input file")
)

func main() {
	log.SetFlags(0) // don't prefix the log statements
	log.SetOutput(os.Stderr)
	flag.Parse()

	if len(*input) == 0 {
		log.Fatal("No input files provided.")
	}

	measurements, err := parseCSV(*input)
	if err != nil {
		log.Fatal(err)
	}

	m, err := usl.Build(measurements)
	if err != nil {
		log.Fatal(err)
	}

	printModel(m)

	printPredictions(m)
}

func printModel(m usl.Model) {
	var a, b string
	if m.Alpha > m.Beta {
		a = " (constrained by contention effects)"
	} else if m.Alpha < m.Beta {
		b = " (constrained by coherency effects)"
	}

	log.Println("Model:")
	log.Printf("\tα:    %f%s\n", m.Alpha, a)
	log.Printf("\tβ:    %f%s\n", m.Beta, b)
	log.Printf("\tpeak: X=%.0f, Y=%2.2f\n", m.Peak, m.Predict(m.Peak))
	log.Println()
}

func printPredictions(m usl.Model) {
	for _, s := range flag.Args() {
		x, err := strconv.ParseFloat(s, 64)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%f,%f\n", x, m.Predict(x))
	}
}

func parseCSV(filename string) (usl.MeasurementSet, error) {
	measurements := make(usl.MeasurementSet, 0)

	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	r := csv.NewReader(f)
	lines, err := r.ReadAll()
	if err != nil {
		return nil, err
	}

	for i, line := range lines {
		m, err := parseLine(i, line)
		if err != nil {
			return nil, err
		}
		measurements = append(measurements, m)
	}

	return measurements, nil
}

func parseLine(i int, line []string) (m usl.Measurement, err error) {
	if len(line) != 2 {
		err = fmt.Errorf("invalid line at line %d", i+1)
		return
	}

	m.X, err = strconv.ParseFloat(line[0], 64)
	if err != nil {
		err = fmt.Errorf("%v at line %d, column 1", err, i+1)
		return
	}

	m.Y, err = strconv.ParseFloat(line[1], 64)
	if err != nil {
		err = fmt.Errorf("%v at line %d, column 2", err, i+1)
		return
	}

	return
}
<|endoftext|>


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

package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
)

var CommitHash string

func version(commit string) string {
	if commit == "" {
		return fmt.Sprintf("ezorm v%d.%d.%d", vMajor, vMinor, vPatch)
	}
	return fmt.Sprintf("ezorm v%d.%d.%d-%s", vMajor, vMinor, vPatch, commit)
}

const (
	vMajor = 2
	vMinor = 5
	vPatch = 4
)

// versionCmd represents the version command
var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "EzOrm 版本信息",
	Long:  `EzOrm 版本信息`,
	Run: func(_ *cobra.Command, _ []string) {
		fmt.Fprintln(os.Stdout, version(CommitHash))
	},
}

func init() {
	RootCmd.AddCommand(versionCmd)
}
<commit_msg>cmd: bump version to 2.5.5<commit_after>// Copyright © 2022 ezbuy & LITB Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
)

var CommitHash string

func version(commit string) string {
	if commit == "" {
		return fmt.Sprintf("ezorm v%d.%d.%d", vMajor, vMinor, vPatch)
	}
	return fmt.Sprintf("ezorm v%d.%d.%d-%s", vMajor, vMinor, vPatch, commit)
}

const (
	vMajor = 2
	vMinor = 5
	vPatch = 5
)

// versionCmd represents the version command
var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "EzOrm 版本信息",
	Long:  `EzOrm 版本信息`,
	Run: func(_ *cobra.Command, _ []string) {
		fmt.Fprintln(os.Stdout, version(CommitHash))
	},
}

func init() {
	RootCmd.AddCommand(versionCmd)
}
<|endoftext|>


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

package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

var buildVersion = "Unknown"
var commitId string

// versionCmd represents the version command
var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Shows the version information",
	Long:  `Shows version information and exits`,
	Run: func(cmd *cobra.Command, args []string) {
		//	Show the version number
		fmt.Printf("Centralconfig version %s", buildVersion)

		//	Show the commitid if available:
		if commitId != "" {
			fmt.Printf(" (%s)", commitId)
		}
	},
}

func init() {
	RootCmd.AddCommand(versionCmd)
}
<commit_msg>Version info<commit_after>// Copyright © 2016 NAME HERE <EMAIL ADDRESS>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

var buildVersion = "Unknown"
var commitId string

// versionCmd represents the version command
var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Shows the version information",
	Long:  `Shows version information and exits`,
	Run: func(cmd *cobra.Command, args []string) {
		//	Show the version number
		fmt.Printf("Centralconfig version %s", buildVersion)

		//	Show the commitid if available:
		if commitId != "" {
			fmt.Printf(" (%s)", commitId[:7])
		}
	},
}

func init() {
	RootCmd.AddCommand(versionCmd)
}
<|endoftext|>


<commit_before>package main

import  (
        "fmt"
        "../go-todotxt"
        "github.com/docopt/docopt.go"
)

func main() {

        usage := `Go Todo.txt

Usage:
    gotodo
    gotodo list
    gotodo add <task>
    gotodo (finish|done) <id>
    gotodo --num-tasks
    gotodo -h | --help
    gotodo -v | --version

Options:
    -h --help     Show this screen.
    -v --version  Show version.
    --num-tasks   Show number of tasks.`

        arguments, _ := docopt.Parse(usage, nil, true, "Go Todo.txt 0.1", false)

        //fmt.Println(arguments)

        tasks := todotxt.LoadTaskList("todo.txt")
        tasks.Sort()

        if (arguments["--num-tasks"].(bool)) {
                fmt.Println(tasks.Len())
        } else {
                for i, task := range tasks {
                        fmt.Println(i, task.RawText())
                }
        }

        //fmt.Println(tasks)
        //fmt.Println(tasks.Count())
}
<commit_msg>sort by date added<commit_after>package main

import  (
        "fmt"
        "../go-todotxt"
        "github.com/docopt/docopt.go"
)

func main() {

        usage := `Go Todo.txt

Usage:
    gotodo [--sort=<prio|date>]
    gotodo list [--sort=<prio|date>]
    gotodo add <task>
    gotodo (finish|done) <id>
    gotodo --num-tasks
    gotodo -h | --help
    gotodo -v | --version

Options:
    -h --help     Show this screen.
    -v --version  Show version.
    --num-tasks   Show number of tasks.`

        arguments, _ := docopt.Parse(usage, nil, true, "Go Todo.txt 0.1", false)

        //fmt.Println(arguments)

        tasks := todotxt.LoadTaskList("todo.txt")

        if (arguments["--num-tasks"].(bool)) {
                fmt.Println(tasks.Len())
        } else {

                if arguments["--sort"] == nil || arguments["--sort"] == "prio" {
                        tasks.Sort()
                } else {
                        tasks.SortByCreateDate()
                }

                for i, task := range tasks {
                        fmt.Println(i, task.RawText())
                }
        }

        //fmt.Println(tasks)
        //fmt.Println(tasks.Count())
}
<|endoftext|>


<commit_before>package handlers

import (
	"context"
	"fmt"
	"net/http"

	"github.com/danielkrainas/gobag/api/errcode"
	"github.com/danielkrainas/gobag/context"
	"github.com/urfave/negroni"

	"github.com/danielkrainas/shexd/api/v1"
)

func Base(w http.ResponseWriter, r *http.Request) {
	const emptyJSON = "{}"

	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Header().Set("Content-Length", fmt.Sprint(len(emptyJSON)))
	w.WriteHeader(http.StatusOK)
	fmt.Fprint(w, emptyJSON)
}

func Alive(path string) negroni.Handler {
	return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
		if r.URL.Path == path {
			w.Header().Set("Cache-Control", "no-cache")
			w.WriteHeader(http.StatusOK)
			return
		}

		next(w, r)
	})
}

func Context(parent context.Context) negroni.Handler {
	return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
		ctx := acontext.DefaultContextManager.Context(parent, w, r)
		defer acontext.DefaultContextManager.Release(ctx)

		ctx = acontext.WithVars(ctx, r)
		ctx = acontext.WithLogger(ctx, acontext.GetLogger(ctx))
		ctx = context.WithValue(ctx, "url.builder", v1.NewURLBuilderFromRequest(r, false))

		if iw, err := acontext.GetResponseWriter(ctx); err != nil {
			acontext.GetLogger(ctx).Warnf("response writer not found in context")
		} else {
			w = iw
		}

		next(w, r.WithContext(ctx))
	})
}

func Logging(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	ctx := r.Context()
	acontext.GetRequestLogger(ctx).Info("request started")
	defer func() {
		status, ok := ctx.Value("http.response.status").(int)
		if ok && status >= 200 && status <= 399 {
			acontext.GetResponseLogger(ctx).Info("response completed")
		}
	}()

	next(w, r)
}

func TrackErrors(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	ctx := acontext.ErrorTracking(r.Context())
	next(w, r.WithContext(ctx))
	if errors := acontext.GetErrors(ctx); errors.Len() > 0 {
		if err := errcode.ServeJSON(w, errors); err != nil {
			acontext.GetLogger(ctx).Errorf("error serving error json: %v (from %s)", err, errors)
		}

		logErrors(ctx, errors)
	}
}

func logErrors(ctx context.Context, errors errcode.Errors) {
	for _, err := range errors {
		var lctx context.Context

		switch err.(type) {
		case errcode.Error:
			e, _ := err.(errcode.Error)
			lctx = acontext.WithValue(ctx, "err.code", e.Code)
			lctx = acontext.WithValue(lctx, "err.message", e.Code.Message())
			lctx = acontext.WithValue(lctx, "err.detail", e.Detail)
		case errcode.ErrorCode:
			e, _ := err.(errcode.ErrorCode)
			lctx = acontext.WithValue(ctx, "err.code", e)
			lctx = acontext.WithValue(lctx, "err.message", e.Message())
		default:
			// normal "error"
			lctx = acontext.WithValue(ctx, "err.code", errcode.ErrorCodeUnknown)
			lctx = acontext.WithValue(lctx, "err.message", err.Error())
		}

		lctx = acontext.WithLogger(ctx, acontext.GetLogger(lctx,
			"err.code",
			"err.message",
			"err.detail"))

		acontext.GetResponseLogger(lctx).Errorf("response completed with error")
	}
}
<commit_msg>log error responses as complete as well<commit_after>package handlers

import (
	"context"
	"fmt"
	"net/http"

	"github.com/danielkrainas/gobag/api/errcode"
	"github.com/danielkrainas/gobag/context"
	"github.com/urfave/negroni"

	"github.com/danielkrainas/shexd/api/v1"
)

func Base(w http.ResponseWriter, r *http.Request) {
	const emptyJSON = "{}"

	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Header().Set("Content-Length", fmt.Sprint(len(emptyJSON)))
	w.WriteHeader(http.StatusOK)
	fmt.Fprint(w, emptyJSON)
}

func Alive(path string) negroni.Handler {
	return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
		if r.URL.Path == path {
			w.Header().Set("Cache-Control", "no-cache")
			w.WriteHeader(http.StatusOK)
			return
		}

		next(w, r)
	})
}

func Context(parent context.Context) negroni.Handler {
	return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
		ctx := acontext.DefaultContextManager.Context(parent, w, r)
		defer acontext.DefaultContextManager.Release(ctx)

		ctx = acontext.WithVars(ctx, r)
		ctx = acontext.WithLogger(ctx, acontext.GetLogger(ctx))
		ctx = context.WithValue(ctx, "url.builder", v1.NewURLBuilderFromRequest(r, false))

		if iw, err := acontext.GetResponseWriter(ctx); err != nil {
			acontext.GetLogger(ctx).Warnf("response writer not found in context")
		} else {
			w = iw
		}

		next(w, r.WithContext(ctx))
	})
}

func Logging(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	ctx := r.Context()
	acontext.GetRequestLogger(ctx).Info("request started")
	defer func() {
		status, ok := ctx.Value("http.response.status").(int)
		if ok && status >= 200 && status <= 399 {
			acontext.GetResponseLogger(ctx).Info("response completed")
		} else {
			acontext.GetResponseLogger(ctx).Warn("response completed with error")
		}
	}()

	next(w, r)
}

func TrackErrors(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	ctx := acontext.ErrorTracking(r.Context())
	next(w, r.WithContext(ctx))
	if errors := acontext.GetErrors(ctx); errors.Len() > 0 {
		if err := errcode.ServeJSON(w, errors); err != nil {
			acontext.GetLogger(ctx).Errorf("error serving error json: %v (from %s)", err, errors)
		}

		logErrors(ctx, errors)
	}
}

func logErrors(ctx context.Context, errors errcode.Errors) {
	for _, err := range errors {
		var lctx context.Context

		switch err.(type) {
		case errcode.Error:
			e, _ := err.(errcode.Error)
			lctx = acontext.WithValue(ctx, "err.code", e.Code)
			lctx = acontext.WithValue(lctx, "err.message", e.Code.Message())
			lctx = acontext.WithValue(lctx, "err.detail", e.Detail)
		case errcode.ErrorCode:
			e, _ := err.(errcode.ErrorCode)
			lctx = acontext.WithValue(ctx, "err.code", e)
			lctx = acontext.WithValue(lctx, "err.message", e.Message())
		default:
			// normal "error"
			lctx = acontext.WithValue(ctx, "err.code", errcode.ErrorCodeUnknown)
			lctx = acontext.WithValue(lctx, "err.message", err.Error())
		}

		lctx = acontext.WithLogger(ctx, acontext.GetLogger(lctx,
			"err.code",
			"err.message",
			"err.detail"))

		acontext.GetResponseLogger(lctx).Errorf("response completed with error")
	}
}
<|endoftext|>


<commit_before>package service

import (
	"github.com/timeredbull/tsuru/api/app"
	"github.com/timeredbull/tsuru/db"
	"labix.org/v2/mgo/bson"
)

type ServiceInstance struct {
	Name        string   `bson:"_id"`
	ServiceName string   `bson:"service_name"`
	Apps        []string `bson:"apps"`
	Instance    string
	Host        string
}

func (si *ServiceInstance) Create() error {
	err := db.Session.ServiceInstances().Insert(si)
	return err
}

func (si *ServiceInstance) Delete() error {
	doc := bson.M{"_id": si.Name, "apps": si.Apps}
	err := db.Session.ServiceInstances().Remove(doc)
	return err
}

func (si *ServiceInstance) Service() *Service {
	s := &Service{}
	db.Session.Services().Find(bson.M{"_id": si.ServiceName}).One(s)
	return s
}

func (si *ServiceInstance) AllApps() []app.App {
	var apps []app.App
	q := bson.M{"name": bson.M{"$in": si.Apps}}
	db.Session.Apps().Find(q).All(&apps)
	return apps
}
<commit_msg>api/service: added Env map to ServiceInstance<commit_after>package service

import (
	"github.com/timeredbull/tsuru/api/app"
	"github.com/timeredbull/tsuru/db"
	"labix.org/v2/mgo/bson"
)

type ServiceInstance struct {
	Name        string   `bson:"_id"`
	ServiceName string   `bson:"service_name"`
	Apps        []string `bson:"apps"`
	Instance    string
	Host        string
	Env         map[string]string
}

func (si *ServiceInstance) Create() error {
	err := db.Session.ServiceInstances().Insert(si)
	return err
}

func (si *ServiceInstance) Delete() error {
	doc := bson.M{"_id": si.Name, "apps": si.Apps}
	err := db.Session.ServiceInstances().Remove(doc)
	return err
}

func (si *ServiceInstance) Service() *Service {
	s := &Service{}
	db.Session.Services().Find(bson.M{"_id": si.ServiceName}).One(s)
	return s
}

func (si *ServiceInstance) AllApps() []app.App {
	var apps []app.App
	q := bson.M{"name": bson.M{"$in": si.Apps}}
	db.Session.Apps().Find(q).All(&apps)
	return apps
}
<|endoftext|>


<commit_before>package coco

import (
	"bytes"
	"crypto/cipher"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"os"
	"regexp"
	"strconv"
	"time"

	"github.com/dedis/crypto/abstract"
	"github.com/dedis/crypto/nist"
)

/*
Example configuration file.
file format: json

conn: indicates what protocol should be used
	by default it uses the "tcp" protocol
	"tcp": uses TcpConn for communications
	"goroutine": uses GoConn for communications [default]

ex.json
{
	conn: "tcp"
	hosts: ["host1", "host2", "host3"],
	tree: {name: host1,
		   children: [
		     {name: host2,
			  children: [{name: host3}, {name: host4}]}
			 {name: host5,
			  children: [{name: host6}]}}
}
*/

type ConfigFile struct {
	Conn  string   `json:"conn,omitempty"`
	Hosts []string `json:"hosts"`
	Tree  Node     `json:"tree"`
}

// why can't I just deal with nist.Point
type JSONPoint json.RawMessage

type Node struct {
	Name     string `json:"name"`
	PriKey   string `json:"prikey,omitempty"`
	PubKey   string `json:"pubkey,omitempty"`
	Children []Node `json:"children,omitempty"`
}

// HostConfig stores all of the relevant information of the configuration file.
type HostConfig struct {
	SNodes []*SigningNode          // an array of signing nodes
	Hosts  map[string]*SigningNode // maps hostname to host
	Dir    *GoDirectory            // the directory mapping hostnames to goPeers
}

func (hc *HostConfig) Verify() error {
	root := hc.SNodes[0]
	traverseTree(root, hc, publicKeyCheck)
	fmt.Println("tree verified")
	return nil
}

func publicKeyCheck(n *SigningNode, hc *HostConfig) error {
	x_hat := n.pubKey
	for cn := range n.Children() {
		c := hc.Hosts[cn]
		x_hat.Add(x_hat, c.X_hat)
	}
	/*if x_hat != n.X_hat {
		return errors.New("parent X_hat != Sum(child.X_hat)+pubKey")
	}*/
	return nil
}

func traverseTree(p *SigningNode,
	hc *HostConfig,
	f func(*SigningNode, *HostConfig) error) error {
	if err := f(p, hc); err != nil {
		return err
	}
	for cn := range p.Children() {
		c := hc.Hosts[cn]
		err := traverseTree(c, hc, f)
		if err != nil {
			return err
		}
	}
	return nil
}

func (hc *HostConfig) String() string {
	b := bytes.NewBuffer([]byte{})

	// write the hosts
	b.WriteString("{\"hosts\": [")
	for i, sn := range hc.SNodes {
		if i != 0 {
			b.WriteString(", ")
		}
		b.WriteString("\"" + sn.Name() + "\"")
	}
	b.WriteString("],")

	// write the tree structure
	b.WriteString("\"tree\": ")
	root := hc.SNodes[0]
	writeHC(b, hc, root)
	b.WriteString("}\n")

	// format the resulting JSON for readability
	bformatted := bytes.NewBuffer([]byte{})
	err := json.Indent(bformatted, b.Bytes(), "", "\t")
	if err != nil {
		fmt.Println(string(b.Bytes()))
		fmt.Println("ERROR: ", err)
	}

	return string(bformatted.Bytes())
}

func writeHC(b *bytes.Buffer, hc *HostConfig, p *SigningNode) {
	// Node{name, pubkey, x_hat, children}
	fmt.Fprint(b, "{\"name\":", "\""+p.Name()+"\",")
	fmt.Fprint(b, "\"prikey\":", "\""+string(hex.EncodeToString(p.privKey.Encode()))+"\",")
	fmt.Fprint(b, "\"pubkey\":", "\""+string(hex.EncodeToString(p.pubKey.Encode()))+"\",")

	// recursively format children
	fmt.Fprint(b, "\"children\":[")
	i := 0
	for n := range p.Children() {
		if i != 0 {
			b.WriteString(", ")
		}
		c := hc.Hosts[n]
		writeHC(b, hc, c)
		i++
	}
	fmt.Fprint(b, "]}")
}

// NewHostConfig creates a new host configuration that can be populated with
// hosts.
func NewHostConfig() *HostConfig {
	return &HostConfig{SNodes: make([]*SigningNode, 0), Hosts: make(map[string]*SigningNode), Dir: NewGoDirectory()}
}

type ConnType int

const (
	GoC ConnType = iota
	TcpC
)

// ConstructTree does a depth-first construction of the tree specified in the
// config file. ConstructTree must be call AFTER populating the HostConfig with
// ALL the possible hosts.
func ConstructTree(
	n Node,
	hc *HostConfig,
	parent string,
	suite abstract.Suite,
	rand cipher.Stream,
	hosts map[string]Host,
	nameToAddr map[string]string,
	opts ConfigOptions) (abstract.Point, error) {
	// passes up its X_hat, and/or an error

	// get the name associated with this address
	name, ok := nameToAddr[n.Name]
	if !ok {
		fmt.Println("unknown name in address book:", n.Name)
		return nil, errors.New("unknown name in address book")
	}

	// generate indicates whether we should generate the signing
	// node for this hostname
	generate := opts.Host == "" || opts.Host == name

	// check to make sure the this hostname is in the tree
	// it can be backed by a nil pointer
	h, ok := hosts[name]
	if !ok {
		fmt.Println("unknown host in tree:", name)
		return nil, errors.New("unknown host in tree")
	}

	var prikey abstract.Secret
	var pubkey abstract.Point
	var sn *SigningNode

	// if the JSON holds the fields field is set load from there
	if len(n.PubKey) != 0 {
		log.Println("decoding point")
		encoded, err := hex.DecodeString(string(n.PubKey))
		if err != nil {
			log.Print("failed to decode hex from encoded")
			return nil, err
		}
		pubkey = suite.Point()
		err = pubkey.Decode(encoded)
		if err != nil {
			log.Print("failed to decode point from hex")
			return nil, err
		}
		log.Println("decoding point")
		encoded, err = hex.DecodeString(string(n.PriKey))
		if err != nil {
			log.Print("failed to decode hex from encoded")
			return nil, err
		}
		prikey = suite.Secret()
		err = prikey.Decode(encoded)
		if err != nil {
			log.Print("failed to decode point from hex")
			return nil, err
		}
	} else if generate {
		if prikey != nil {
			// if we have been given a private key load that
			hc.SNodes = append(hc.SNodes, NewKeyedSigningNode(h, suite, prikey))
		} else {
			// otherwise generate a random new one
			hc.SNodes = append(hc.SNodes, NewSigningNode(h, suite, rand))
		}
		sn = hc.SNodes[len(hc.SNodes)-1]
		hc.Hosts[name] = sn
		if prikey == nil {
			prikey = sn.privKey
			pubkey = sn.pubKey
		}
		// log.Println("pubkey:", sn.pubKey)
		// log.Println("given: ", pubkey)
	} else {
		log.Fatal("public keys have not been given and not generating")
	}
	// if the parent of this call is empty then this must be the root node
	if parent != "" && generate {
		h.AddParent(parent)
	}
	// log.Println("name: ", n.Name)
	// log.Println("prikey: ", prikey)
	// log.Println("pubkey: ", pubkey)
	x_hat := suite.Point().Null()
	x_hat.Add(x_hat, pubkey)
	// log.Println("x_hat: ", x_hat)
	for _, c := range n.Children {
		// connect this node to its children
		cname, ok := nameToAddr[c.Name]
		if !ok {
			fmt.Println("unknown name in address book:", n.Name)
			return nil, errors.New("unknown name in address book")
		}

		if generate {
			h.AddChildren(cname)
		}

		// recursively construct the children
		cpubkey, err := ConstructTree(c, hc, h.Name(), suite, rand, hosts, nameToAddr, opts)
		if err != nil {
			return nil, err
		}

		// if generating all csn will be availible
		// log.Print("adding from child: ", x_hat, cpubkey)
		x_hat.Add(x_hat, cpubkey)
	}
	if generate {
		sn.X_hat = x_hat
	}
	// log.Println("name: ", n.Name)
	// log.Println("final x_hat: ", x_hat)
	// log.Println("final pubkey: ", pubkey)
	return x_hat, nil
}

var ipv4Reg = regexp.MustCompile(`\d+\.\d+\.\d+\.\d+`)
var ipv4host = "NONE"

// getAddress gets the localhosts IPv4 address.
func GetAddress() (string, error) {
	name, err := os.Hostname()
	if err != nil {
		log.Print("Error Resolving Hostname:", err)
		return "", err
	}

	if ipv4host == "NONE" {
		as, err := net.LookupHost(name)
		if err != nil {
			return "", err
		}

		addr := ""

		for _, a := range as {
			log.Printf("a = %+v", a)
			if ipv4Reg.MatchString(a) {
				log.Print("matches")
				addr = a
			}
		}

		if addr == "" {
			err = errors.New("No IPv4 Address for Hostname")
		}
		return addr, err
	}
	return ipv4host, nil
}

var startConfigPort = 8089

type ConfigOptions struct {
	ConnType  string   // "go", tcp"
	Hostnames []string // if not nil replace hostnames with these
	GenHosts  bool     // if true generate random hostnames (all tcp)
	Host      string   // hostname to load into memory: "" for all
}

// TODO: if in tcp mode associate each hostname in the file with a different
// port. Get the remote address of this computer to combine with those for the
// complete hostnames to be used by the hosts.
func LoadJSON(file []byte, optsSlice ...ConfigOptions) (*HostConfig, error) {
	opts := ConfigOptions{}
	if len(optsSlice) > 0 {
		opts = optsSlice[0]
	}

	hc := NewHostConfig()
	var cf ConfigFile
	err := json.Unmarshal(file, &cf)
	if err != nil {
		return hc, err
	}

	connT := GoC
	if cf.Conn == "tcp" {
		connT = TcpC
	}

	// options override file
	if opts.ConnType == "tcp" {
		connT = TcpC
	}

	dir := NewGoDirectory()
	hosts := make(map[string]Host)
	nameToAddr := make(map[string]string)

	if connT == GoC {
		for _, h := range cf.Hosts {
			if _, ok := hc.Hosts[h]; !ok {
				nameToAddr[h] = h
				// it doesn't make sense to only make 1 go host
				hosts[h] = NewGoHost(h, dir)
			}
		}

	} else if connT == TcpC {
		localAddr := ""

		if opts.GenHosts {
			localAddr, err = GetAddress()
			if err != nil {
				return nil, err
			}
		}

		for _, h := range cf.Hosts {

			addr := h
			if opts.GenHosts {
				p := strconv.Itoa(startConfigPort)
				addr = localAddr + ":" + p
				//log.Println("created new host address: ", addr)
				startConfigPort++
			}

			nameToAddr[h] = addr
			// add to the hosts list if we havent added it before
			if _, ok := hc.Hosts[addr]; !ok {
				// only create the tcp hosts requested
				if opts.Host == "" || opts.Host == addr {
					hosts[addr] = NewTCPHost(addr)
				} else {
					hosts[addr] = nil // it is there but not backed
				}
			}
		}
	}
	suite := nist.NewAES128SHA256P256()
	rand := suite.Cipher([]byte("example"))
	_, err = ConstructTree(cf.Tree, hc, "", suite, rand, hosts, nameToAddr, opts)
	return hc, err
}

// run the given hostnames
func (hc *HostConfig) Run(hostnameSlice ...string) error {
	hostnames := make(map[string]*SigningNode)
	if hostnameSlice == nil {
		hostnames = hc.Hosts
	} else {

		for _, h := range hostnameSlice {
			sn, ok := hc.Hosts[h]
			if !ok {
				return errors.New("hostname given not in config file:" + h)
			}
			hostnames[h] = sn
		}
	}
	for _, sn := range hostnames {
		go func(sn *SigningNode) {
			// start listening for messages from within the tree
			sn.Host.Listen()
		}(sn)
	}

	for _, sn := range hostnames {
		var err error
		// exponential backoff for attempting to connect to parent
		startTime := time.Duration(200)
		maxTime := time.Duration(60000)
		for i := 0; i < 100; i++ {
			log.Println("attempting to connect to parent")
			err = sn.Connect()
			if err == nil {
				break
			}

			time.Sleep(startTime * time.Millisecond)
			startTime *= 2
			if startTime > maxTime {
				startTime = maxTime
			}
		}
		if err != nil {
			return errors.New("failed to connect")
		}
	}

	// need to make sure connections are setup properly first
	// wait for a little bit for connections to establish fully
	time.Sleep(1000 * time.Millisecond)
	for _, sn := range hostnames {
		go func(sn *SigningNode) {
			// start listening for messages from within the tree
			sn.Listen()
		}(sn)
	}
	return nil
}

// LoadConfig loads a configuration file in the format specified above. It
// populates a HostConfig with HostNode Hosts and goPeer Peers.
func LoadConfig(fname string, opts ...ConfigOptions) (*HostConfig, error) {
	file, err := ioutil.ReadFile(fname)
	if err != nil {
		return nil, err
	}
	return LoadJSON(file, opts...)
}
<commit_msg>config file able to save and recover with private keys specified<commit_after>package coco

import (
	"bytes"
	"crypto/cipher"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"os"
	"regexp"
	"strconv"
	"time"

	"github.com/dedis/crypto/abstract"
	"github.com/dedis/crypto/nist"
)

/*
Example configuration file.
file format: json

conn: indicates what protocol should be used
	by default it uses the "tcp" protocol
	"tcp": uses TcpConn for communications
	"goroutine": uses GoConn for communications [default]

ex.json
{
	conn: "tcp"
	hosts: ["host1", "host2", "host3"],
	tree: {name: host1,
		   children: [
		     {name: host2,
			  children: [{name: host3}, {name: host4}]}
			 {name: host5,
			  children: [{name: host6}]}}
}
*/

type ConfigFile struct {
	Conn  string   `json:"conn,omitempty"`
	Hosts []string `json:"hosts"`
	Tree  Node     `json:"tree"`
}

// why can't I just deal with nist.Point
type JSONPoint json.RawMessage

type Node struct {
	Name     string `json:"name"`
	PriKey   string `json:"prikey,omitempty"`
	PubKey   string `json:"pubkey,omitempty"`
	Children []Node `json:"children,omitempty"`
}

// HostConfig stores all of the relevant information of the configuration file.
type HostConfig struct {
	SNodes []*SigningNode          // an array of signing nodes
	Hosts  map[string]*SigningNode // maps hostname to host
	Dir    *GoDirectory            // the directory mapping hostnames to goPeers
}

func (hc *HostConfig) Verify() error {
	root := hc.SNodes[0]
	traverseTree(root, hc, publicKeyCheck)
	fmt.Println("tree verified")
	return nil
}

func publicKeyCheck(n *SigningNode, hc *HostConfig) error {
	x_hat := n.pubKey
	for cn := range n.Children() {
		c := hc.Hosts[cn]
		x_hat.Add(x_hat, c.X_hat)
	}
	/*if x_hat != n.X_hat {
		return errors.New("parent X_hat != Sum(child.X_hat)+pubKey")
	}*/
	return nil
}

func traverseTree(p *SigningNode,
	hc *HostConfig,
	f func(*SigningNode, *HostConfig) error) error {
	if err := f(p, hc); err != nil {
		return err
	}
	for cn := range p.Children() {
		c := hc.Hosts[cn]
		err := traverseTree(c, hc, f)
		if err != nil {
			return err
		}
	}
	return nil
}

func (hc *HostConfig) String() string {
	b := bytes.NewBuffer([]byte{})

	// write the hosts
	b.WriteString("{\"hosts\": [")
	for i, sn := range hc.SNodes {
		if i != 0 {
			b.WriteString(", ")
		}
		b.WriteString("\"" + sn.Name() + "\"")
	}
	b.WriteString("],")

	// write the tree structure
	b.WriteString("\"tree\": ")
	root := hc.SNodes[0]
	writeHC(b, hc, root)
	b.WriteString("}\n")

	// format the resulting JSON for readability
	bformatted := bytes.NewBuffer([]byte{})
	err := json.Indent(bformatted, b.Bytes(), "", "\t")
	if err != nil {
		fmt.Println(string(b.Bytes()))
		fmt.Println("ERROR: ", err)
	}

	return string(bformatted.Bytes())
}

func writeHC(b *bytes.Buffer, hc *HostConfig, p *SigningNode) {
	// Node{name, pubkey, x_hat, children}
	fmt.Fprint(b, "{\"name\":", "\""+p.Name()+"\",")
	fmt.Fprint(b, "\"prikey\":", "\""+string(hex.EncodeToString(p.privKey.Encode()))+"\",")
	fmt.Fprint(b, "\"pubkey\":", "\""+string(hex.EncodeToString(p.pubKey.Encode()))+"\",")

	// recursively format children
	fmt.Fprint(b, "\"children\":[")
	i := 0
	for n := range p.Children() {
		if i != 0 {
			b.WriteString(", ")
		}
		c := hc.Hosts[n]
		writeHC(b, hc, c)
		i++
	}
	fmt.Fprint(b, "]}")
}

// NewHostConfig creates a new host configuration that can be populated with
// hosts.
func NewHostConfig() *HostConfig {
	return &HostConfig{SNodes: make([]*SigningNode, 0), Hosts: make(map[string]*SigningNode), Dir: NewGoDirectory()}
}

type ConnType int

const (
	GoC ConnType = iota
	TcpC
)

// ConstructTree does a depth-first construction of the tree specified in the
// config file. ConstructTree must be call AFTER populating the HostConfig with
// ALL the possible hosts.
func ConstructTree(
	n Node,
	hc *HostConfig,
	parent string,
	suite abstract.Suite,
	rand cipher.Stream,
	hosts map[string]Host,
	nameToAddr map[string]string,
	opts ConfigOptions) (abstract.Point, error) {
	// passes up its X_hat, and/or an error

	// get the name associated with this address
	name, ok := nameToAddr[n.Name]
	if !ok {
		fmt.Println("unknown name in address book:", n.Name)
		return nil, errors.New("unknown name in address book")
	}

	// generate indicates whether we should generate the signing
	// node for this hostname
	generate := opts.Host == "" || opts.Host == name

	// check to make sure the this hostname is in the tree
	// it can be backed by a nil pointer
	h, ok := hosts[name]
	if !ok {
		fmt.Println("unknown host in tree:", name)
		return nil, errors.New("unknown host in tree")
	}

	var prikey abstract.Secret
	var pubkey abstract.Point
	var sn *SigningNode

	// if the JSON holds the fields field is set load from there
	if len(n.PubKey) != 0 {
		log.Println("decoding point")
		encoded, err := hex.DecodeString(string(n.PubKey))
		if err != nil {
			log.Print("failed to decode hex from encoded")
			return nil, err
		}
		pubkey = suite.Point()
		err = pubkey.Decode(encoded)
		if err != nil {
			log.Print("failed to decode point from hex")
			return nil, err
		}
		log.Println("decoding point")
		encoded, err = hex.DecodeString(string(n.PriKey))
		if err != nil {
			log.Print("failed to decode hex from encoded")
			return nil, err
		}
		prikey = suite.Secret()
		err = prikey.Decode(encoded)
		if err != nil {
			log.Print("failed to decode point from hex")
			return nil, err
		}
	}
	if generate {
		if prikey != nil {
			// if we have been given a private key load that
			hc.SNodes = append(hc.SNodes, NewKeyedSigningNode(h, suite, prikey))
		} else {
			// otherwise generate a random new one
			hc.SNodes = append(hc.SNodes, NewSigningNode(h, suite, rand))
		}
		sn = hc.SNodes[len(hc.SNodes)-1]
		hc.Hosts[name] = sn
		if prikey == nil {
			prikey = sn.privKey
			pubkey = sn.pubKey
		}
		// log.Println("pubkey:", sn.pubKey)
		// log.Println("given: ", pubkey)
	} else {
		log.Fatal("public keys have not been given and not generating")
	}
	// if the parent of this call is empty then this must be the root node
	if parent != "" && generate {
		h.AddParent(parent)
	}
	// log.Println("name: ", n.Name)
	// log.Println("prikey: ", prikey)
	// log.Println("pubkey: ", pubkey)
	x_hat := suite.Point().Null()
	x_hat.Add(x_hat, pubkey)
	// log.Println("x_hat: ", x_hat)
	for _, c := range n.Children {
		// connect this node to its children
		cname, ok := nameToAddr[c.Name]
		if !ok {
			fmt.Println("unknown name in address book:", n.Name)
			return nil, errors.New("unknown name in address book")
		}

		if generate {
			h.AddChildren(cname)
		}

		// recursively construct the children
		cpubkey, err := ConstructTree(c, hc, h.Name(), suite, rand, hosts, nameToAddr, opts)
		if err != nil {
			return nil, err
		}

		// if generating all csn will be availible
		// log.Print("adding from child: ", x_hat, cpubkey)
		x_hat.Add(x_hat, cpubkey)
	}
	if generate {
		sn.X_hat = x_hat
	}
	// log.Println("name: ", n.Name)
	// log.Println("final x_hat: ", x_hat)
	// log.Println("final pubkey: ", pubkey)
	return x_hat, nil
}

var ipv4Reg = regexp.MustCompile(`\d+\.\d+\.\d+\.\d+`)
var ipv4host = "NONE"

// getAddress gets the localhosts IPv4 address.
func GetAddress() (string, error) {
	name, err := os.Hostname()
	if err != nil {
		log.Print("Error Resolving Hostname:", err)
		return "", err
	}

	if ipv4host == "NONE" {
		as, err := net.LookupHost(name)
		if err != nil {
			return "", err
		}

		addr := ""

		for _, a := range as {
			log.Printf("a = %+v", a)
			if ipv4Reg.MatchString(a) {
				log.Print("matches")
				addr = a
			}
		}

		if addr == "" {
			err = errors.New("No IPv4 Address for Hostname")
		}
		return addr, err
	}
	return ipv4host, nil
}

var startConfigPort = 8089

type ConfigOptions struct {
	ConnType  string   // "go", tcp"
	Hostnames []string // if not nil replace hostnames with these
	GenHosts  bool     // if true generate random hostnames (all tcp)
	Host      string   // hostname to load into memory: "" for all
}

// TODO: if in tcp mode associate each hostname in the file with a different
// port. Get the remote address of this computer to combine with those for the
// complete hostnames to be used by the hosts.
func LoadJSON(file []byte, optsSlice ...ConfigOptions) (*HostConfig, error) {
	opts := ConfigOptions{}
	if len(optsSlice) > 0 {
		opts = optsSlice[0]
	}

	hc := NewHostConfig()
	var cf ConfigFile
	err := json.Unmarshal(file, &cf)
	if err != nil {
		return hc, err
	}

	connT := GoC
	if cf.Conn == "tcp" {
		connT = TcpC
	}

	// options override file
	if opts.ConnType == "tcp" {
		connT = TcpC
	}

	dir := NewGoDirectory()
	hosts := make(map[string]Host)
	nameToAddr := make(map[string]string)

	if connT == GoC {
		for _, h := range cf.Hosts {
			if _, ok := hc.Hosts[h]; !ok {
				nameToAddr[h] = h
				// it doesn't make sense to only make 1 go host
				hosts[h] = NewGoHost(h, dir)
			}
		}

	} else if connT == TcpC {
		localAddr := ""

		if opts.GenHosts {
			localAddr, err = GetAddress()
			if err != nil {
				return nil, err
			}
		}

		for _, h := range cf.Hosts {

			addr := h
			if opts.GenHosts {
				p := strconv.Itoa(startConfigPort)
				addr = localAddr + ":" + p
				//log.Println("created new host address: ", addr)
				startConfigPort++
			}

			nameToAddr[h] = addr
			// add to the hosts list if we havent added it before
			if _, ok := hc.Hosts[addr]; !ok {
				// only create the tcp hosts requested
				if opts.Host == "" || opts.Host == addr {
					hosts[addr] = NewTCPHost(addr)
				} else {
					hosts[addr] = nil // it is there but not backed
				}
			}
		}
	}
	suite := nist.NewAES128SHA256P256()
	rand := suite.Cipher([]byte("example"))
	_, err = ConstructTree(cf.Tree, hc, "", suite, rand, hosts, nameToAddr, opts)
	return hc, err
}

// run the given hostnames
func (hc *HostConfig) Run(hostnameSlice ...string) error {
	hostnames := make(map[string]*SigningNode)
	if hostnameSlice == nil {
		hostnames = hc.Hosts
	} else {

		for _, h := range hostnameSlice {
			sn, ok := hc.Hosts[h]
			if !ok {
				return errors.New("hostname given not in config file:" + h)
			}
			hostnames[h] = sn
		}
	}
	for _, sn := range hostnames {
		go func(sn *SigningNode) {
			// start listening for messages from within the tree
			sn.Host.Listen()
		}(sn)
	}

	for _, sn := range hostnames {
		var err error
		// exponential backoff for attempting to connect to parent
		startTime := time.Duration(200)
		maxTime := time.Duration(60000)
		for i := 0; i < 100; i++ {
			log.Println("attempting to connect to parent")
			err = sn.Connect()
			if err == nil {
				break
			}

			time.Sleep(startTime * time.Millisecond)
			startTime *= 2
			if startTime > maxTime {
				startTime = maxTime
			}
		}
		if err != nil {
			return errors.New("failed to connect")
		}
	}

	// need to make sure connections are setup properly first
	// wait for a little bit for connections to establish fully
	time.Sleep(1000 * time.Millisecond)
	for _, sn := range hostnames {
		go func(sn *SigningNode) {
			// start listening for messages from within the tree
			sn.Listen()
		}(sn)
	}
	return nil
}

// LoadConfig loads a configuration file in the format specified above. It
// populates a HostConfig with HostNode Hosts and goPeer Peers.
func LoadConfig(fname string, opts ...ConfigOptions) (*HostConfig, error) {
	file, err := ioutil.ReadFile(fname)
	if err != nil {
		return nil, err
	}
	return LoadJSON(file, opts...)
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor: Julien Vehent jvehent@mozilla.com [:ulfr]
package main

import (
	_ "mig/modules/agentdestroy"
	_ "mig/modules/file"
	_ "mig/modules/filechecker"
	_ "mig/modules/netstat"
	_ "mig/modules/upgrade"
)
<commit_msg>[minor] disable filechecker & upgrade modules by default<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor: Julien Vehent jvehent@mozilla.com [:ulfr]
package main

import (
	_ "mig/modules/agentdestroy"
	_ "mig/modules/file"
	//_ "mig/modules/filechecker"
	_ "mig/modules/netstat"
	//_ "mig/modules/upgrade"
)
<|endoftext|>


<commit_before>package main

import (
	cnt "github.com/orian/counters/global"
	"flag"
	"net/http"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	FLAG_signal := flag.Bool("signal", false, "handle SIGINT and SIGTERM")
	flag.Parse()
	if *FLAG_signal {
		sigs := make(chan os.Signal, 1)
		signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
		go func() {
			lastInt := time.Now()
			for sig := range sigs {
				fmt.Printf("Got signal: %s(%d)", sig, sig)
				fmt.Printf("I am: %d", os.Getpid())
				fmt.Printf(counters.String())
				l := time.Now()
				if sig == syscall.SIGTERM || l.Sub(lastInt).Seconds() < 1. {
					os.Exit(0)
				}
				lastInt = l
			}
		}()
	}

	cnt.GetCounter("start").Increment()
	http.Handle("/status", cnt.CreateHttpHandler())
	go func() {
		c := time.Tick(1 * time.Second)
		for range c {
			cnt.GetCounter("ticker").Increment()
		}
	}()
	cnt.GetMax("monist").Set(128)
	http.ListenAndServe(":8080", nil)
}
<commit_msg>fix typo<commit_after>package main

import (
	cnt "github.com/orian/counters/global"
	"flag"
	"net/http"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	FLAG_signal := flag.Bool("signal", false, "handle SIGINT and SIGTERM")
	flag.Parse()
	if *FLAG_signal {
		sigs := make(chan os.Signal, 1)
		signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
		go func() {
			lastInt := time.Now()
			for sig := range sigs {
				fmt.Printf("Got signal: %s(%d)", sig, sig)
				fmt.Printf("I am: %d", os.Getpid())
				fmt.Printf(cnt.String())
				l := time.Now()
				if sig == syscall.SIGTERM || l.Sub(lastInt).Seconds() < 1. {
					os.Exit(0)
				}
				lastInt = l
			}
		}()
	}

	cnt.GetCounter("start").Increment()
	http.Handle("/status", cnt.CreateHttpHandler())
	go func() {
		c := time.Tick(1 * time.Second)
		for range c {
			cnt.GetCounter("ticker").Increment()
		}
	}()
	cnt.GetMax("monist").Set(128)
	http.ListenAndServe(":8080", nil)
}
<|endoftext|>