<commit_before>package hb_test

import (
	"fmt"
	"log"

	"github.com/nstratos/go-hummingbird/hb"
)

func ExampleAnimeService_Get() {
	c := hb.NewClient(nil)

	anime, _, err := c.Anime.Get("nichijou", "english")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Title:", anime.Title)
	fmt.Println("Synopsis:", anime.Synopsis)
}

func ExampleAnimeService_Search() {
	c := hb.NewClient(nil)

	anime, _, err := c.Anime.Search("anohana")
	if err != nil {
		log.Fatal(err)
	}
	for i, a := range anime {
		fmt.Printf("--- Search result #%d ---\n", i+1)
		fmt.Printf("Title: %v\n", a.Title)
		fmt.Printf("Synopsis: %v\n\n", a.Synopsis)
	}
}

func ExampleUserService_Authenticate() {
	c := hb.NewClient(nil)

	token, _, err := c.User.Authenticate("", "USER_HUMMINGBIRD_EMAIL", "USER_HUMMINGBIRD_PASSWORD")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("user auth token:", token)
}

func ExampleUserService_Get() {
	c := hb.NewClient(nil)

	u, _, err := c.User.Get("cybrox")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Name:", u.Name)
	fmt.Println("About:", u.About)
}

func ExampleUserService_FavoriteAnime() {
	c := hb.NewClient(nil)

	anime, _, err := c.User.FavoriteAnime("cybrox")
	if err != nil {
		log.Fatal(err)
	}
	for i, a := range anime {
		fmt.Printf("--- Favorite anime #%d ---\n", i+1)
		fmt.Println("Title:", a.Title)
		fmt.Println("Synopsis:", a.Synopsis)
	}
}

func ExampleUserService_Library() {
	c := hb.NewClient(nil)

	entries, _, err := c.User.Library("cybrox", hb.StatusCurrentlyWatching)
	if err != nil {
		log.Fatal(err)
	}
	for i, e := range entries {
		fmt.Printf("--- Library entry #%d ---\n", i+1)
		fmt.Printf("Anime Title: %v\n", e.Anime.Title)
		fmt.Printf("Episodes watched: %v\n\n", e.EpisodesWatched)
	}
}

func ExampleUserService_Library_getAllStatuses() {
	c := hb.NewClient(nil)

	entries, _, err := c.User.Library("cybrox", "")
	if err != nil {
		log.Fatal(err)
	}
	for i, e := range entries {
		fmt.Printf("--- Library entry #%d ---\n", i+1)
		fmt.Printf("Anime Title: %v\n", e.Anime.Title)
		fmt.Printf("Episodes watched: %v\n\n", e.EpisodesWatched)
	}
}

func ExampleUserService_Feed() {
	c := hb.NewClient(nil)

	stories, _, err := c.User.Feed("cybrox")
	if err != nil {
		log.Fatal(err)
	}
	for _, s := range stories {
		if s.StoryType == "comment" {
			for _, ss := range s.Substories {
				if ss.SubstoryType == "comment" {
					fmt.Printf("%v said to %v:\n", s.Poster.Name, s.User.Name)
					fmt.Printf("%v\n\n", ss.Comment)
				}
			}
		}
	}
}

func ExampleLibraryService_Update() {
	c := hb.NewClient(nil)

	// Aquire user's authentication token.
	token, _, err := c.User.Authenticate("USER_HUMMINGBIRD_USERNAME", "", "USER_HUMMINGBIRD_PASSWORD")
	if err != nil {
		log.Fatalf("token err = %v", err)
	}

	// Add nichijou to the user's library (Status currently watching is added by default).
	c.Library.Update("nichijou", token, nil)

	// Update nichijou increasing episodes watched by one
	c.Library.Update("nichijou", token, &hb.Entry{IncrementEpisodes: true})

	// Update nichijou setting status as on-hold
	c.Library.Update("nichijou", token, &hb.Entry{Status: hb.StatusOnHold})

	// Update nichijou setting status as currently-watching and number of episodes watched as 5.
	c.Library.Update("nichijou", token, &hb.Entry{Status: hb.StatusCurrentlyWatching, EpisodesWatched: 5})

	// Update nichijou setting status as completed and setting a note.
	c.Library.Update("nichijou", token, &hb.Entry{Status: hb.StatusCompleted, Notes: "crazy"})

}

func ExampleLibraryService_Remove() {
	c := hb.NewClient(nil)

	// Aquire user's authentication token.
	token, _, err := c.User.Authenticate("USER_HUMMINGBIRD_USERNAME", "", "USER_HUMMINGBIRD_PASSWORD")
	if err != nil {
		log.Fatalf("token err = %v", err)
	}

	removed, _, err := c.Library.Remove("nichijou", token)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Anime was removed:", removed)
}
<commit_msg>Fix typo<commit_after>package hb_test

import (
	"fmt"
	"log"

	"github.com/nstratos/go-hummingbird/hb"
)

func ExampleAnimeService_Get() {
	c := hb.NewClient(nil)

	anime, _, err := c.Anime.Get("nichijou", "english")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Title:", anime.Title)
	fmt.Println("Synopsis:", anime.Synopsis)
}

func ExampleAnimeService_Search() {
	c := hb.NewClient(nil)

	anime, _, err := c.Anime.Search("anohana")
	if err != nil {
		log.Fatal(err)
	}
	for i, a := range anime {
		fmt.Printf("--- Search result #%d ---\n", i+1)
		fmt.Printf("Title: %v\n", a.Title)
		fmt.Printf("Synopsis: %v\n\n", a.Synopsis)
	}
}

func ExampleUserService_Authenticate() {
	c := hb.NewClient(nil)

	token, _, err := c.User.Authenticate("", "USER_HUMMINGBIRD_EMAIL", "USER_HUMMINGBIRD_PASSWORD")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("user auth token:", token)
}

func ExampleUserService_Get() {
	c := hb.NewClient(nil)

	u, _, err := c.User.Get("cybrox")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Name:", u.Name)
	fmt.Println("About:", u.About)
}

func ExampleUserService_FavoriteAnime() {
	c := hb.NewClient(nil)

	anime, _, err := c.User.FavoriteAnime("cybrox")
	if err != nil {
		log.Fatal(err)
	}
	for i, a := range anime {
		fmt.Printf("--- Favorite anime #%d ---\n", i+1)
		fmt.Println("Title:", a.Title)
		fmt.Println("Synopsis:", a.Synopsis)
	}
}

func ExampleUserService_Library() {
	c := hb.NewClient(nil)

	entries, _, err := c.User.Library("cybrox", hb.StatusCurrentlyWatching)
	if err != nil {
		log.Fatal(err)
	}
	for i, e := range entries {
		fmt.Printf("--- Library entry #%d ---\n", i+1)
		fmt.Printf("Anime Title: %v\n", e.Anime.Title)
		fmt.Printf("Episodes watched: %v\n\n", e.EpisodesWatched)
	}
}

func ExampleUserService_Library_getAllStatuses() {
	c := hb.NewClient(nil)

	entries, _, err := c.User.Library("cybrox", "")
	if err != nil {
		log.Fatal(err)
	}
	for i, e := range entries {
		fmt.Printf("--- Library entry #%d ---\n", i+1)
		fmt.Printf("Anime Title: %v\n", e.Anime.Title)
		fmt.Printf("Episodes watched: %v\n\n", e.EpisodesWatched)
	}
}

func ExampleUserService_Feed() {
	c := hb.NewClient(nil)

	stories, _, err := c.User.Feed("cybrox")
	if err != nil {
		log.Fatal(err)
	}
	for _, s := range stories {
		if s.StoryType == "comment" {
			for _, ss := range s.Substories {
				if ss.SubstoryType == "comment" {
					fmt.Printf("%v said to %v:\n", s.Poster.Name, s.User.Name)
					fmt.Printf("%v\n\n", ss.Comment)
				}
			}
		}
	}
}

func ExampleLibraryService_Update() {
	c := hb.NewClient(nil)

	// Acquire user's authentication token.
	token, _, err := c.User.Authenticate("USER_HUMMINGBIRD_USERNAME", "", "USER_HUMMINGBIRD_PASSWORD")
	if err != nil {
		log.Fatalf("token err = %v", err)
	}

	// Add nichijou to the user's library (Status currently watching is added by default).
	c.Library.Update("nichijou", token, nil)

	// Update nichijou increasing episodes watched by one
	c.Library.Update("nichijou", token, &hb.Entry{IncrementEpisodes: true})

	// Update nichijou setting status as on-hold
	c.Library.Update("nichijou", token, &hb.Entry{Status: hb.StatusOnHold})

	// Update nichijou setting status as currently-watching and number of episodes watched as 5.
	c.Library.Update("nichijou", token, &hb.Entry{Status: hb.StatusCurrentlyWatching, EpisodesWatched: 5})

	// Update nichijou setting status as completed and setting a note.
	c.Library.Update("nichijou", token, &hb.Entry{Status: hb.StatusCompleted, Notes: "crazy"})

}

func ExampleLibraryService_Remove() {
	c := hb.NewClient(nil)

	// Acquire user's authentication token.
	token, _, err := c.User.Authenticate("USER_HUMMINGBIRD_USERNAME", "", "USER_HUMMINGBIRD_PASSWORD")
	if err != nil {
		log.Fatalf("token err = %v", err)
	}

	removed, _, err := c.Library.Remove("nichijou", token)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Anime was removed:", removed)
}
<|endoftext|>


<commit_before>package platform

import (
	"fmt"
	"os"
	"os/exec"
	"regexp"
	"runtime"
	"strings"
)

type Platform struct{}

const name = "platform"

func (self *Platform) Name() string {
	return name
}

func (self *Platform) Collect() (result interface{}, err error) {
	result, err = getPlatformInfo()
	return
}

func getPlatformInfo() (platformInfo map[string]interface{}, err error) {
	platformInfo = make(map[string]interface{})

	hostname, err := os.Hostname()
	if err != nil {
		return platformInfo, err
	}
	platformInfo["hostname"] = hostname

	platformInfo["os"] = runtime.GOOS
	platformInfo["goV"] = strings.Replace(runtime.Version(), "go", "", -1)
	pythonV, err := getPythonVersion()
	if err != nil {
		return platformInfo, err
	}
	platformInfo["pythonV"] = pythonV

	return
}

func getPythonVersion() (string, error) {
	out, err := exec.Command("python", "-V").CombinedOutput()
	if err != nil {
		return "", err
	}
	version := fmt.Sprintf("%s", out)
	values := regexp.MustCompile("Python (.*)\n").FindStringSubmatch(version)
	return values[1], nil
}
<commit_msg>Add arch info to system collector<commit_after>package platform

import (
	"fmt"
	"os/exec"
	"regexp"
	"runtime"
	"strings"
)

type Platform struct{}

const name = "platform"

func (self *Platform) Name() string {
	return name
}

func (self *Platform) Collect() (result interface{}, err error) {
	result, err = getPlatformInfo()
	return
}

func getPlatformInfo() (platformInfo map[string]interface{}, err error) {

	platformInfo, err = getArchInfo()
	if err != nil {
		return platformInfo, err
	}

	platformInfo["goV"] = strings.Replace(runtime.Version(), "go", "", -1)
	pythonV, err := getPythonVersion()
	if err != nil {
		return platformInfo, err
	}
	platformInfo["pythonV"] = pythonV

	return
}

func getArchInfo() (archInfo map[string]interface{}, err error) {
	archInfo = make(map[string]interface{})

	out, err := exec.Command("uname", "-s", "-n", "-r", "-m", "-p", "-i", "-o").Output()
	if err != nil {
		return nil, err
	}
	line := fmt.Sprintf("%s", out)
	values := regexp.MustCompile(" +").Split(line, 7)
	archInfo["kernel_name"] = values[0]
	archInfo["hostname"] = values[1]
	archInfo["kernel_release"] = values[2]
    archInfo["machine"] = values[3]
    archInfo["processor"] = values[4]
    archInfo["hardware_platform"] = values[5]
    archInfo["os"] = strings.Replace(values[6], "\n", "", -1)

    out, err = exec.Command("uname", "-v").Output()
    if err != nil {
        return nil, err
    }
    archInfo["kernel_version"] = strings.Replace(fmt.Sprintf("%s", out), "\n", "", -1)

	return
}

func getPythonVersion() (string, error) {
	out, err := exec.Command("python", "-V").CombinedOutput()
	if err != nil {
		return "", err
	}
	version := fmt.Sprintf("%s", out)
	values := regexp.MustCompile("Python (.*)\n").FindStringSubmatch(version)
	return values[1], nil
}
<|endoftext|>


<commit_before>package core

import (
	"container/list"
	"fmt"

	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethdb"
	"github.com/ethereum/go-ethereum/ethutil"
	"github.com/ethereum/go-ethereum/event"
)

// Implement our EthTest Manager
type TestManager struct {
	// stateManager *StateManager
	eventMux *event.TypeMux

	db         ethutil.Database
	txPool     *TxPool
	blockChain *ChainManager
	Blocks     []*types.Block
}

func (s *TestManager) IsListening() bool {
	return false
}

func (s *TestManager) IsMining() bool {
	return false
}

func (s *TestManager) PeerCount() int {
	return 0
}

func (s *TestManager) Peers() *list.List {
	return list.New()
}

func (s *TestManager) ChainManager() *ChainManager {
	return s.blockChain
}

func (tm *TestManager) TxPool() *TxPool {
	return tm.txPool
}

// func (tm *TestManager) StateManager() *StateManager {
// 	return tm.stateManager
// }

func (tm *TestManager) EventMux() *event.TypeMux {
	return tm.eventMux
}
func (tm *TestManager) KeyManager() *crypto.KeyManager {
	return nil
}

func (tm *TestManager) Db() ethutil.Database {
	return tm.db
}

func NewTestManager() *TestManager {
	db, err := ethdb.NewMemDatabase()
	if err != nil {
		fmt.Println("Could not create mem-db, failing")
		return nil
	}

	testManager := &TestManager{}
	testManager.eventMux = new(event.TypeMux)
	testManager.db = db
	// testManager.txPool = NewTxPool(testManager)
	// testManager.blockChain = NewChainManager(testManager)
	// testManager.stateManager = NewStateManager(testManager)

	// Start the tx pool
	testManager.txPool.Start()

	return testManager
}
<commit_msg>Comment out broken test (return type does not exist)<commit_after>package core

import (
	"container/list"
	"fmt"

	"github.com/ethereum/go-ethereum/core/types"
	// "github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethdb"
	"github.com/ethereum/go-ethereum/ethutil"
	"github.com/ethereum/go-ethereum/event"
)

// Implement our EthTest Manager
type TestManager struct {
	// stateManager *StateManager
	eventMux *event.TypeMux

	db         ethutil.Database
	txPool     *TxPool
	blockChain *ChainManager
	Blocks     []*types.Block
}

func (s *TestManager) IsListening() bool {
	return false
}

func (s *TestManager) IsMining() bool {
	return false
}

func (s *TestManager) PeerCount() int {
	return 0
}

func (s *TestManager) Peers() *list.List {
	return list.New()
}

func (s *TestManager) ChainManager() *ChainManager {
	return s.blockChain
}

func (tm *TestManager) TxPool() *TxPool {
	return tm.txPool
}

// func (tm *TestManager) StateManager() *StateManager {
// 	return tm.stateManager
// }

func (tm *TestManager) EventMux() *event.TypeMux {
	return tm.eventMux
}

// func (tm *TestManager) KeyManager() *crypto.KeyManager {
// 	return nil
// }

func (tm *TestManager) Db() ethutil.Database {
	return tm.db
}

func NewTestManager() *TestManager {
	db, err := ethdb.NewMemDatabase()
	if err != nil {
		fmt.Println("Could not create mem-db, failing")
		return nil
	}

	testManager := &TestManager{}
	testManager.eventMux = new(event.TypeMux)
	testManager.db = db
	// testManager.txPool = NewTxPool(testManager)
	// testManager.blockChain = NewChainManager(testManager)
	// testManager.stateManager = NewStateManager(testManager)

	// Start the tx pool
	testManager.txPool.Start()

	return testManager
}
<|endoftext|>


<commit_before>package reference

import (
	"fmt"
	"io"
	"strconv"
	"strings"
)

// symbolicRefPathStmt parse a following statement master~2
// to split branch name and refrence path
type symbolicRefPathStmt struct {
	branchName string
	refPath    []int
}

// parser represents a parser.
type parser struct {
	s   *scanner
	buf struct {
		tok token
		lit string
		n   int
	}
}

// newParser returns a new instance of parser.
func newParser(r io.Reader) *parser {
	return &parser{s: newScanner(r)}
}

// ParseSymbolicReferencePath creates a symbolicRefPathStmt
func (p *parser) parseSymbolicReferencePath() (*symbolicRefPathStmt, error) {
	branchName, err := p.parseBranchName()

	if err != nil {
		return nil, err
	}

	refPath, err := p.parseRefPath()

	if err != nil {
		return nil, err
	}

	return &symbolicRefPathStmt{
		branchName: branchName,
		refPath:    refPath,
	}, nil
}

// parseFuncArg parse one function argument
func (p *parser) parseBranchName() (string, error) {
	var tok token
	var previousTok token
	var lit string
	var buf string
	var subBuf string

	for {
		tok, lit = p.scan()

		if tok == dot && buf == "" {
			return "", fmt.Errorf("branch name must not start with a dot")
		}

		if tok == colon {
			return "", fmt.Errorf("branch name must not contains any colon")
		}

		if tok == slash {
			return "", fmt.Errorf("branch name must not end with a slash")
		}

		if tok == dot && previousTok == dot {
			return "", fmt.Errorf("branch name must not contains any double dot")
		}

		if tok == space {
			return "", fmt.Errorf("branch name contains a space character")
		}

		if tok == control {
			return "", fmt.Errorf("branch name contains a control character")
		}

		if len(buf) > 4 {
			subBuf = strings.ToLower(buf[len(buf)-5:])
		}

		if (tok == tilde || tok == caret || tok == eof) && subBuf == ".lock" {
			return "", fmt.Errorf("branch name cannot end with .lock")
		}

		if tok == tilde || tok == caret {
			p.unscan()

			return buf, nil
		}

		if tok == eof {
			return buf, nil
		}

		buf += lit
		previousTok = tok
	}
}

func (p *parser) parseRefPath() ([]int, error) {
	var tok token
	var buf = []int{}

	for {
		tok, _ = p.scan()

		if tok == caret {
			nTok, nLit := p.scan()

			if nTok != number {
				p.unscan()
				buf = append(buf, 1)
				continue
			}

			level, err := strconv.Atoi(nLit)

			if err != nil {
				return buf, err
			}

			if level != 2 && level != 1 {
				return buf, fmt.Errorf("level associated to a caret must be 1 or 2")
			}

			buf = append(buf, level)
		}

		if tok == tilde {
			nTok, nLit := p.scan()

			if nTok != number {
				p.unscan()
				buf = append(buf, 1)
				continue
			}

			level, err := strconv.Atoi(nLit)

			if err != nil {
				return buf, err
			}

			for i := 0; i < level; i++ {
				buf = append(buf, 1)
			}
		}

		if tok == eof {
			return buf, nil
		}

		if tok != caret && tok != tilde {
			return buf, fmt.Errorf("must be a caret or a tilde and may be followed with a number")
		}
	}
}

// scan returns the next token from the underlying scanner.
// If a token has been unscanned then read that instead.
func (p *parser) scan() (tok token, lit string) {
	if p.buf.n != 0 {
		p.buf.n = 0
		return p.buf.tok, p.buf.lit
	}

	tok, lit = p.s.scan()

	p.buf.tok, p.buf.lit = tok, lit
	return
}

// unscan pushes the previously read token back onto the buffer.
func (p *parser) unscan() { p.buf.n = 1 }
<commit_msg>ref(reference) : decrease cyclo complexity<commit_after>package reference

import (
	"fmt"
	"io"
	"strconv"
	"strings"
)

// symbolicRefPathStmt parse a following statement master~2
// to split branch name and refrence path
type symbolicRefPathStmt struct {
	branchName string
	refPath    []int
}

// parser represents a parser.
type parser struct {
	s   *scanner
	buf struct {
		tok token
		lit string
		n   int
	}
}

// newParser returns a new instance of parser.
func newParser(r io.Reader) *parser {
	return &parser{s: newScanner(r)}
}

// ParseSymbolicReferencePath creates a symbolicRefPathStmt
func (p *parser) parseSymbolicReferencePath() (*symbolicRefPathStmt, error) {
	branchName, err := p.parseBranchName()

	if err != nil {
		return nil, err
	}

	refPath, err := p.parseRefPath()

	if err != nil {
		return nil, err
	}

	return &symbolicRefPathStmt{
		branchName: branchName,
		refPath:    refPath,
	}, nil
}

// parseFuncArg parse one function argument
func (p *parser) parseBranchName() (string, error) {
	var tok token
	var previousTok token
	var lit string
	var buf string
	var subBuf string

	for {
		tok, lit = p.scan()

		err := p.checkBranchNameToken(tok)

		if err != nil {
			return "", err
		}

		if len(buf) > 4 {
			subBuf = strings.ToLower(buf[len(buf)-5:])
		}

		err = p.checkBranchNameConditions(tok, previousTok, buf, subBuf)

		if err != nil {
			return "", err
		}

		switch tok {
		case tilde, caret:
			p.unscan()
			return buf, nil
		case eof:
			return buf, nil
		}

		buf += lit
		previousTok = tok
	}
}

func (p *parser) checkBranchNameToken(tok token) error {
	switch tok {
	case colon:
		return fmt.Errorf("branch name must not contains any colon")
	case slash:
		return fmt.Errorf("branch name must not end with a slash")
	case space:
		return fmt.Errorf("branch name contains a space character")
	case control:
		return fmt.Errorf("branch name contains a control character")
	}

	return nil
}

func (p *parser) checkBranchNameConditions(currentToken token, previousToken token, currentBuf string, subBuf string) error {
	if currentToken == dot && currentBuf == "" {
		return fmt.Errorf("branch name must not start with a dot")
	}

	if currentToken == dot && previousToken == dot {
		return fmt.Errorf("branch name must not contains any double dot")
	}

	if (currentToken == tilde || currentToken == caret || currentToken == eof) && subBuf == ".lock" {
		return fmt.Errorf("branch name cannot end with .lock")
	}

	return nil
}

func (p *parser) parseRefPath() ([]int, error) {
	var tok token
	var buf = []int{}

	for {
		tok, _ = p.scan()

		if tok == caret {
			err := p.parseCaretLevel(&buf)

			if err != nil {
				return nil, err
			}
		}

		if tok == tilde {
			err := p.parseTildeLevel(&buf)

			if err != nil {
				return nil, err
			}
		}

		if tok == eof {
			return buf, nil
		}

		if tok != caret && tok != tilde {
			return buf, fmt.Errorf("must be a caret or a tilde and may be followed with a number")
		}
	}
}

func (p *parser) parseCaretLevel(buf *[]int) error {
	nTok, nLit := p.scan()

	if nTok != number {
		p.unscan()
		*buf = append(*buf, 1)
		return nil
	}

	level, err := strconv.Atoi(nLit)

	if err != nil {
		return err
	}

	if level != 2 && level != 1 {
		return fmt.Errorf("level associated to a caret must be 1 or 2")
	}

	*buf = append(*buf, level)

	return nil
}

func (p *parser) parseTildeLevel(buf *[]int) error {
	nTok, nLit := p.scan()

	if nTok != number {
		p.unscan()
		*buf = append(*buf, 1)
		return nil
	}

	level, err := strconv.Atoi(nLit)

	if err != nil {
		return err
	}

	for i := 0; i < level; i++ {
		*buf = append(*buf, 1)
	}

	return nil
}

// scan returns the next token from the underlying scanner.
// If a token has been unscanned then read that instead.
func (p *parser) scan() (tok token, lit string) {
	if p.buf.n != 0 {
		p.buf.n = 0
		return p.buf.tok, p.buf.lit
	}

	tok, lit = p.s.scan()

	p.buf.tok, p.buf.lit = tok, lit
	return
}

// unscan pushes the previously read token back onto the buffer.
func (p *parser) unscan() { p.buf.n = 1 }
<|endoftext|>


<commit_before>package commands

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

	"github.com/phase2/rig/cli/commands/project"
	"github.com/phase2/rig/cli/util"
	"github.com/urfave/cli"
)

type Project struct {
	BaseCommand
}

func (cmd *Project) Commands() cli.Command {
	project.ConfigInit()
	command := cli.Command{
		Name:        "project",
		Usage:       "Run a project script from configuration.",
		Description: "Configure scripts representing core operations of the project in a Rig configuration file.\n\n\tThis Yaml file by default is ./.outrigger.yml. It can be overridden by setting an environment variable $RIG_PROJECT_CONFIG_FILE.",
		Category:    "Development",
		Before:      cmd.Before,
		Subcommands: cmd.GetScriptsAsSubcommands(project.GetConfigPath()),
	}

	return command
}

// Processes script configuration into formal subcommands.
func (cmd *Project) GetScriptsAsSubcommands(filename string) []cli.Command {
	var scripts = cmd.GetProjectScripts(filename)

	var commands = []cli.Command{}
	for id, script := range scripts {
		if len(script.Run) > 0 {
			command := cli.Command{
				Name:        id,
				Usage:       script.Description,
				Description: fmt.Sprintf("%s\n\n\tThis command was configured in %s\n\n\tThere are %d steps in this script and any 'extra' arguments will be appended to the final step.", script.Description, filename, len(script.Run)),
				ArgsUsage:   "<args passed to last step>",
				Before:      cmd.Before,
				Action:      cmd.Run,
			}

			if len(script.Alias) > 0 {
				command.Aliases = []string{script.Alias}
			}

			commands = append(commands, command)
		}
	}

	return commands
}

// Return the help for all the scripts.
func (cmd *Project) Run(c *cli.Context) error {
	var scripts = cmd.GetProjectScripts(project.GetConfigPath())

	key := c.Command.Name
	if script, ok := scripts[key]; ok {
		cmd.out.Verbose.Printf("Executing '%s' for '%s'", key, script.Description)
		cmd.addCommandPath(project.GetConfigPath())
		dir := filepath.Dir(project.GetConfigPath())
		for step, val := range script.Run {
			cmd.out.Verbose.Printf("Step %d: Executing '%s' as '%s'", step+1, key, val)
			// If this is the last step, append any further args to the end of the command.
			if len(script.Run) == step+1 {
				val = val + " " + strings.Join(c.Args(), " ")
			}
			shellCmd := cmd.GetCommand(val)
			shellCmd.Dir = dir

			if _, stderr, exitCode := util.PassthruCommand(shellCmd); exitCode != 0 {
				cmd.out.Error.Printf("Error running project script '%s' on step %d: %s", key, step+1, stderr)
				os.Exit(exitCode)
			}
		}
	} else {
		util.Logger().Error.Printf("Unrecognized script '%s'", key)
	}

	return nil
}

// Construct a command to execute a configured script.
// @see https://github.com/medhoover/gom/blob/staging/config/command.go
func (cmd *Project) GetCommand(val string) *exec.Cmd {
	var (
		sysShell      = "sh"
		sysCommandArg = "-c"
	)
	if runtime.GOOS == "windows" {
		sysShell = "cmd"
		sysCommandArg = "/c"
	}

	return exec.Command(sysShell, sysCommandArg, val)
}

// Load the scripts from the project-specific configuration.
func (cmd *Project) GetProjectScripts(filename string) map[string]*project.ProjectScript {
	scripts := project.GetProjectConfigFromFile(filename).Scripts
	// We can hard-wire scripts here by assigning: scripts["name"] = &project.ProjectScript{}

	return scripts
}

// Override the PATH environment variable for further shell executions.
// This is used on POSIX systems for lookup of scripts.
func (cmd *Project) addCommandPath(filename string) error {
	binDir := project.GetProjectConfigFromFile(filename).Bin
	cmd.out.Verbose.Printf("Adding '%s' to the PATH for script execution.", binDir)
	path := os.Getenv("PATH")
	os.Setenv("PATH", fmt.Sprintf("%s:%s", path, binDir))

	return nil
}
<commit_msg>parsing compose files for volumes that are external and end in -sync<commit_after>package commands

import (
	"fmt"
  "io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"

  "github.com/phase2/rig/cli/commands/project"
	"github.com/phase2/rig/cli/util"
	"github.com/urfave/cli"
  "gopkg.in/yaml.v2"
)

type Project struct {
	BaseCommand
}

func (cmd *Project) Commands() cli.Command {
	project.ConfigInit()
	command := cli.Command{
		Name:        "project",
		Usage:       "Run a project script from configuration.",
		Description: "Configure scripts representing core operations of the project in a Rig configuration file.\n\n\tThis Yaml file by default is ./.outrigger.yml. It can be overridden by setting an environment variable $RIG_PROJECT_CONFIG_FILE.",
		Category:    "Development",
		Before:      cmd.Before,
		Subcommands: cmd.GetScriptsAsSubcommands(project.GetConfigPath()),
	}

	syncStart := cli.Command{
		Name:        "sync:start",
		Usage:       "Start a unison sync on local project directory",
		Before:      cmd.Before,
		Action:      cmd.RunSyncStart,
	}

	command.Subcommands = append(command.Subcommands, syncStart)

	return command
}

// Processes script configuration into formal subcommands.
func (cmd *Project) GetScriptsAsSubcommands(filename string) []cli.Command {
	var scripts = cmd.GetProjectScripts(filename)

	var commands = []cli.Command{}
	for id, script := range scripts {
		if len(script.Run) > 0 {
			command := cli.Command{
				Name:        id,
				Usage:       script.Description,
				Description: fmt.Sprintf("%s\n\n\tThis command was configured in %s\n\n\tThere are %d steps in this script and any 'extra' arguments will be appended to the final step.", script.Description, filename, len(script.Run)),
				ArgsUsage:   "<args passed to last step>",
				Before:      cmd.Before,
				Action:      cmd.Run,
			}

			if len(script.Alias) > 0 {
				command.Aliases = []string{script.Alias}
			}

			commands = append(commands, command)
		}
	}

	return commands
}

// Return the help for all the scripts.
func (cmd *Project) Run(c *cli.Context) error {
	var scripts = cmd.GetProjectScripts(project.GetConfigPath())

	key := c.Command.Name
	if script, ok := scripts[key]; ok {
		cmd.out.Verbose.Printf("Executing '%s' for '%s'", key, script.Description)
		cmd.addCommandPath(project.GetConfigPath())
		dir := filepath.Dir(project.GetConfigPath())
		for step, val := range script.Run {
			cmd.out.Verbose.Printf("Step %d: Executing '%s' as '%s'", step+1, key, val)
			// If this is the last step, append any further args to the end of the command.
			if len(script.Run) == step+1 {
				val = val + " " + strings.Join(c.Args(), " ")
			}
			shellCmd := cmd.GetCommand(val)
			shellCmd.Dir = dir

			if _, stderr, exitCode := util.PassthruCommand(shellCmd); exitCode != 0 {
				cmd.out.Error.Printf("Error running project script '%s' on step %d: %s", key, step+1, stderr)
				os.Exit(exitCode)
			}
		}
	} else {
		util.Logger().Error.Printf("Unrecognized script '%s'", key)
	}

	return nil
}

// Construct a command to execute a configured script.
// @see https://github.com/medhoover/gom/blob/staging/config/command.go
func (cmd *Project) GetCommand(val string) *exec.Cmd {
	var (
		sysShell      = "sh"
		sysCommandArg = "-c"
	)
	if runtime.GOOS == "windows" {
		sysShell = "cmd"
		sysCommandArg = "/c"
	}

	return exec.Command(sysShell, sysCommandArg, val)
}

// Load the scripts from the project-specific configuration.
func (cmd *Project) GetProjectScripts(filename string) map[string]*project.ProjectScript {
	scripts := project.GetProjectConfigFromFile(filename).Scripts
	// We can hard-wire scripts here by assigning: scripts["name"] = &project.ProjectScript{}

	return scripts
}

// Override the PATH environment variable for further shell executions.
// This is used on POSIX systems for lookup of scripts.
func (cmd *Project) addCommandPath(filename string) error {
	binDir := project.GetProjectConfigFromFile(filename).Bin
	cmd.out.Verbose.Printf("Adding '%s' to the PATH for script execution.", binDir)
	path := os.Getenv("PATH")
	os.Setenv("PATH", fmt.Sprintf("%s:%s", path, binDir))

	return nil
}

// Start the unison sync process
func (cmd *Project) RunSyncStart(c *cli.Context) error {
  project.ConfigInit();
  //config := project.GetProjectConfigFromFile(project.GetConfigPath())

  volume := cmd.GetVolumeName()
  cmd.out.Info.Printf("Volume name: %s", volume)
	return nil
}

func (cmd *Project) GetVolumeName() string {
  // 1. Check for argument
  // 2. Check for config
  // 3. Parse compose file looking for an external volume named *-sync
  if composeConfig, err := cmd.LoadComposeFile(); err == nil {
    for name, volume := range composeConfig.Volumes {
      cmd.out.Info.Printf("Name: %s", name);
      cmd.out.Info.Printf("External: %t", volume.External);
      if strings.HasSuffix(name, "-sync") && volume.External{
        return name
      }
    }
  }

  // 4. Use local dir for the volume name
  cmd.out.Error.Fatal("Use local dir name for volume")
  return ""
}

type ComposeFile struct {
  Volumes map[string]Volume
}

type Volume struct {
  External bool
}

// Load the proper compose file
func (cmd *Project) LoadComposeFile() (*ComposeFile, error) {
  yamlFile, err := ioutil.ReadFile("./docker-compose.yml")

  if err == nil {
    var config ComposeFile
    if err := yaml.Unmarshal(yamlFile, &config); err != nil {
      cmd.out.Error.Fatalf("YAML Parsing Error: %s", err)
    }
    return &config, nil
  }

  return nil, err
}

<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"time"

	"github.com/privacylab/talek/common"
	"github.com/privacylab/talek/libtalek"
)

var config = flag.String("config", "talek.conf", "Client configuration for talek")
var create = flag.Bool("create", false, "Create a new talek handle")
var share = flag.String("share", "", "Create a read-only version of the topic for sharing")
var handle = flag.String("topic", "talek.handle", "The talek handle to use")
var write = flag.String("write", "", "A message to append to the log (If not specified, the next item will be read.)")
var read = flag.Bool("read", false, "Read from the provided topic")
var verbose = flag.Bool("verbose", false, "Print diagnostic information")

// The CLI client will read or write a single item for talek
func main() {
	flag.Parse()

	// Config
	config := libtalek.ClientConfigFromFile(*config)
	if config.Config == nil && *verbose {
		fmt.Fprintln(os.Stderr, "Common configuration will be fetched from frontend.")
	}

	topicdata, err := ioutil.ReadFile(*handle)
	if err != nil {
		panic(err)
	}
	topic := libtalek.Topic{}
	if *create {
		nt, newerr := libtalek.NewTopic()
		if newerr != nil {
			panic(err)
		}
		topic = *nt
	} else {
		if err = json.Unmarshal(topicdata, &topic); err != nil {
			panic(err)
		}
	}

	if len(*share) > 0 {
		handle := topic.Handle
		handleBytes, handleerr := json.Marshal(handle)
		if handleerr != nil {
			panic(handleerr)
		}
		ioutil.WriteFile(*share, handleBytes, 0640)
		fmt.Fprintf(os.Stderr, "Read-only topic written to %s\n", *share)
	}

	// Client-connected activity below.
	leaderRPC := common.NewFrontendRPC("RPC", config.FrontendAddr)

	client := libtalek.NewClient("Client", *config, leaderRPC)
	if client == nil {
		panic("could not create talek client")
	} else if *verbose {
		fmt.Fprintln(os.Stderr, "Connection to RPC established.")
	}

	if *read == false && len(*write) > 0 {
		if err = client.Publish(&topic, []byte(*write)); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to publish: %s", err)
			panic(err)
		}
	} else if *read == false {
		fmt.Fprintf(os.Stderr, "No Read or Write operation requested. Closing.")
	} else {
		msgs := client.Poll(&topic.Handle)
		timeout := time.After(config.ReadInterval * 5)
		select {
		case next := <-msgs:
			fmt.Println(next)
			break
		case <-timeout:
			if *verbose {
				fmt.Fprintln(os.Stderr, "Timed out waiting for new message.")
			}
			return
		}
		client.Done(&topic.Handle)
	}
	updatedTopic, err := json.Marshal(topic)
	if err != nil {
		panic(err)
	}
	if err = ioutil.WriteFile(*handle, updatedTopic, 0600); err != nil {
		panic(err)
	}
}
<commit_msg>add an error when no config passed<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"time"

	"github.com/privacylab/talek/common"
	"github.com/privacylab/talek/libtalek"
)

var config = flag.String("config", "talek.conf", "Client configuration for talek")
var create = flag.Bool("create", false, "Create a new talek handle")
var share = flag.String("share", "", "Create a read-only version of the topic for sharing")
var handle = flag.String("topic", "talek.handle", "The talek handle to use")
var write = flag.String("write", "", "A message to append to the log (If not specified, the next item will be read.)")
var read = flag.Bool("read", false, "Read from the provided topic")
var verbose = flag.Bool("verbose", false, "Print diagnostic information")

// The CLI client will read or write a single item for talek
func main() {
	flag.Parse()

	// Config
	config := libtalek.ClientConfigFromFile(*config)
	if config == nil {
		fmt.Fprintln(os.Stderr, "Talek Client must be run with --config specifying where the server is.")
		os.Exit(1)
	}
	if config.Config == nil && *verbose {
		fmt.Fprintln(os.Stderr, "Common configuration will be fetched from frontend.")
	}

	topicdata, err := ioutil.ReadFile(*handle)
	if err != nil {
		panic(err)
	}
	topic := libtalek.Topic{}
	if *create {
		nt, newerr := libtalek.NewTopic()
		if newerr != nil {
			panic(err)
		}
		topic = *nt
	} else {
		if err = json.Unmarshal(topicdata, &topic); err != nil {
			panic(err)
		}
	}

	if len(*share) > 0 {
		handle := topic.Handle
		handleBytes, handleerr := json.Marshal(handle)
		if handleerr != nil {
			panic(handleerr)
		}
		ioutil.WriteFile(*share, handleBytes, 0640)
		fmt.Fprintf(os.Stderr, "Read-only topic written to %s\n", *share)
	}

	// Client-connected activity below.
	leaderRPC := common.NewFrontendRPC("RPC", config.FrontendAddr)

	client := libtalek.NewClient("Client", *config, leaderRPC)
	if client == nil {
		panic("could not create talek client")
	} else if *verbose {
		fmt.Fprintln(os.Stderr, "Connection to RPC established.")
	}

	if *read == false && len(*write) > 0 {
		if err = client.Publish(&topic, []byte(*write)); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to publish: %s", err)
			panic(err)
		}
	} else if *read == false {
		fmt.Fprintf(os.Stderr, "No Read or Write operation requested. Closing.")
	} else {
		msgs := client.Poll(&topic.Handle)
		timeout := time.After(config.ReadInterval * 5)
		select {
		case next := <-msgs:
			fmt.Println(next)
			break
		case <-timeout:
			if *verbose {
				fmt.Fprintln(os.Stderr, "Timed out waiting for new message.")
			}
			return
		}
		client.Done(&topic.Handle)
	}
	updatedTopic, err := json.Marshal(topic)
	if err != nil {
		panic(err)
	}
	if err = ioutil.WriteFile(*handle, updatedTopic, 0600); err != nil {
		panic(err)
	}
}
<|endoftext|>


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

// +build example

package main

import (
	"fmt"
	"image"
	_ "image/jpeg"
	"log"
	"net/http"

	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/ebitenutil"
)

var (
	count        int
	highDPIImage *ebiten.Image
)

func init() {
	// licensed under Public Domain
	// https://commons.wikimedia.org/wiki/File:As08-16-2593.jpg
	const url = "https://upload.wikimedia.org/wikipedia/commons/1/1f/As08-16-2593.jpg"

	res, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()

	img, _, err := image.Decode(res.Body)
	if err != nil {
		log.Fatal(err)
	}

	highDPIImage, err = ebiten.NewImageFromImage(img, ebiten.FilterLinear)
	if err != nil {
		log.Fatal(err)
	}
}

func update(screen *ebiten.Image) error {
	if ebiten.IsRunningSlowly() {
		return nil
	}

	scale := ebiten.DeviceScaleFactor()
	sw, sh := screen.Size()

	w, h := highDPIImage.Size()
	op := &ebiten.DrawImageOptions{}
	op.GeoM.Translate(float64(-w)/2, float64(-h)/2)
	// The image is just too big. Adjust the scale.
	op.GeoM.Scale(0.25, 0.25)
	// Scale the image by the device ratio so that the rendering result can be same
	// on various (diffrent-DPI) environments.
	op.GeoM.Scale(scale, scale)
	op.GeoM.Translate(float64(sw)/2, float64(sh)/2)
	screen.DrawImage(highDPIImage, op)

	ebitenutil.DebugPrint(screen, fmt.Sprintf("Device Scale Ratio: %0.2f", scale))
	return nil
}

func main() {
	const (
		screenWidth  = 640
		screenHeight = 480
	)

	// Pass the invert of scale so that Ebiten's auto scaling by device scale is disabled.
	s := ebiten.DeviceScaleFactor()
	if err := ebiten.Run(update, int(screenWidth*s), int(screenHeight*s), 1/s, "High DPI (Ebiten Demo)"); err != nil {
		log.Fatal(err)
	}
}
<commit_msg>examples/highdpi: Add comments<commit_after>// Copyright 2018 The Ebiten Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build example

package main

import (
	"fmt"
	"image"
	_ "image/jpeg"
	"log"
	"net/http"

	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/ebitenutil"
)

var (
	count        int
	highDPIImage *ebiten.Image
)

func init() {
	// licensed under Public Domain
	// https://commons.wikimedia.org/wiki/File:As08-16-2593.jpg
	const url = "https://upload.wikimedia.org/wikipedia/commons/1/1f/As08-16-2593.jpg"

	res, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()

	img, _, err := image.Decode(res.Body)
	if err != nil {
		log.Fatal(err)
	}

	highDPIImage, err = ebiten.NewImageFromImage(img, ebiten.FilterLinear)
	if err != nil {
		log.Fatal(err)
	}
}

func update(screen *ebiten.Image) error {
	if ebiten.IsRunningSlowly() {
		return nil
	}

	scale := ebiten.DeviceScaleFactor()
	sw, sh := screen.Size()

	w, h := highDPIImage.Size()
	op := &ebiten.DrawImageOptions{}

	// Move the images's center to the upper left corner.
	op.GeoM.Translate(float64(-w)/2, float64(-h)/2)

	// The image is just too big. Adjust the scale.
	op.GeoM.Scale(0.25, 0.25)
	// Scale the image by the device ratio so that the rendering result can be same
	// on various (diffrent-DPI) environments.
	op.GeoM.Scale(scale, scale)

	// Move the image's center to the screen's center.
	op.GeoM.Translate(float64(sw)/2, float64(sh)/2)
	screen.DrawImage(highDPIImage, op)

	ebitenutil.DebugPrint(screen, fmt.Sprintf("Device Scale Ratio: %0.2f", scale))
	return nil
}

func main() {
	const (
		screenWidth  = 640
		screenHeight = 480
	)

	// Pass the invert of scale so that Ebiten's auto scaling by device scale is disabled.
	s := ebiten.DeviceScaleFactor()
	if err := ebiten.Run(update, int(screenWidth*s), int(screenHeight*s), 1/s, "High DPI (Ebiten Demo)"); err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package parser

import (
	"errors"
	"fmt"
	//"go/ast"
	"regexp"
	"strconv"
	"strings"
)

type Operation struct {
	HttpMethod       string            `json:"httpMethod"`
	Nickname         string            `json:"nickname"`
	Type             string            `json:"type"`
	Items            OperationItems    `json:"items,omitempty"`
	Summary          string            `json:"summary,omitempty"`
	Notes            string            `json:"notes,omitempty"`
	Parameters       []Parameter       `json:"parameters,omitempty"`
	ResponseMessages []ResponseMessage `json:"responseMessages,omitempty"`
	Consumes         []string          `json:"-"`
	Produces         []string          `json:"produces,omitempty"`
	Authorizations   []Authorization   `json:"authorizations,omitempty"`
	Protocols        []Protocol        `json:"protocols,omitempty"`
	Path             string            `json:"-"`
	ForceResource    string            `json:"-"`
	parser           *Parser
	Models           []*Model `json:"-"`
	packageName      string
}
type OperationItems struct {
	Ref  string `json:"$ref,omitempty"`
	Type string `json:"type,omitempty"`
}

func NewOperation(p *Parser, packageName string) *Operation {
	return &Operation{
		parser:      p,
		Models:      make([]*Model, 0),
		packageName: packageName,
	}
}

func (operation *Operation) SetItemsType(itemsType string) {
	operation.Items = OperationItems{}
	if IsBasicType(itemsType) {
		operation.Items.Type = itemsType
	} else {
		operation.Items.Ref = itemsType
	}
}

func (operation *Operation) ParseComment(comment string) error {
	commentLine := strings.TrimSpace(strings.TrimLeft(comment, "//"))
	attribute := strings.ToLower(strings.Split(commentLine, " ")[0])
	switch attribute {
	case "@router":
		if err := operation.ParseRouterComment(commentLine); err != nil {
			return err
		}
	case "@resource":
		resource := strings.TrimSpace(commentLine[len("@Resource"):])
		if resource[0:1] == "/" {
			resource = resource[1:]
		}
		operation.ForceResource = resource
	case "@title":
		operation.Nickname = strings.TrimSpace(commentLine[len("@Title"):])
	case "@description":
		operation.Summary = strings.TrimSpace(commentLine[len("@Description"):])
	case "@success":
		sourceString := strings.TrimSpace(commentLine[len("@Success"):])
		if err := operation.ParseResponseComment(sourceString); err != nil {
			return err
		}
	case "@param":
		if err := operation.ParseParamComment(commentLine); err != nil {
			return err
		}
	case "@failure":
		sourceString := strings.TrimSpace(commentLine[len("@Failure"):])
		if err := operation.ParseResponseComment(sourceString); err != nil {
			return err
		}
	case "@accept":
		if err := operation.ParseAcceptComment(commentLine); err != nil {
			return err
		}
	}

	operation.Models = operation.getUniqueModels()

	return nil
}

func (operation *Operation) getUniqueModels() []*Model {

	uniqueModels := make([]*Model, 0, len(operation.Models))
	modelIds := map[string]bool{}

	for _, model := range operation.Models {
		if _, exists := modelIds[model.Id]; exists {
			continue
		}
		uniqueModels = append(uniqueModels, model)
		modelIds[model.Id] = true
	}

	return uniqueModels
}

// Parse params return []string of param properties
// @Param	queryText		form	      string	  true		        "The email for login"
// 			[param name]    [param type] [data type]  [is mandatory?]   [Comment]
func (operation *Operation) ParseParamComment(commentLine string) error {
	swaggerParameter := Parameter{}
	paramString := strings.TrimSpace(commentLine[len("@Param "):])

	re := regexp.MustCompile(`([\w]+)[\s]+([\w]+)[\s]+([\w.]+)[\s]+([\w]+)[\s]+"([^"]+)"`)

	if matches := re.FindStringSubmatch(paramString); len(matches) != 6 {
		return fmt.Errorf("Can not parse param comment \"%s\", skipped.", paramString)
	} else {
		//TODO: if type is not simple, then add to Models[]
		swaggerParameter.Name = matches[1]
		swaggerParameter.ParamType = matches[2]
		swaggerParameter.Type = matches[3]
		swaggerParameter.DataType = matches[3]
		swaggerParameter.Required = strings.ToLower(matches[4]) == "true"
		swaggerParameter.Description = matches[5]

		operation.Parameters = append(operation.Parameters, swaggerParameter)
	}

	return nil
}

// @Accept  json
func (operation *Operation) ParseAcceptComment(commentLine string) error {
	accepts := strings.Split(strings.TrimSpace(strings.TrimSpace(commentLine[len("@Accept"):])), ",")
	for _, a := range accepts {
		switch a {
		case "json", "application/json":
			operation.Consumes = append(operation.Consumes, ContentTypeJson)
			operation.Produces = append(operation.Produces, ContentTypeJson)
		case "xml", "text/xml":
			operation.Consumes = append(operation.Consumes, ContentTypeXml)
			operation.Produces = append(operation.Produces, ContentTypeXml)
		case "plain", "text/plain":
			operation.Consumes = append(operation.Consumes, ContentTypePlain)
			operation.Produces = append(operation.Produces, ContentTypePlain)
		case "html", "text/html":
			operation.Consumes = append(operation.Consumes, ContentTypeHtml)
			operation.Produces = append(operation.Produces, ContentTypeHtml)
		}
	}
	return nil
}

// @Router /customer/get-wishlist/{wishlist_id} [get]
func (operation *Operation) ParseRouterComment(commentLine string) error {
	sourceString := strings.TrimSpace(commentLine[len("@Router"):])

	re := regexp.MustCompile(`([\w\.\/\-{}]+)[^\[]+\[([^\]]+)`)
	var matches []string

	if matches = re.FindStringSubmatch(sourceString); len(matches) != 3 {
		return fmt.Errorf("Can not parse router comment \"%s\", skipped.", commentLine)
	}

	operation.Path = matches[1]
	operation.HttpMethod = strings.ToUpper(matches[2])
	return nil
}

// @Success 200 {object} model.OrderRow "Error message, if code != 200"
func (operation *Operation) ParseResponseComment(commentLine string) error {
	re := regexp.MustCompile(`([\d]+)[\s]+([\w\{\}]+)[\s]+([\w\-\.\/]+)[^"]*(.*)?`)
	var matches []string

	if matches = re.FindStringSubmatch(commentLine); len(matches) != 5 {
		return fmt.Errorf("Can not parse response comment \"%s\", skipped.", commentLine)
	}

	response := ResponseMessage{}
	if code, err := strconv.Atoi(matches[1]); err != nil {
		return errors.New("Success http code must be int")
	} else {
		response.Code = code
	}
	response.Message = strings.Trim(matches[4], "\"")

	typeName := ""
	if IsBasicType(matches[3]) {
		typeName = matches[3]
	} else {
		model := NewModel(operation.parser)
		response.ResponseModel = matches[3]
		knownModelNames := map[string]bool{}
		if err, innerModels := model.ParseModel(response.ResponseModel, operation.parser.CurrentPackage, knownModelNames); err != nil {
			return err
		} else {
			typeName = model.Id

			operation.Models = append(operation.Models, model)
			operation.Models = append(operation.Models, innerModels...)
		}
	}

	response.ResponseModel = typeName
	if response.Code == 200 {
		if matches[2] == "{array}" {
			operation.SetItemsType(typeName)
			operation.Type = "array"
		} else {
			operation.Type = typeName
		}
	}

	operation.ResponseMessages = append(operation.ResponseMessages, response)
	return nil
}
<commit_msg>Parse not simple type for @Params<commit_after>package parser

import (
	"errors"
	"fmt"
	//"go/ast"
	"regexp"
	"strconv"
	"strings"
)

type Operation struct {
	HttpMethod       string            `json:"httpMethod"`
	Nickname         string            `json:"nickname"`
	Type             string            `json:"type"`
	Items            OperationItems    `json:"items,omitempty"`
	Summary          string            `json:"summary,omitempty"`
	Notes            string            `json:"notes,omitempty"`
	Parameters       []Parameter       `json:"parameters,omitempty"`
	ResponseMessages []ResponseMessage `json:"responseMessages,omitempty"`
	Consumes         []string          `json:"-"`
	Produces         []string          `json:"produces,omitempty"`
	Authorizations   []Authorization   `json:"authorizations,omitempty"`
	Protocols        []Protocol        `json:"protocols,omitempty"`
	Path             string            `json:"-"`
	ForceResource    string            `json:"-"`
	parser           *Parser
	Models           []*Model `json:"-"`
	packageName      string
}
type OperationItems struct {
	Ref  string `json:"$ref,omitempty"`
	Type string `json:"type,omitempty"`
}

func NewOperation(p *Parser, packageName string) *Operation {
	return &Operation{
		parser:      p,
		Models:      make([]*Model, 0),
		packageName: packageName,
	}
}

func (operation *Operation) SetItemsType(itemsType string) {
	operation.Items = OperationItems{}
	if IsBasicType(itemsType) {
		operation.Items.Type = itemsType
	} else {
		operation.Items.Ref = itemsType
	}
}

func (operation *Operation) ParseComment(comment string) error {
	commentLine := strings.TrimSpace(strings.TrimLeft(comment, "//"))
	attribute := strings.ToLower(strings.Split(commentLine, " ")[0])
	switch attribute {
	case "@router":
		if err := operation.ParseRouterComment(commentLine); err != nil {
			return err
		}
	case "@resource":
		resource := strings.TrimSpace(commentLine[len("@Resource"):])
		if resource[0:1] == "/" {
			resource = resource[1:]
		}
		operation.ForceResource = resource
	case "@title":
		operation.Nickname = strings.TrimSpace(commentLine[len("@Title"):])
	case "@description":
		operation.Summary = strings.TrimSpace(commentLine[len("@Description"):])
	case "@success":
		sourceString := strings.TrimSpace(commentLine[len("@Success"):])
		if err := operation.ParseResponseComment(sourceString); err != nil {
			return err
		}
	case "@param":
		if err := operation.ParseParamComment(commentLine); err != nil {
			return err
		}
	case "@failure":
		sourceString := strings.TrimSpace(commentLine[len("@Failure"):])
		if err := operation.ParseResponseComment(sourceString); err != nil {
			return err
		}
	case "@accept":
		if err := operation.ParseAcceptComment(commentLine); err != nil {
			return err
		}
	}

	operation.Models = operation.getUniqueModels()

	return nil
}

func (operation *Operation) getUniqueModels() []*Model {

	uniqueModels := make([]*Model, 0, len(operation.Models))
	modelIds := map[string]bool{}

	for _, model := range operation.Models {
		if _, exists := modelIds[model.Id]; exists {
			continue
		}
		uniqueModels = append(uniqueModels, model)
		modelIds[model.Id] = true
	}

	return uniqueModels
}

func (operation *Operation) registerType(typeName string) (string, error) {
	registerType := ""

	if IsBasicType(typeName) {
		registerType = typeName
	} else {
		model := NewModel(operation.parser)
		knownModelNames := map[string]bool{}

		if err, innerModels := model.ParseModel(typeName, operation.parser.CurrentPackage, knownModelNames); err != nil {
			return registerType, err
		} else {
			registerType = model.Id

			operation.Models = append(operation.Models, model)
			operation.Models = append(operation.Models, innerModels...)
		}
	}

	return registerType, nil
}

// Parse params return []string of param properties
// @Param	queryText		form	      string	  true		        "The email for login"
// 			[param name]    [param type] [data type]  [is mandatory?]   [Comment]
func (operation *Operation) ParseParamComment(commentLine string) error {
	swaggerParameter := Parameter{}
	paramString := strings.TrimSpace(commentLine[len("@Param "):])

	re := regexp.MustCompile(`([\w]+)[\s]+([\w]+)[\s]+([\w.]+)[\s]+([\w]+)[\s]+"([^"]+)"`)

	if matches := re.FindStringSubmatch(paramString); len(matches) != 6 {
		return fmt.Errorf("Can not parse param comment \"%s\", skipped.", paramString)
	} else {
		typeName, err := operation.registerType(matches[3])
		if err != nil {
			return err
		}

		swaggerParameter.Name = matches[1]
		swaggerParameter.ParamType = matches[2]
		swaggerParameter.Type = typeName
		swaggerParameter.DataType = typeName
		swaggerParameter.Required = strings.ToLower(matches[4]) == "true"
		swaggerParameter.Description = matches[5]

		operation.Parameters = append(operation.Parameters, swaggerParameter)
	}

	return nil
}

// @Accept  json
func (operation *Operation) ParseAcceptComment(commentLine string) error {
	accepts := strings.Split(strings.TrimSpace(strings.TrimSpace(commentLine[len("@Accept"):])), ",")
	for _, a := range accepts {
		switch a {
		case "json", "application/json":
			operation.Consumes = append(operation.Consumes, ContentTypeJson)
			operation.Produces = append(operation.Produces, ContentTypeJson)
		case "xml", "text/xml":
			operation.Consumes = append(operation.Consumes, ContentTypeXml)
			operation.Produces = append(operation.Produces, ContentTypeXml)
		case "plain", "text/plain":
			operation.Consumes = append(operation.Consumes, ContentTypePlain)
			operation.Produces = append(operation.Produces, ContentTypePlain)
		case "html", "text/html":
			operation.Consumes = append(operation.Consumes, ContentTypeHtml)
			operation.Produces = append(operation.Produces, ContentTypeHtml)
		}
	}
	return nil
}

// @Router /customer/get-wishlist/{wishlist_id} [get]
func (operation *Operation) ParseRouterComment(commentLine string) error {
	sourceString := strings.TrimSpace(commentLine[len("@Router"):])

	re := regexp.MustCompile(`([\w\.\/\-{}]+)[^\[]+\[([^\]]+)`)
	var matches []string

	if matches = re.FindStringSubmatch(sourceString); len(matches) != 3 {
		return fmt.Errorf("Can not parse router comment \"%s\", skipped.", commentLine)
	}

	operation.Path = matches[1]
	operation.HttpMethod = strings.ToUpper(matches[2])
	return nil
}

// @Success 200 {object} model.OrderRow "Error message, if code != 200"
func (operation *Operation) ParseResponseComment(commentLine string) error {
	re := regexp.MustCompile(`([\d]+)[\s]+([\w\{\}]+)[\s]+([\w\-\.\/]+)[^"]*(.*)?`)
	var matches []string

	if matches = re.FindStringSubmatch(commentLine); len(matches) != 5 {
		return fmt.Errorf("Can not parse response comment \"%s\", skipped.", commentLine)
	}

	response := ResponseMessage{}
	if code, err := strconv.Atoi(matches[1]); err != nil {
		return errors.New("Success http code must be int")
	} else {
		response.Code = code
	}
	response.Message = strings.Trim(matches[4], "\"")

	typeName, err := operation.registerType(matches[3])
	if err != nil {
		return err
	}

	response.ResponseModel = typeName
	if response.Code == 200 {
		if matches[2] == "{array}" {
			operation.SetItemsType(typeName)
			operation.Type = "array"
		} else {
			operation.Type = typeName
		}
	}

	operation.ResponseMessages = append(operation.ResponseMessages, response)
	return nil
}
<|endoftext|>


<commit_before>package echo

import (
	"github.com/oklahomer/go-sarah"
	"github.com/oklahomer/go-sarah/gitter"
	"github.com/oklahomer/go-sarah/slack"
	"golang.org/x/net/context"
	"regexp"
)

var (
	identifier   = "echo"
	matchPattern = regexp.MustCompile(`^\.echo`)
)

var commandFnc = func(input sarah.Input) string {
	return sarah.StripMessage(matchPattern, input.Message())
}

// SlackCommandFunc is a sarah.CommandFunc especially designed for Slack adapter.
func SlackCommandFunc(_ context.Context, input sarah.Input) (*sarah.CommandResponse, error) {
	return slack.NewStringResponse(commandFnc(input)), nil
}

// SlackCommandFunc is a sarah.CommandFunc especially designed for gitter adapter.
func GitterCommandFunc(_ context.Context, input sarah.Input) (*sarah.CommandResponse, error) {
	return gitter.NewStringResponse(commandFnc(input)), nil
}

// SlackCommand is a pre-built Command for Slack.
var SlackCommand = sarah.NewCommandBuilder().
	Identifier(identifier).
	MatchPattern(matchPattern).
	Func(SlackCommandFunc).
	InputExample(".echo knock knock").
	MustBuild()

// GitterCommand is a pre-built Command for gitter.
var GitterCommand = sarah.NewCommandBuilder().
	Identifier(identifier).
	MatchPattern(matchPattern).
	Func(GitterCommandFunc).
	InputExample(".echo knock knock")
<commit_msg>Fix comment<commit_after>package echo

import (
	"github.com/oklahomer/go-sarah"
	"github.com/oklahomer/go-sarah/gitter"
	"github.com/oklahomer/go-sarah/slack"
	"golang.org/x/net/context"
	"regexp"
)

var (
	identifier   = "echo"
	matchPattern = regexp.MustCompile(`^\.echo`)
)

var commandFnc = func(input sarah.Input) string {
	return sarah.StripMessage(matchPattern, input.Message())
}

// SlackCommandFunc is a sarah.CommandFunc especially designed for Slack adapter.
func SlackCommandFunc(_ context.Context, input sarah.Input) (*sarah.CommandResponse, error) {
	return slack.NewStringResponse(commandFnc(input)), nil
}

// GitterCommandFunc is a sarah.CommandFunc especially designed for gitter adapter.
func GitterCommandFunc(_ context.Context, input sarah.Input) (*sarah.CommandResponse, error) {
	return gitter.NewStringResponse(commandFnc(input)), nil
}

// SlackCommand is a pre-built Command for Slack.
var SlackCommand = sarah.NewCommandBuilder().
	Identifier(identifier).
	MatchPattern(matchPattern).
	Func(SlackCommandFunc).
	InputExample(".echo knock knock").
	MustBuild()

// GitterCommand is a pre-built Command for gitter.
var GitterCommand = sarah.NewCommandBuilder().
	Identifier(identifier).
	MatchPattern(matchPattern).
	Func(GitterCommandFunc).
	InputExample(".echo knock knock")
<|endoftext|>


<commit_before>package neurgo

import (
	"fmt"
)

type TrainingSample struct {

	// for each sensor in the network, provide a sample input vector
	SampleInputs [][]float64

	// for each actuator in the network, provide an expected output vector
	ExpectedOutputs [][]float64
}

func (t *TrainingSample) String() string {
	return fmt.Sprintf("Inputs: %v, Expected: %v",
		t.SampleInputs,
		t.ExpectedOutputs)
}
<commit_msg>add trainer interface<commit_after>package neurgo

import (
	"fmt"
)

type TrainingSample struct {

	// for each sensor in the network, provide a sample input vector
	SampleInputs [][]float64

	// for each actuator in the network, provide an expected output vector
	ExpectedOutputs [][]float64
}

func (t *TrainingSample) String() string {
	return fmt.Sprintf("Inputs: %v, Expected: %v",
		t.SampleInputs,
		t.ExpectedOutputs)
}

type Trainer interface {
	Train(cortex *Cortex, examples []*TrainingSample) *Cortex
}
<|endoftext|>


<commit_before>// Package cliutil contains methods used across all cli commands
// @todo: get rid of os.Exits and use errors instread
package util

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

	"github.com/micro/micro/v3/internal/config"
	"github.com/urfave/cli/v2"
)

const (
	// EnvLocal is a builtin environment, it represents your local `micro server`
	EnvLocal = "local"
	// EnvPlatform is a builtin environment, the One True Micro Live(tm) environment.
	EnvPlatform = "platform"
)

const (
	// localProxyAddress is the default proxy address for environment server
	localProxyAddress = "127.0.0.1:8081"
	// platformProxyAddress is teh default proxy address for environment platform
	platformProxyAddress = "proxy.m3o.com"
)

var (
	// list of services managed
	// TODO: make use server/server list
	services = []string{
		// runtime services
		"network",  // :8085 (peer), :8443 (proxy)
		"runtime",  // :8088
		"registry", // :8000
		"config",   // :8001
		"store",    // :8002
		"broker",   // :8003
		"router",   // :8084
		"auth",     // :8010
		"proxy",    // :8081
		"api",      // :8080
	}
)

var defaultEnvs = map[string]Env{
	EnvLocal: {
		Name:         EnvLocal,
		ProxyAddress: localProxyAddress,
	},
	EnvPlatform: {
		Name:         EnvPlatform,
		ProxyAddress: platformProxyAddress,
	},
}

func IsBuiltInService(command string) bool {
	for _, service := range services {
		if command == service {
			return true
		}
	}
	return false
}

// CLIProxyAddress returns the proxy address which should be set for the client
func CLIProxyAddress(ctx *cli.Context) (string, error) {
	switch ctx.Args().First() {
	case "new", "server", "help", "env":
		return "", nil
	}

	// fix for "micro service [command]", e.g "micro service auth"
	if ctx.Args().First() == "service" && IsBuiltInService(ctx.Args().Get(1)) {
		return "", nil
	}

	// don't set the proxy address on the proxy
	if ctx.Args().First() == "proxy" {
		return "", nil
	}

	env, err := GetEnv(ctx)
	if err != nil {
		return "", err
	}
	addr := env.ProxyAddress
	if !strings.Contains(addr, ":") {
		return fmt.Sprintf("%v:443", addr), nil
	}
	return addr, nil
}

type Env struct {
	Name         string
	ProxyAddress string
}

func AddEnv(env Env) error {
	envs, err := getEnvs()
	if err != nil {
		return err
	}
	envs[env.Name] = env
	return setEnvs(envs)
}

func getEnvs() (map[string]Env, error) {
	envsJSON, err := config.Get("envs")
	if err != nil {
		return nil, fmt.Errorf("Error getting environment: %v", err)
	}
	envs := map[string]Env{}
	if len(envsJSON) > 0 {
		err := json.Unmarshal([]byte(envsJSON), &envs)
		if err != nil {
			return nil, err
		}
	}
	for k, v := range defaultEnvs {
		envs[k] = v
	}
	return envs, nil
}

func setEnvs(envs map[string]Env) error {
	envsJSON, err := json.Marshal(envs)
	if err != nil {
		return err
	}
	return config.Set("envs", string(envsJSON))
}

// GetEnv returns the current selected environment
// Does not take
func GetEnv(ctx *cli.Context) (Env, error) {
	var envName string
	if len(ctx.String("env")) > 0 {
		envName = ctx.String("env")
	} else {
		env, err := config.Get("env")
		if err != nil {
			return Env{}, err
		}
		if env == "" {
			env = EnvLocal
		}
		envName = env
	}

	return GetEnvByName(envName)
}

func GetEnvByName(env string) (Env, error) {
	envs, err := getEnvs()
	if err != nil {
		return Env{}, err
	}
	envir, ok := envs[env]
	if !ok {
		return Env{}, fmt.Errorf("Env \"%s\" not found. See `micro env` for available environments.", env)
	}
	return envir, nil
}

func GetEnvs() ([]Env, error) {
	envs, err := getEnvs()
	if err != nil {
		return nil, err
	}
	ret := []Env{defaultEnvs[EnvLocal], defaultEnvs[EnvPlatform]}
	nonDefaults := []Env{}
	for _, env := range envs {
		if _, isDefault := defaultEnvs[env.Name]; !isDefault {
			nonDefaults = append(nonDefaults, env)
		}
	}
	// @todo order nondefault envs alphabetically
	ret = append(ret, nonDefaults...)
	return ret, nil
}

// SetEnv selects an environment to be used.
func SetEnv(envName string) error {
	envs, err := getEnvs()
	if err != nil {
		return err
	}
	_, ok := envs[envName]
	if !ok {
		return fmt.Errorf("Environment '%v' does not exist\n", envName)
	}
	return config.Set("env", envName)
}

// DelEnv deletes an env from config
func DelEnv(envName string) error {
	envs, err := getEnvs()
	if err != nil {
		return err
	}
	_, ok := envs[envName]
	if !ok {
		return fmt.Errorf("Environment '%v' does not exist\n", envName)
	}
	delete(envs, envName)
	return setEnvs(envs)
}

func IsPlatform(ctx *cli.Context) bool {
	env, err := GetEnv(ctx)
	if err == nil && env.Name == EnvPlatform {
		return true
	}
	return false
}

type Exec func(*cli.Context, []string) ([]byte, error)

func Print(e Exec) func(*cli.Context) error {
	return func(c *cli.Context) error {
		rsp, err := e(c, c.Args().Slice())
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		if len(rsp) > 0 {
			fmt.Printf("%s\n", string(rsp))
		}
		return nil
	}
}
<commit_msg>Add dev as a default environment (#1404)<commit_after>// Package cliutil contains methods used across all cli commands
// @todo: get rid of os.Exits and use errors instread
package util

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

	"github.com/micro/micro/v3/internal/config"
	"github.com/urfave/cli/v2"
)

const (
	// EnvLocal is a builtin environment, it represents your local `micro server`
	EnvLocal = "local"
	// EnvDev is a builtin staging / dev environment in the cloud
	EnvDev = "dev"
	// EnvPlatform is a builtin highly available environment in the cloud,
	EnvPlatform = "platform"
)

const (
	// localProxyAddress is the default proxy address for environment server
	localProxyAddress = "127.0.0.1:8081"
	// devProxyAddress is the address for the proxy server in the dev environment
	devProxyAddress = "proxy.m3o.dev"
	// platformProxyAddress is the default proxy address for environment platform
	platformProxyAddress = "proxy.m3o.com"
)

var (
	// list of services managed
	// TODO: make use server/server list
	services = []string{
		// runtime services
		"network",  // :8085 (peer), :8443 (proxy)
		"runtime",  // :8088
		"registry", // :8000
		"config",   // :8001
		"store",    // :8002
		"broker",   // :8003
		"router",   // :8084
		"auth",     // :8010
		"proxy",    // :8081
		"api",      // :8080
	}
)

var defaultEnvs = map[string]Env{
	EnvLocal: {
		Name:         EnvLocal,
		ProxyAddress: localProxyAddress,
	},
	EnvDev: {
		Name:         EnvDev,
		ProxyAddress: devProxyAddress,
	},
	EnvPlatform: {
		Name:         EnvPlatform,
		ProxyAddress: platformProxyAddress,
	},
}

func IsBuiltInService(command string) bool {
	for _, service := range services {
		if command == service {
			return true
		}
	}
	return false
}

// CLIProxyAddress returns the proxy address which should be set for the client
func CLIProxyAddress(ctx *cli.Context) (string, error) {
	switch ctx.Args().First() {
	case "new", "server", "help", "env":
		return "", nil
	}

	// fix for "micro service [command]", e.g "micro service auth"
	if ctx.Args().First() == "service" && IsBuiltInService(ctx.Args().Get(1)) {
		return "", nil
	}

	// don't set the proxy address on the proxy
	if ctx.Args().First() == "proxy" {
		return "", nil
	}

	env, err := GetEnv(ctx)
	if err != nil {
		return "", err
	}
	addr := env.ProxyAddress
	if !strings.Contains(addr, ":") {
		return fmt.Sprintf("%v:443", addr), nil
	}
	return addr, nil
}

type Env struct {
	Name         string
	ProxyAddress string
}

func AddEnv(env Env) error {
	envs, err := getEnvs()
	if err != nil {
		return err
	}
	envs[env.Name] = env
	return setEnvs(envs)
}

func getEnvs() (map[string]Env, error) {
	envsJSON, err := config.Get("envs")
	if err != nil {
		return nil, fmt.Errorf("Error getting environment: %v", err)
	}
	envs := map[string]Env{}
	if len(envsJSON) > 0 {
		err := json.Unmarshal([]byte(envsJSON), &envs)
		if err != nil {
			return nil, err
		}
	}
	for k, v := range defaultEnvs {
		envs[k] = v
	}
	return envs, nil
}

func setEnvs(envs map[string]Env) error {
	envsJSON, err := json.Marshal(envs)
	if err != nil {
		return err
	}
	return config.Set("envs", string(envsJSON))
}

// GetEnv returns the current selected environment
// Does not take
func GetEnv(ctx *cli.Context) (Env, error) {
	var envName string
	if len(ctx.String("env")) > 0 {
		envName = ctx.String("env")
	} else {
		env, err := config.Get("env")
		if err != nil {
			return Env{}, err
		}
		if env == "" {
			env = EnvLocal
		}
		envName = env
	}

	return GetEnvByName(envName)
}

func GetEnvByName(env string) (Env, error) {
	envs, err := getEnvs()
	if err != nil {
		return Env{}, err
	}
	envir, ok := envs[env]
	if !ok {
		return Env{}, fmt.Errorf("Env \"%s\" not found. See `micro env` for available environments.", env)
	}
	return envir, nil
}

func GetEnvs() ([]Env, error) {
	envs, err := getEnvs()
	if err != nil {
		return nil, err
	}

	var ret []Env

	// populate the default environments
	for _, env := range defaultEnvs {
		ret = append(ret, env)
	}

	var nonDefaults []Env

	for _, env := range envs {
		if _, isDefault := defaultEnvs[env.Name]; !isDefault {
			nonDefaults = append(nonDefaults, env)
		}
	}

	// @todo order nondefault envs alphabetically
	ret = append(ret, nonDefaults...)

	return ret, nil
}

// SetEnv selects an environment to be used.
func SetEnv(envName string) error {
	envs, err := getEnvs()
	if err != nil {
		return err
	}
	_, ok := envs[envName]
	if !ok {
		return fmt.Errorf("Environment '%v' does not exist\n", envName)
	}
	return config.Set("env", envName)
}

// DelEnv deletes an env from config
func DelEnv(envName string) error {
	envs, err := getEnvs()
	if err != nil {
		return err
	}
	_, ok := envs[envName]
	if !ok {
		return fmt.Errorf("Environment '%v' does not exist\n", envName)
	}
	delete(envs, envName)
	return setEnvs(envs)
}

func IsPlatform(ctx *cli.Context) bool {
	env, err := GetEnv(ctx)
	if err == nil && env.Name == EnvPlatform {
		return true
	}
	return false
}

type Exec func(*cli.Context, []string) ([]byte, error)

func Print(e Exec) func(*cli.Context) error {
	return func(c *cli.Context) error {
		rsp, err := e(c, c.Args().Slice())
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		if len(rsp) > 0 {
			fmt.Printf("%s\n", string(rsp))
		}
		return nil
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"os/exec"
	"path"
	"testing"
	"time"
)

// change these!
var tests = map[string]string{
	"Blah Hello World": "Blah A MUCH LONGER THING World",
	"Blah":             "Blah",
	"Blah\xff\xfe\xaa\x00\x00Hello World": "Blah\xff\xfe\xaa\x00\x00A MUCH LONGER THING World",
	"": "",
}

func sleepyConnect(dest string) (s net.Conn, err error) {
	zzz := 1 * time.Millisecond
	for {
		if zzz > 1*time.Second {
			err = fmt.Errorf("Failed to connect to fix server")
			return
		}
		time.Sleep(zzz)
		s, err = net.Dial("unix", dest)
		if err == nil {
			return
		}
		zzz *= 2
	}
}

func BenchmarkFixup(b *testing.B) {
	sock := path.Join(os.TempDir(), "aflfix.sock")
	os.Setenv("AFL_FIX_SOCK", sock)
	server := exec.Command("./aflfix")
	err := server.Start()
	if err != nil {
		b.Fatalf("Unable to launch server: %s", err)
	}
	// When we exit the sock will EOF and the server will exit cleanly.
	s, err := sleepyConnect(sock)
	if err != nil {
		b.Fatalf("Failed to connect to fix server")
	}
	defer s.Close()

	scanner := bufio.NewScanner(s)
	scanner.Split(ScanNetStrings)
	k := "Blah\xff\xfe\xaa\x00\x00Hello World"
	out := []byte(fmt.Sprintf("%d:%s,", len(k), k))
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		s.Write(out)
		scanner.Scan()
	}
}

func TestRoundTrip(t *testing.T) {

	sock := path.Join(os.TempDir(), "aflfix.sock")
	os.Setenv("AFL_FIX_SOCK", sock)
	server := exec.Command("./aflfix")
	err := server.Start()
	if err != nil {
		t.Fatalf("Unable to launch server: %s", err)
	}
	// Don't defer Kill() - when we exit the sock will EOF at the server end
	// and it will exit cleanly.
	s, err := sleepyConnect(sock)
	if err != nil {
		t.Fatalf("Failed to connect to fix server")
	}
	defer s.Close()

	scanner := bufio.NewScanner(s)
	scanner.Split(ScanNetStrings)

	// Change the tests if you change the core logic, obviously.
	for k, want := range tests {
		s.Write([]byte(fmt.Sprintf("%d:%s,", len(k), k)))
		scanner.Scan()
		if scanner.Text() != want {
			t.Fatalf("Sent %s, got %s, want %s", k, scanner.Text(), want)
		}
	}
}
<commit_msg>minor formatting<commit_after>package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"os/exec"
	"path"
	"testing"
	"time"
)

// change these!
var tests = map[string]string{
	"Blah Hello World": "Blah A MUCH LONGER THING World",
	"Blah":             "Blah",
	"Blah\xff\xfe\xaa\x00\x00Hello World": "Blah\xff\xfe\xaa\x00\x00A MUCH LONGER THING World",
	"": "",
}

func sleepyConnect(dest string) (s net.Conn, err error) {
	zzz := 1 * time.Millisecond
	for {
		if zzz > 1*time.Second {
			err = fmt.Errorf("Failed to connect to fix server")
			return
		}
		time.Sleep(zzz)
		s, err = net.Dial("unix", dest)
		if err == nil {
			return
		}
		zzz *= 2
	}
}

func BenchmarkFixup(b *testing.B) {

	sock := path.Join(os.TempDir(), "aflfix.sock")
	os.Setenv("AFL_FIX_SOCK", sock)

	server := exec.Command("./aflfix")
	err := server.Start()
	if err != nil {
		b.Fatalf("Unable to launch server: %s", err)
	}

	s, err := sleepyConnect(sock)
	if err != nil {
		b.Fatalf("Failed to connect to fix server")
	}
	defer s.Close()

	scanner := bufio.NewScanner(s)
	scanner.Split(ScanNetStrings)
	k := "Blah\xff\xfe\xaa\x00\x00Hello World"
	out := []byte(fmt.Sprintf("%d:%s,", len(k), k))

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		s.Write(out)
		scanner.Scan()
	}
}

func TestRoundTrip(t *testing.T) {

	sock := path.Join(os.TempDir(), "aflfix.sock")
	os.Setenv("AFL_FIX_SOCK", sock)

	server := exec.Command("./aflfix")
	err := server.Start()
	if err != nil {
		t.Fatalf("Unable to launch server: %s", err)
	}

	s, err := sleepyConnect(sock)
	if err != nil {
		t.Fatalf("Failed to connect to fix server")
	}
	defer s.Close()
	// don't need to kill, server will exit the socket EOFs

	scanner := bufio.NewScanner(s)
	scanner.Split(ScanNetStrings)

	// Change the tests if you change the core logic, obviously.
	for k, want := range tests {
		s.Write([]byte(fmt.Sprintf("%d:%s,", len(k), k)))
		scanner.Scan()
		if scanner.Text() != want {
			t.Fatalf("Sent %s, got %s, want %s", k, scanner.Text(), want)
		}
	}
}
<|endoftext|>


<commit_before>package agent

import (
	"fmt"
	"math/rand" // TODO(yifan): Need to change this??
	"net"
	"sync"

	"github.com/go-distributed/gog/codec"
	"github.com/go-distributed/gog/config"
	"github.com/go-distributed/gog/message"
	"github.com/go-distributed/gog/node"

	log "github.com/golang/glog"
)

// Agent describes the interface of an agent.
type Agent interface {
	// Serve starts a standalone agent, waiting for
	// incoming connections.
	Serve() error
	// Join joins the agent to the cluster.
	Join(addr ...string) error
	// Leave causes the agent to leave the cluster.
	Leave() error
	// Broadcast broadcasts a message to the cluster.
	Broadcast(msg []byte) error
	// Count does a broadcast and returns a channel of
	// nodes, which can be used to compute the broadcast
	// delay.
	Count(addr string) (chan *node.Node, error)
}

// agent implements the Agent interface.
type agent struct {
	// The id of the agent.
	id string
	// Configuration.
	cfg *config.Config
	// Active View.
	mua   sync.Mutex
	aView map[string]*node.Node
	// Passive View.
	mup   sync.Mutex
	pView map[string]*node.Node
	// TCP listener.
	ln *net.TCPListener
	// The codec.
	codec codec.Codec
}

// NewAgent creates a new agent.
func NewAgent(cfg *config.Config) Agent {
	// Create a codec and register messages.
	codec := codec.NewProtobufCodec()
	codec.Register(&message.UserMessage{})
	codec.Register(&message.Join{})
	codec.Register(&message.ForwardJoin{})
	codec.Register(&message.Disconnect{})
	codec.Register(&message.Shuffle{})
	codec.Register(&message.ShuffleReply{})

	return &agent{
		cfg:   cfg,
		codec: codec,
		aView: make(map[string]*node.Node),
		pView: make(map[string]*node.Node),
	}
}

// Serve starts a standalone agent, waiting for
// incoming connections.
func (ag *agent) Serve() error {
	ln, err := net.ListenTCP(ag.cfg.Net, ag.cfg.LocalTCPAddr)
	if err != nil {
		return err
	}
	ag.ln = ln
	// TODO(yifan): Added a tick to trigger shuffle periodically.
	ag.serve()
	return nil
}

// serveNewConn listens on the TCP listener, waits for incoming connections.
func (ag *agent) serve() {
	for {
		conn, err := ag.ln.AcceptTCP()
		if err != nil {
			log.Errorf("Agent.serve(): Failed to accept\n")
			continue
		}
		// TODO(Yifan): Set read time ount.
		go ag.serveConn(conn)
	}
}

// serveConn() serves a connection.
func (ag *agent) serveConn(conn *net.TCPConn) {
	defer conn.Close()
	for {
		msg, err := ag.codec.ReadMsg(conn)
		if err != nil {
			log.Errorf("Agent.serveConn(): Failed to decode message: %v\n", err)
			// TODO(yifan): Now what? Drop the conn?
			// Update the view?
			return
		}
		// Dispatch messages.
		switch t := msg.(type) {
		case *message.Join:
			ag.handleJoin(conn, msg.(*message.Join))
		case *message.Neighbor:
			ag.handleNeighbor(conn, msg.(*message.Neighbor))
		case *message.ForwardJoin:
			ag.handleForwardJoin(msg.(*message.ForwardJoin))
		case *message.Disconnect:
			ag.handleDisconnect(msg.(*message.Disconnect))
			return
		case *message.Shuffle:
			ag.handleShuffle(msg.(*message.Shuffle))
		case *message.UserMessage:
			ag.handleUserMessage(msg.(*message.UserMessage))
		default:
			log.Errorf("Agent.serveConn(): Unexpected message type: %T\n", t)
			// TODO(yifan): Now what? Drop the conn?
			// Update the view?
			return
		}
	}
}

func chooseRandomNode(view map[string]*node.Node) *node.Node {
	index := rand.Intn(len(view))
	i := 0
	for _, node := range view {
		if i == index {
			return node
		}
		i++
	}
	panic("Must not get here!")
}

func (ag *agent) addNodeActiveView(node *node.Node) {
	if node.Id == ag.id {
		return
	}
	if _, existed := ag.aView[node.Id]; existed {
		return
	}
	if len(ag.aView) == ag.cfg.AViewSize {
		n := chooseRandomNode(ag.aView)
		ag.disconnect(n)
		delete(ag.aView, n.Id)
		ag.addNodePassiveView(n)
	}
	ag.aView[node.Id] = node
}

func (ag *agent) addNodePassiveView(node *node.Node) {
	if node.Id == ag.id {
		return
	}
	if _, existed := ag.aView[node.Id]; existed {
		return
	}
	if _, existed := ag.pView[node.Id]; existed {
		return
	}
	if len(ag.pView) == ag.cfg.PViewSize {
		n := chooseRandomNode(ag.pView)
		delete(ag.pView, n.Id)
	}
	ag.pView[node.Id] = node
}

// handleJoin() handles Join message. If it accepts the request, it will add
// the node in the active view. As specified by the protocol, a node should
// always accept Join requests.
func (ag *agent) handleJoin(conn *net.TCPConn, msg *message.Join) {
	newNode := &node.Node{
		Id:   msg.GetId(),
		Addr: conn.RemoteAddr().String(),
		Conn: conn,
	}

	ag.mua.Lock()
	ag.mup.Lock()
	defer ag.mua.Unlock()
	defer ag.mup.Unlock()

	ag.addNodeActiveView(newNode)
	go ag.serveConn(newNode.Conn)

	// Send ForwardJoin message to all other the nodes in the active view.
	for _, node := range ag.aView {
		if node == newNode {
			continue
		}
		ag.forwardJoin(node, uint32(rand.Intn(ag.cfg.ARWL))) // TODO(yifan): go ag.forwardJoin()
	}
}

// handleNeighbor() handles Neighbor message. If the request is high priority,
// the receiver will always accept the request and add the node to its active view.
// If the request is low priority, then the request will only be accepted when
// there are empty slot in the active view.
func (ag *agent) handleNeighbor(conn *net.TCPConn, msg *message.Neighbor) {
	newNode := &node.Node{
		Id:   msg.GetId(),
		Addr: conn.RemoteAddr().String(),
		Conn: conn,
	}

	ag.mua.Lock()
	ag.mup.Lock()
	defer ag.mua.Unlock()
	defer ag.mup.Unlock()

	if len(ag.aView) == ag.cfg.AViewSize {
		if msg.GetPriority() == message.Neighbor_Low {
			ag.rejectNeighbor(newNode) // TODO(yifan): go ag.rejectNeighbor()
			// TODO(yifan): Add the node to passive view.
			return
		}
	}
	ag.addNodeActiveView(newNode)
	go ag.serveConn(newNode.Conn)
	ag.acceptNeighbor(newNode) // TODO(yifan): go ag.acceptNeighbor()
	return
}

// handleForwardJoin() handles the ForwardJoin message, and decides whether
// it will add the original sender to the active view or passive view.
func (ag *agent) handleForwardJoin(msg *message.ForwardJoin) {
	from, ttl := msg.GetId(), msg.GetTtl()
	newNode := &node.Node{
		Id:   msg.GetSourceId(),
		Addr: msg.GetSourceAddr(),
	}

	ag.mua.Lock()
	ag.mup.Lock()
	defer ag.mua.Unlock()
	defer ag.mup.Unlock()

	if ttl == 0 || len(ag.aView) == 1 { // TODO(yifan): Loose this?
		ag.neighbor(newNode, message.Neighbor_High)
		return
	}
	if ttl == uint32(ag.cfg.PRWL) {
		ag.addNodePassiveView(newNode)
	}
	for i, node := range ag.aView {
		if i == from {
			continue
		}
		ag.forwardJoin(node, ttl-1) // TODO(yifan): go ag.forwardJoin()
	}
	return
}

// handleDisconnect() handles Disconnect message. It will replace the node
// with another node from the passive view. And send Neighbor message to it.
func (ag *agent) handleDisconnect(msg *message.Disconnect) {
	id := msg.GetId()

	ag.mua.Lock()
	ag.mup.Lock()
	defer ag.mua.Unlock()
	defer ag.mup.Unlock()

	node, existed := ag.aView[id]
	if !existed {
		return
	}
	ag.pView[id] = node
	return
}

// handleShuffle() handles Shuffle message. It will send back a ShuffleReply
// message and update it's views.
func (ag *agent) handleShuffle(msg *message.Shuffle) {
	fmt.Println("Fill me in")
	return
}

// handleShuffleReply() handles ShuffleReply message. It will update it's views.
func (ag *agent) handleShuffleReply(msg *message.ShuffleReply) {
	fmt.Println("Fill me in")
	return
}

// handleUserMessage() handles user defined messages. It will forward the message
// to the nodes in its active view.
func (ag *agent) handleUserMessage(msg *message.UserMessage) {
	ag.mua.Lock()
	defer ag.mua.Unlock()

	for _, node := range ag.aView {
		ag.userMessage(node, msg) // TODO(yifan) go ag.userMessage
	}
	return
}

// Join joins the node to the cluster by contacting the nodes provied in the
// list.
func (ag *agent) Join(addr ...string) error {
	return fmt.Errorf("Fill me in")
}

// Leave causes the agent to leave the cluster.
func (ag *agent) Leave() error {
	return fmt.Errorf("Fill me in")
}

// Broadcast broadcasts a message to the cluster.
func (ag *agent) Broadcast(msg []byte) error {
	return fmt.Errorf("Fill me in")
}

// Count does a broadcast and returns a channel of
// nodes, which can be used to compute the broadcast
// delay.
func (ag *agent) Count(addr string) (chan *node.Node, error) {
	return nil, fmt.Errorf("Fill me in")
}
<commit_msg>Added some doc.<commit_after>package agent

import (
	"fmt"
	"math/rand" // TODO(yifan): Need to change this??
	"net"
	"sync"

	"github.com/go-distributed/gog/codec"
	"github.com/go-distributed/gog/config"
	"github.com/go-distributed/gog/message"
	"github.com/go-distributed/gog/node"

	log "github.com/golang/glog"
)

// Agent describes the interface of an agent.
type Agent interface {
	// Serve starts a standalone agent, waiting for
	// incoming connections.
	Serve() error
	// Join joins the agent to the cluster.
	Join(addr ...string) error
	// Leave causes the agent to leave the cluster.
	Leave() error
	// Broadcast broadcasts a message to the cluster.
	Broadcast(msg []byte) error
	// Count does a broadcast and returns a channel of
	// nodes, which can be used to compute the broadcast
	// delay.
	Count(addr string) (chan *node.Node, error)
}

// agent implements the Agent interface.
type agent struct {
	// The id of the agent.
	id string
	// Configuration.
	cfg *config.Config
	// Active View.
	mua   sync.Mutex
	aView map[string]*node.Node
	// Passive View.
	mup   sync.Mutex
	pView map[string]*node.Node
	// TCP listener.
	ln *net.TCPListener
	// The codec.
	codec codec.Codec
}

// NewAgent creates a new agent.
func NewAgent(cfg *config.Config) Agent {
	// Create a codec and register messages.
	codec := codec.NewProtobufCodec()
	codec.Register(&message.UserMessage{})
	codec.Register(&message.Join{})
	codec.Register(&message.ForwardJoin{})
	codec.Register(&message.Disconnect{})
	codec.Register(&message.Shuffle{})
	codec.Register(&message.ShuffleReply{})

	return &agent{
		cfg:   cfg,
		codec: codec,
		aView: make(map[string]*node.Node),
		pView: make(map[string]*node.Node),
	}
}

// Serve starts a standalone agent, waiting for
// incoming connections.
func (ag *agent) Serve() error {
	ln, err := net.ListenTCP(ag.cfg.Net, ag.cfg.LocalTCPAddr)
	if err != nil {
		return err
	}
	ag.ln = ln
	// TODO(yifan): Added a tick to trigger shuffle periodically.
	ag.serve()
	return nil
}

// serveNewConn listens on the TCP listener, waits for incoming connections.
func (ag *agent) serve() {
	for {
		conn, err := ag.ln.AcceptTCP()
		if err != nil {
			log.Errorf("Agent.serve(): Failed to accept\n")
			continue
		}
		// TODO(Yifan): Set read time ount.
		go ag.serveConn(conn)
	}
}

// serveConn() serves a connection.
func (ag *agent) serveConn(conn *net.TCPConn) {
	defer conn.Close()
	for {
		msg, err := ag.codec.ReadMsg(conn)
		if err != nil {
			log.Errorf("Agent.serveConn(): Failed to decode message: %v\n", err)
			// TODO(yifan): Now what? Drop the conn?
			// Update the view?
			return
		}
		// Dispatch messages.
		switch t := msg.(type) {
		case *message.Join:
			ag.handleJoin(conn, msg.(*message.Join))
		case *message.Neighbor:
			ag.handleNeighbor(conn, msg.(*message.Neighbor))
		case *message.ForwardJoin:
			ag.handleForwardJoin(msg.(*message.ForwardJoin))
		case *message.Disconnect:
			ag.handleDisconnect(msg.(*message.Disconnect))
			return
		case *message.Shuffle:
			ag.handleShuffle(msg.(*message.Shuffle))
		case *message.UserMessage:
			ag.handleUserMessage(msg.(*message.UserMessage))
		default:
			log.Errorf("Agent.serveConn(): Unexpected message type: %T\n", t)
			// TODO(yifan): Now what? Drop the conn?
			// Update the view?
			return
		}
	}
}

// chooseRandomNode() chooses a random node from the active view
// or passive view.
func chooseRandomNode(view map[string]*node.Node) *node.Node {
	index := rand.Intn(len(view))
	i := 0
	for _, node := range view {
		if i == index {
			return node
		}
		i++
	}
	panic("Must not get here!")
}

// addNodeActiveView() adds the node to the active view. If
// the active view is full, it will move one node from the active
// view to the passive view before adding the node.
// If the passive view is also full, it will drop a random node
// in the passive view.
func (ag *agent) addNodeActiveView(node *node.Node) {
	if node.Id == ag.id {
		return
	}
	if _, existed := ag.aView[node.Id]; existed {
		return
	}
	if len(ag.aView) == ag.cfg.AViewSize {
		n := chooseRandomNode(ag.aView)
		ag.disconnect(n)
		delete(ag.aView, n.Id)
		ag.addNodePassiveView(n)
	}
	ag.aView[node.Id] = node
}

// addNodePassiveView() adds a node to the passive view. If
// the passive view is full, it will drop a random node.
func (ag *agent) addNodePassiveView(node *node.Node) {
	if node.Id == ag.id {
		return
	}
	if _, existed := ag.aView[node.Id]; existed {
		return
	}
	if _, existed := ag.pView[node.Id]; existed {
		return
	}
	if len(ag.pView) == ag.cfg.PViewSize {
		n := chooseRandomNode(ag.pView)
		delete(ag.pView, n.Id)
	}
	ag.pView[node.Id] = node
}

// handleJoin() handles Join message. If it accepts the request, it will add
// the node in the active view. As specified by the protocol, a node should
// always accept Join requests.
func (ag *agent) handleJoin(conn *net.TCPConn, msg *message.Join) {
	newNode := &node.Node{
		Id:   msg.GetId(),
		Addr: conn.RemoteAddr().String(),
		Conn: conn,
	}

	ag.mua.Lock()
	ag.mup.Lock()
	defer ag.mua.Unlock()
	defer ag.mup.Unlock()

	ag.addNodeActiveView(newNode)
	go ag.serveConn(newNode.Conn)

	// Send ForwardJoin message to all other the nodes in the active view.
	for _, node := range ag.aView {
		if node == newNode {
			continue
		}
		ag.forwardJoin(node, uint32(rand.Intn(ag.cfg.ARWL))) // TODO(yifan): go ag.forwardJoin()
	}
}

// handleNeighbor() handles Neighbor message. If the request is high priority,
// the receiver will always accept the request and add the node to its active view.
// If the request is low priority, then the request will only be accepted when
// there are empty slot in the active view.
func (ag *agent) handleNeighbor(conn *net.TCPConn, msg *message.Neighbor) {
	newNode := &node.Node{
		Id:   msg.GetId(),
		Addr: conn.RemoteAddr().String(),
		Conn: conn,
	}

	ag.mua.Lock()
	ag.mup.Lock()
	defer ag.mua.Unlock()
	defer ag.mup.Unlock()

	if len(ag.aView) == ag.cfg.AViewSize {
		if msg.GetPriority() == message.Neighbor_Low {
			ag.rejectNeighbor(newNode) // TODO(yifan): go ag.rejectNeighbor()
			// TODO(yifan): Add the node to passive view.
			return
		}
	}
	ag.addNodeActiveView(newNode)
	go ag.serveConn(newNode.Conn)
	ag.acceptNeighbor(newNode) // TODO(yifan): go ag.acceptNeighbor()
	return
}

// handleForwardJoin() handles the ForwardJoin message, and decides whether
// it will add the original sender to the active view or passive view.
func (ag *agent) handleForwardJoin(msg *message.ForwardJoin) {
	from, ttl := msg.GetId(), msg.GetTtl()
	newNode := &node.Node{
		Id:   msg.GetSourceId(),
		Addr: msg.GetSourceAddr(),
	}

	ag.mua.Lock()
	ag.mup.Lock()
	defer ag.mua.Unlock()
	defer ag.mup.Unlock()

	if ttl == 0 || len(ag.aView) == 1 { // TODO(yifan): Loose this?
		ag.neighbor(newNode, message.Neighbor_High)
		return
	}
	if ttl == uint32(ag.cfg.PRWL) {
		ag.addNodePassiveView(newNode)
	}
	for i, node := range ag.aView {
		if i == from {
			continue
		}
		ag.forwardJoin(node, ttl-1) // TODO(yifan): go ag.forwardJoin()
	}
	return
}

// handleDisconnect() handles Disconnect message. It will replace the node
// with another node from the passive view. And send Neighbor message to it.
func (ag *agent) handleDisconnect(msg *message.Disconnect) {
	id := msg.GetId()

	ag.mua.Lock()
	ag.mup.Lock()
	defer ag.mua.Unlock()
	defer ag.mup.Unlock()

	node, existed := ag.aView[id]
	if !existed {
		return
	}
	ag.pView[id] = node
	return
}

// handleShuffle() handles Shuffle message. It will send back a ShuffleReply
// message and update it's views.
func (ag *agent) handleShuffle(msg *message.Shuffle) {
	fmt.Println("Fill me in")
	return
}

// handleShuffleReply() handles ShuffleReply message. It will update it's views.
func (ag *agent) handleShuffleReply(msg *message.ShuffleReply) {
	fmt.Println("Fill me in")
	return
}

// handleUserMessage() handles user defined messages. It will forward the message
// to the nodes in its active view.
func (ag *agent) handleUserMessage(msg *message.UserMessage) {
	ag.mua.Lock()
	defer ag.mua.Unlock()

	for _, node := range ag.aView {
		ag.userMessage(node, msg) // TODO(yifan) go ag.userMessage
	}
	return
}

// Join joins the node to the cluster by contacting the nodes provied in the
// list.
func (ag *agent) Join(addr ...string) error {
	return fmt.Errorf("Fill me in")
}

// Leave causes the agent to leave the cluster.
func (ag *agent) Leave() error {
	return fmt.Errorf("Fill me in")
}

// Broadcast broadcasts a message to the cluster.
func (ag *agent) Broadcast(msg []byte) error {
	return fmt.Errorf("Fill me in")
}

// Count does a broadcast and returns a channel of
// nodes, which can be used to compute the broadcast
// delay.
func (ag *agent) Count(addr string) (chan *node.Node, error) {
	return nil, fmt.Errorf("Fill me in")
}
<|endoftext|>


<commit_before>package coremain

// Various CoreDNS constants.
const (
	CoreVersion = "1.6.7"
	coreName    = "CoreDNS"
	serverType  = "dns"
)
<commit_msg>release: up the version to 1.6.8 (#3772)<commit_after>package coremain

// Various CoreDNS constants.
const (
	CoreVersion = "1.6.8"
	coreName    = "CoreDNS"
	serverType  = "dns"
)
<|endoftext|>