<commit_before>// Dependency Manager for Golang Projects
// Author: Nicholas Capo <nicholas@vubeology.com>
//
// For help run 'depman help'
package main

// Copyright 2013 Vubeology, Inc.

//===============================================

import (
	"flag"
	"log"
	"strings"
	"fmt"
	"github.com/vube/depman/add"
	"github.com/vube/depman/colors"
	"github.com/vube/depman/create"
	"github.com/vube/depman/dep"
	"github.com/vube/depman/install"
	"github.com/vube/depman/update"
	"github.com/vube/depman/upgrade"
	"github.com/vube/depman/util"
	"github.com/vube/depman/showfrozen"
)

// Version number
const VERSION string = "2.5.1"

//===============================================

func main() {
	var result int
	var help bool
	var path string
	var command string
	var arguments []string
	var deps dep.DependencyMap
	var err error

	log.SetFlags(0)

	flag.BoolVar(&help, "help", false, "Display help")
	flag.StringVar(&path, "path", ".", "Directory or full path to deps.json")
	util.Parse()

	util.Version(VERSION)

	path = util.GetPath(path)

	if flag.NArg() > 0 {
		command = strings.ToLower(flag.Arg(0))
	}

	if flag.NArg() > 1 {
		arguments = flag.Args()[1:]
	}

	if help {
		command = "help"
	}

	// switch to check for deps.json
	switch command {
	case "init", "help":
		// don't check for deps.json
	default:
		util.CheckPath(path)
		deps, err = dep.Read(path)
		if err != nil {
			util.Fatal(colors.Red("Error Reading deps.json: " + err.Error()))
		}
	}

	// switch to exec the sub command
	switch command {
	case "init", "create":
		result = create.Create(path)
	case "add":
		if len(arguments) < 1 {
			util.Print(colors.Red("Add command requires 1 argument: Add [nickname]"))
			Help()
		} else {
			add.Add(deps, arguments[0])
		}

	case "update":
		if len(arguments) < 2 {
			util.Print(colors.Red("Update command requires 2 arguments: Update [nickname] [branch]"))
			Help()
		} else {
			update.Update(deps, arguments[0], arguments[1])
		}
	case "install", "":
		result = install.Install(deps)
	case "self-upgrade":
		upgrade.Self()
	case "show-frozen":
		var recursive bool
		flagset := flag.NewFlagSet("show-frozen", flag.ExitOnError)
		flagset.BoolVar(&recursive, "recursive", false, "descend recursively (depth-first) into dependencies")
		flagset.Parse(flag.Args()[1:])

		if recursive {
			fmt.Println(showfrozen.ReadRecursively(deps, nil))
		} else {
			fmt.Print(showfrozen.Read(deps))
		}
	default:
		result = 1
		log.Println(colors.Red("Unknown Command: " + command))
		fallthrough
	case "help":
		Help()
	}

	if result == 0 {
		util.Print("Success")
	}

	util.OsExit(result)
}

//===============================================

// Help prints the help message for depman
func Help() {
	log.Println("")
	log.Println("Commands:")
	log.Println("   Init                        : Create an empty deps.json (not yet implemented)")
	log.Println("   Add [nickname]              : Add a dependency (interactive)")
	log.Println("   Install                     : Install all the dependencies listed in deps.json (default)")
	log.Println("   Update [nickname] [branch]  : Update [nickname] to use the latest commit in [branch]")
	log.Println("   Self-Upgrade                : Upgrade depman to the latest version on the master branch")
	log.Println("   Help                        : Display this help")
	log.Println("   show-frozen                 : Show dependencies as resolved to commit IDs")
	log.Println("")
	log.Println("Example: depman --verbose install")
	log.Println("")
	//log.Println("   freeze                      : For each dependency change tag and branch versions to commits (not yet implemented)")
	log.Println("Options:")
	flag.PrintDefaults()
}
<commit_msg>Bump version number and gofmt<commit_after>// Dependency Manager for Golang Projects
// Author: Nicholas Capo <nicholas@vubeology.com>
//
// For help run 'depman help'
package main

// Copyright 2013 Vubeology, Inc.

//===============================================

import (
	"flag"
	"fmt"
	"github.com/vube/depman/add"
	"github.com/vube/depman/colors"
	"github.com/vube/depman/create"
	"github.com/vube/depman/dep"
	"github.com/vube/depman/install"
	"github.com/vube/depman/showfrozen"
	"github.com/vube/depman/update"
	"github.com/vube/depman/upgrade"
	"github.com/vube/depman/util"
	"log"
	"strings"
)

// Version number
const VERSION string = "2.6.0"

//===============================================

func main() {
	var result int
	var help bool
	var path string
	var command string
	var arguments []string
	var deps dep.DependencyMap
	var err error

	log.SetFlags(0)

	flag.BoolVar(&help, "help", false, "Display help")
	flag.StringVar(&path, "path", ".", "Directory or full path to deps.json")
	util.Parse()

	util.Version(VERSION)

	path = dep.GetPath(path)

	if flag.NArg() > 0 {
		command = strings.ToLower(flag.Arg(0))
	}

	if flag.NArg() > 1 {
		arguments = flag.Args()[1:]
	}

	if help {
		command = "help"
	}

	// switch to check for deps.json
	switch command {
	case "init", "help":
		// don't check for deps.json
	default:
		util.CheckPath(path)
		deps, err = dep.Read(path)
		if err != nil {
			util.Fatal(colors.Red("Error Reading deps.json: " + err.Error()))
		}
	}

	// switch to exec the sub command
	switch command {
	case "init", "create":
		result = create.Create(path)
	case "add":
		if len(arguments) < 1 {
			util.Print(colors.Red("Add command requires 1 argument: Add [nickname]"))
			Help()
		} else {
			add.Add(deps, arguments[0])
		}

	case "update":
		if len(arguments) < 2 {
			util.Print(colors.Red("Update command requires 2 arguments: Update [nickname] [branch]"))
			Help()
		} else {
			update.Update(deps, arguments[0], arguments[1])
		}
	case "install", "":
		result = install.Install(deps)
	case "self-upgrade":
		upgrade.Self()
	case "show-frozen":
		var recursive bool
		flagset := flag.NewFlagSet("show-frozen", flag.ExitOnError)
		flagset.BoolVar(&recursive, "recursive", false, "descend recursively (depth-first) into dependencies")
		flagset.Parse(flag.Args()[1:])

		if recursive {
			fmt.Println(showfrozen.ReadRecursively(deps, nil))
		} else {
			fmt.Print(showfrozen.Read(deps))
		}
	default:
		result = 1
		log.Println(colors.Red("Unknown Command: " + command))
		fallthrough
	case "help":
		Help()
	}

	if result == 0 {
		util.Print("Success")
	}

	util.OsExit(result)
}

//===============================================

// Help prints the help message for depman
func Help() {
	log.Println("")
	log.Println("Commands:")
	log.Println("   Init                        : Create an empty deps.json (not yet implemented)")
	log.Println("   Add [nickname]              : Add a dependency (interactive)")
	log.Println("   Install                     : Install all the dependencies listed in deps.json (default)")
	log.Println("   Update [nickname] [branch]  : Update [nickname] to use the latest commit in [branch]")
	log.Println("   Self-Upgrade                : Upgrade depman to the latest version on the master branch")
	log.Println("   Help                        : Display this help")
	log.Println("   show-frozen                 : Show dependencies as resolved to commit IDs")
	log.Println("")
	log.Println("Example: depman --verbose install")
	log.Println("")
	//log.Println("   freeze                      : For each dependency change tag and branch versions to commits (not yet implemented)")
	log.Println("Options:")
	flag.PrintDefaults()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/mitchellh/colorstring"
	"github.com/urfave/cli"
	"net/http"
	"os"
	"strings"
)

type NodeService struct {
	Service string
	Address string
	Port    int
	Tags    []string
}

type ConsulNode struct {
	Node     string
	Services []NodeService
}

func main() {
	app := cli.NewApp()
	app.Usage = "Decode micro registry's tag of metadata and endpoint"
	app.Action = dec
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "data, d",
			Usage: "encoded string",
		},
		cli.StringFlag{
			Name:  "url, u",
			Usage: "consul address",
			Value: "http://127.0.0.1:8500/v1/internal/ui/nodes?dc=dc1&token=",
		},
		cli.StringSliceFlag{
			Name:  "service, s",
			Usage: "services you wanted to decode",
		},
		cli.StringSliceFlag{
			Name:  "keyword, k",
			Usage: "highlight keywords",
		},
	}

	if err := app.Run(os.Args); err != nil {
		fmt.Println(err)
		return
	}
}

func dec(c *cli.Context) (err error) {

	data := c.String("data")
	keywords := c.StringSlice("keyword")

	if len(data) > 0 {
		return decData(data, keywords)
	}

	url := c.String("url")
	if len(url) == 0 {
		return
	}

	serviceList := c.StringSlice("service")
	var srvMap map[string]bool
	if len(serviceList) > 0 {
		srvMap = make(map[string]bool)
		for i := 0; i < len(serviceList); i++ {
			srvMap[serviceList[i]] = true
		}
	}

	var resp *http.Response
	if resp, err = http.DefaultClient.Get(url); err != nil {
		return
	}

	defer resp.Body.Close()

	nodes := []ConsulNode{}

	decoder := json.NewDecoder(resp.Body)

	if err = decoder.Decode(&nodes); err != nil {
		return
	}

	for i := 0; i < len(nodes); i++ {
		for j := 0; j < len(nodes[i].Services); j++ {
			service := nodes[i].Services[j]
			if srvMap != nil {
				if _, exist := srvMap[service.Service]; !exist {
					continue
				}
			}

			metadata, endpoints := decodeTags(service.Tags)
			dataMap := map[string]interface{}{
				"service":   service.Service,
				"address":   service.Address,
				"port":      service.Port,
				"metadata":  metadata,
				"endpoints": endpoints,
			}

			var out []byte
			if out, err = json.MarshalIndent(dataMap, "", "    "); err != nil {
				return
			}

			strJSON := string(out)
			for i := 0; i < len(keywords); i++ {
				strJSON = strings.Replace(strJSON, keywords[i], "[yellow]"+keywords[i]+"[white]", -1)
			}

			colorstring.Println(strJSON)
		}
	}
	return
}

func decData(data string, keywords []string) (err error) {
	data = strings.TrimSpace(data)

	tags := strings.Split(data, ",")
	metadata, endpoints := decodeTags(tags)

	dataMap := map[string]interface{}{"metadata": metadata, "endpoints": endpoints}

	var out []byte
	if out, err = json.MarshalIndent(dataMap, "", "    "); err != nil {
		return
	}

	strJSON := string(out)
	for i := 0; i < len(keywords); i++ {
		strJSON = strings.Replace(strJSON, keywords[i], "[yellow]"+keywords[i]+"[white]", -1)
	}

	colorstring.Println(strJSON)

	return
}

func decodeTags(tags []string) (metadata interface{}, endpoints interface{}) {

	var metadataTags []string
	var endpointTags []string

	for i := 0; i < len(tags); i++ {
		tag := strings.TrimSpace(tags[i])
		if strings.HasPrefix(tag, "t") {
			metadataTags = append(metadataTags, tag)
		} else if strings.HasPrefix(tag, "e") {
			endpointTags = append(endpointTags, tag)
		}
	}

	metadata = decodeMetadata(metadataTags)
	endpoints = decodeEndpoints(endpointTags)
	return
}
<commit_msg>improve color and format<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/mitchellh/colorstring"
	"github.com/urfave/cli"
	"net/http"
	"os"
	"strings"
)

type NodeService struct {
	Service string
	Address string
	Port    int
	Tags    []string
}

type ConsulNode struct {
	Node     string
	Services []NodeService
}

func main() {
	app := cli.NewApp()
	app.Usage = "Decode micro registry's tag of metadata and endpoint"
	app.Action = dec
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "data, d",
			Usage: "encoded string",
		},
		cli.StringFlag{
			Name:  "url, u",
			Usage: "consul address",
			Value: "http://127.0.0.1:8500/v1/internal/ui/nodes?dc=dc1&token=",
		},
		cli.StringSliceFlag{
			Name:  "service, s",
			Usage: "services you wanted to decode",
		},
		cli.StringSliceFlag{
			Name:  "keyword, k",
			Usage: "highlight keywords",
		},
	}

	if err := app.Run(os.Args); err != nil {
		fmt.Println(err)
		return
	}
}

func dec(c *cli.Context) (err error) {

	data := c.String("data")
	keywords := c.StringSlice("keyword")

	if len(data) > 0 {
		return decData(data, keywords)
	}

	url := c.String("url")
	if len(url) == 0 {
		return
	}

	serviceList := c.StringSlice("service")
	var srvMap map[string]bool
	if len(serviceList) > 0 {
		srvMap = make(map[string]bool)
		for i := 0; i < len(serviceList); i++ {
			srvMap[serviceList[i]] = true
		}
	}

	var resp *http.Response
	if resp, err = http.DefaultClient.Get(url); err != nil {
		return
	}

	defer resp.Body.Close()

	nodes := []ConsulNode{}

	decoder := json.NewDecoder(resp.Body)

	if err = decoder.Decode(&nodes); err != nil {
		return
	}

	for i := 0; i < len(nodes); i++ {
		for j := 0; j < len(nodes[i].Services); j++ {
			service := nodes[i].Services[j]
			if srvMap != nil {
				if _, exist := srvMap[service.Service]; !exist {
					continue
				}
			}

			metadata, endpoints := decodeTags(service.Tags)
			dataMap := map[string]interface{}{
				"service":   service.Service,
				"address":   service.Address,
				"port":      service.Port,
				"metadata":  metadata,
				"endpoints": endpoints,
			}

			var out []byte
			if out, err = json.MarshalIndent(dataMap, "", "    "); err != nil {
				return
			}

			strJSON := string(out)
			for i := 0; i < len(keywords); i++ {
				strJSON = strings.Replace(strJSON, keywords[i], "[light_yellow][bold]"+keywords[i]+"[reset]", -1)
			}

			colorstring.Println(strJSON)
		}
	}
	return
}

func decData(data string, keywords []string) (err error) {
	data = strings.TrimSpace(data)

	tags := strings.Split(data, ",")
	metadata, endpoints := decodeTags(tags)

	dataMap := map[string]interface{}{"metadata": metadata, "endpoints": endpoints}

	var out []byte
	if out, err = json.MarshalIndent(dataMap, "", "    "); err != nil {
		return
	}

	strJSON := string(out)
	for i := 0; i < len(keywords); i++ {
		strJSON = strings.Replace(strJSON, keywords[i], "[light_yellow][bold]"+keywords[i]+"[reset]", -1)
	}

	colorstring.Println(strJSON)

	return
}

func decodeTags(tags []string) (metadata interface{}, endpoints interface{}) {

	var metadataTags []string
	var endpointTags []string

	for i := 0; i < len(tags); i++ {
		tag := strings.TrimSpace(tags[i])
		if strings.HasPrefix(tag, "t") {
			metadataTags = append(metadataTags, tag)
		} else if strings.HasPrefix(tag, "e") {
			endpointTags = append(endpointTags, tag)
		}
	}

	metadata = decodeMetadata(metadataTags)
	endpoints = decodeEndpoints(endpointTags)
	return
}
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Samuel Giles
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package main

import (
	"flag"
	"errors"
	"net"
	"crypto/tls"
	"fmt"
	"os"
	"io"
	"github.com/samgiles/bytetrie"
)

var numberOfBackendConnections = flag.Int("beconnections", 1, "Number of concurrent connections to open to the Graphite backend")
var listenAddressString = flag.String("listen", ":9090", "Address and port to bind listener to")
var remoteAddressString = flag.String("remote", "", "Address and port of remote graphite instance")
var acceptKeyString     = flag.String("apikey", "MYAPIKEY", "API key to accept")

var certificateFile = flag.String("cert", "", "Path to .pem certificate")
var keyFile         = flag.String("key", "", "Path to .pem key file")

var searchRoot = new(bytetrie.Node)

func main() {
	flag.Parse()

	if *remoteAddressString == "" {
		warn("Flag: 'remote' is required")
		flag.Usage()
		os.Exit(1)
	}

	if *acceptKeyString == "" {
		warn("Flag: 'apiKey' is required")
		flag.Usage()
		os.Exit(1)
	}

	searchRoot.Insert([]byte(*acceptKeyString))
	multiplexers := initialiseMultiplexers(*numberOfBackendConnections, *remoteAddressString)

	if *certificateFile == "" || *keyFile == "" {
		warn("No certiciate file or key file found, not using TLS")
		listener, err := net.Listen("tcp", *listenAddressString)
		check(err)
		startListening(listener, multiplexers)
	} else {
		cert, err := tls.LoadX509KeyPair(*certificateFile, *keyFile)
		check(err)
		tlsConfig := tls.Config{Certificates: []tls.Certificate{cert}}
		listener, err := tls.Listen("tcp", *listenAddressString, &tlsConfig)
		check(err)
		startListening(listener, multiplexers)
	}

}

func initialiseMultiplexers(count int, remoteAddress string) []multiplexer {
	multiplexers := make([]multiplexer, count)

	// Initialise m
	fmt.Printf("Starting %d backend connection(s)\n", count)
	for i := 0; i < count; i++ {
		remoteConnection, err := net.Dial("tcp", remoteAddress)
		check(err)

		multiplexers[i] = multiplexer {
			remoteConnection: remoteConnection,
			erred:              false,
			closesig:           make(chan bool),
			id:                 i,
		}
	}

	return multiplexers
}

func startListening(listener net.Listener, multiplexers []multiplexer) {
	var nextMultiplexer = 0
	var connectionId = 0
	fmt.Printf("Starting listener\n");
	for {
		connection, err := listener.Accept()
		fmt.Printf("Accepted new connection: %d\r", connectionId + 1);
		if err != nil {
			warn("Failed to accept connection '%s'\n", err)
			continue
		}

		multiplexer := multiplexers[nextMultiplexer]
		p := &proxy {
			multiplexer:      multiplexer,
			localConnection:  connection,
			erred:            false,
			closesig:         make(chan bool),
			prefix:           connectionId,
		}

		connectionId++

		// Round robin select the next connection to multiplex this new
		// incoming connection onto
		nextMultiplexer++

		if nextMultiplexer == len(multiplexers) {
			nextMultiplexer = 0
		}

		go p.start()
	}
}

// A multiplexer represents a single TCP connection used to multiplex many
// connections
type multiplexer struct {
	remoteConnection  net.Conn
	erred              bool
	closesig           chan bool
	id                 int
}

func (m *multiplexer) Write(bytes []byte) (int, error) {
	return m.remoteConnection.Write(bytes)
}

type proxy struct {
	multiplexer multiplexer
	localConnection  net.Conn
	erred            bool
	closesig         chan bool
	prefix           int
}

func (p *proxy) start() {
	defer p.localConnection.Close()

	// We only care about one way communication, Graphite never replies
	go p.pipe()

	//wait for close...
	<-p.closesig
}

func (p *proxy) pipe() {
	// 64k buffer
	buffer := make([]byte, 0xffff)
	src := p.localConnection
	dest := p.multiplexer
	var offset = 0

	for {
		numberOfBytes, err := src.Read(buffer[offset:])

		if err != nil {
			if err == io.EOF {
				p.closesig <-true
			} else {
				p.err("Read failed '%s'\n", err)
			}

			return
		}

		receivedBytes := buffer[:numberOfBytes]

		metrics, remaining, err := ParseBuffer(receivedBytes, searchRoot)
		if err != nil {
			p.err("Connection dropped terminated '%s'\n", err)
			return
		}

		offset = len(remaining)
		copy(buffer[:offset], remaining)

		//write out result
		for _, element := range metrics {
			_, err = dest.Write(element)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
		}
	}
}

func (p *proxy) err(s string, err error) {
	if p.erred {
		return
	}

	warn("Connection Error[%d]: " + s, p.prefix, err)

	p.closesig <- true
	p.erred = true
}

func check(err error) {
	if err != nil {
		warn(err.Error())
		os.Exit(1)
	}
}

func warn(f string, args ...interface{}) {
	fmt.Printf(f+"\n", args...)
}

// Split the buffer by '\n' (0x0A) characters, return an byte[][] of
// indicating each metric, and byte[] of the remaining parts of the buffer
func ParseBuffer(buffer []byte, apiKeys *bytetrie.Node) ([][]byte, []byte, error) {
	metrics := make([][]byte, 8)

	var metricBufferCapacity uint = 0xff
	metricBuffer := make([]byte, metricBufferCapacity)

	var metricSize uint =  0
	var metricBufferUsage uint = 0
	var totalMetrics int = 0
	var currentSearchNode = apiKeys
	var byteAccepted = false

	var rootNamespaceAccepted = false

	for _, b := range buffer {

		if b != '.' && !rootNamespaceAccepted {
			currentSearchNode, byteAccepted = currentSearchNode.Accepts(b)
			if !byteAccepted {
				return nil, nil,  errors.New(fmt.Sprintf("Invalid API key: %s*\n", metrics[totalMetrics]))
			}
		} else {
			if !currentSearchNode.IsLeaf {
				return nil, nil,  errors.New(fmt.Sprintf("Invalid API key: %s\n", metrics[totalMetrics]))
			} else {
				rootNamespaceAccepted = true
			}
		}

		if metricBufferUsage == metricBufferCapacity {
			newMetricBufferCapacity := (metricBufferCapacity + 1) * 2
			newBuffer := make([]byte, newMetricBufferCapacity, newMetricBufferCapacity)
			copy(newBuffer, metricBuffer)
			metricBuffer = newBuffer
			metricBufferCapacity = newMetricBufferCapacity
		}

		metricBuffer[metricBufferUsage] = b
		metricSize++
		metricBufferUsage++

		if b == '\n' {
			metrics[totalMetrics] = metricBuffer[metricBufferUsage - metricSize:metricBufferUsage]
			totalMetrics++

			if totalMetrics == cap(metrics) {
				newMetrics  := make([][]byte, cap(metrics), (cap(metrics) + 1) * 2)
				copy(newMetrics, metrics)
				metrics = newMetrics
			}

			metricSize = 0;
			currentSearchNode = apiKeys;
			rootNamespaceAccepted = false
		}
	}

	return metrics[:totalMetrics], metricBuffer[(metricBufferUsage - metricSize):metricBufferUsage], nil
}
<commit_msg>Equivalent logic<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Samuel Giles
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package main

import (
	"flag"
	"errors"
	"net"
	"crypto/tls"
	"fmt"
	"os"
	"io"
	"github.com/samgiles/bytetrie"
)

var numberOfBackendConnections = flag.Int("beconnections", 1, "Number of concurrent connections to open to the Graphite backend")
var listenAddressString = flag.String("listen", ":9090", "Address and port to bind listener to")
var remoteAddressString = flag.String("remote", "", "Address and port of remote graphite instance")
var acceptKeyString     = flag.String("apikey", "MYAPIKEY", "API key to accept")

var certificateFile = flag.String("cert", "", "Path to .pem certificate")
var keyFile         = flag.String("key", "", "Path to .pem key file")

var searchRoot = new(bytetrie.Node)

func main() {
	flag.Parse()

	if *remoteAddressString == "" {
		warn("Flag: 'remote' is required")
		flag.Usage()
		os.Exit(1)
	}

	if *acceptKeyString == "" {
		warn("Flag: 'apiKey' is required")
		flag.Usage()
		os.Exit(1)
	}

	searchRoot.Insert([]byte(*acceptKeyString))
	multiplexers := initialiseMultiplexers(*numberOfBackendConnections, *remoteAddressString)

	if *certificateFile == "" || *keyFile == "" {
		warn("No certiciate file or key file found, not using TLS")
		listener, err := net.Listen("tcp", *listenAddressString)
		check(err)
		startListening(listener, multiplexers)
	} else {
		cert, err := tls.LoadX509KeyPair(*certificateFile, *keyFile)
		check(err)
		tlsConfig := tls.Config{Certificates: []tls.Certificate{cert}}
		listener, err := tls.Listen("tcp", *listenAddressString, &tlsConfig)
		check(err)
		startListening(listener, multiplexers)
	}

}

func initialiseMultiplexers(count int, remoteAddress string) []multiplexer {
	multiplexers := make([]multiplexer, count)

	// Initialise m
	fmt.Printf("Starting %d backend connection(s)\n", count)
	for i := 0; i < count; i++ {
		remoteConnection, err := net.Dial("tcp", remoteAddress)
		check(err)

		multiplexers[i] = multiplexer {
			remoteConnection: remoteConnection,
			erred:              false,
			closesig:           make(chan bool),
			id:                 i,
		}
	}

	return multiplexers
}

func startListening(listener net.Listener, multiplexers []multiplexer) {
	var nextMultiplexer = 0
	var connectionId = 0
	fmt.Printf("Starting listener\n");
	for {
		connection, err := listener.Accept()
		fmt.Printf("Accepted new connection: %d\r", connectionId + 1);
		if err != nil {
			warn("Failed to accept connection '%s'\n", err)
			continue
		}

		multiplexer := multiplexers[nextMultiplexer]
		p := &proxy {
			multiplexer:      multiplexer,
			localConnection:  connection,
			erred:            false,
			closesig:         make(chan bool),
			prefix:           connectionId,
		}

		connectionId++

		// Round robin select the next connection to multiplex this new
		// incoming connection onto
		nextMultiplexer++

		if nextMultiplexer == len(multiplexers) {
			nextMultiplexer = 0
		}

		go p.start()
	}
}

// A multiplexer represents a single TCP connection used to multiplex many
// connections
type multiplexer struct {
	remoteConnection  net.Conn
	erred              bool
	closesig           chan bool
	id                 int
}

func (m *multiplexer) Write(bytes []byte) (int, error) {
	return m.remoteConnection.Write(bytes)
}

type proxy struct {
	multiplexer multiplexer
	localConnection  net.Conn
	erred            bool
	closesig         chan bool
	prefix           int
}

func (p *proxy) start() {
	defer p.localConnection.Close()

	// We only care about one way communication, Graphite never replies
	go p.pipe()

	//wait for close...
	<-p.closesig
}

func (p *proxy) pipe() {
	// 64k buffer
	buffer := make([]byte, 0xffff)
	src := p.localConnection
	dest := p.multiplexer
	var offset = 0

	for {
		numberOfBytes, err := src.Read(buffer[offset:])

		if err != nil {
			if err == io.EOF {
				p.closesig <-true
			} else {
				p.err("Read failed '%s'\n", err)
			}

			return
		}

		receivedBytes := buffer[:numberOfBytes]

		metrics, remaining, err := ParseBuffer(receivedBytes, searchRoot)
		if err != nil {
			p.err("Connection dropped terminated '%s'\n", err)
			return
		}

		offset = len(remaining)
		copy(buffer[:offset], remaining)

		//write out result
		for _, element := range metrics {
			_, err = dest.Write(element)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
		}
	}
}

func (p *proxy) err(s string, err error) {
	if p.erred {
		return
	}

	warn("Connection Error[%d]: " + s, p.prefix, err)

	p.closesig <- true
	p.erred = true
}

func check(err error) {
	if err != nil {
		warn(err.Error())
		os.Exit(1)
	}
}

func warn(f string, args ...interface{}) {
	fmt.Printf(f+"\n", args...)
}

// Split the buffer by '\n' (0x0A) characters, return an byte[][] of
// indicating each metric, and byte[] of the remaining parts of the buffer
func ParseBuffer(buffer []byte, apiKeys *bytetrie.Node) ([][]byte, []byte, error) {
	metrics := make([][]byte, 8)

	var metricBufferCapacity uint = 0xff
	metricBuffer := make([]byte, metricBufferCapacity)

	var metricSize uint =  0
	var metricBufferUsage uint = 0
	var totalMetrics int = 0
	var currentSearchNode = apiKeys
	var byteAccepted = false

	var rootNamespaceAccepted = false

	for _, b := range buffer {

		if !(b == '.' || rootNamespaceAccepted) {
			currentSearchNode, byteAccepted = currentSearchNode.Accepts(b)
			if !byteAccepted {
				return nil, nil,  errors.New(fmt.Sprintf("Invalid API key: %s*\n", metrics[totalMetrics]))
			}
		} else {
			if !currentSearchNode.IsLeaf {
				return nil, nil,  errors.New(fmt.Sprintf("Invalid API key: %s\n", metrics[totalMetrics]))
			} else {
				rootNamespaceAccepted = true
			}
		}

		if metricBufferUsage == metricBufferCapacity {
			newMetricBufferCapacity := (metricBufferCapacity + 1) * 2
			newBuffer := make([]byte, newMetricBufferCapacity, newMetricBufferCapacity)
			copy(newBuffer, metricBuffer)
			metricBuffer = newBuffer
			metricBufferCapacity = newMetricBufferCapacity
		}

		metricBuffer[metricBufferUsage] = b
		metricSize++
		metricBufferUsage++

		if b == '\n' {
			metrics[totalMetrics] = metricBuffer[metricBufferUsage - metricSize:metricBufferUsage]
			totalMetrics++

			if totalMetrics == cap(metrics) {
				newMetrics  := make([][]byte, cap(metrics), (cap(metrics) + 1) * 2)
				copy(newMetrics, metrics)
				metrics = newMetrics
			}

			metricSize = 0;
			currentSearchNode = apiKeys;
			rootNamespaceAccepted = false
		}
	}

	return metrics[:totalMetrics], metricBuffer[(metricBufferUsage - metricSize):metricBufferUsage], nil
}
<|endoftext|>


<commit_before>package main

import "fmt"

func main() {
	fmt.Println("hello app")

}
<commit_msg>Add http server and search template<commit_after>package main

import (
	"html/template"
	"net/http"
)

var (
	homeTmpl        = template.Must(template.New("homeTmpl").Parse(baseTemplate + formTemplate))
	searchReplyTmpl = template.Must(template.New("searchReplyTmpl").Parse(baseTemplate + searchReplyTemplate))
)

// Pet is the pet of the app.
type Pet struct {
	Name string
	Age  int
}

var pets = []Pet{
	{Name: "Blackie", Age: 5},
	{Name: "Rocky", Age: 6},
	{Name: "Lasie", Age: 7},
}

func main() {
	http.Handle("/", http.HandlerFunc(homeHandler))
	http.Handle("/form", http.HandlerFunc(searchReplyHandler))

	http.ListenAndServe(":8080", nil)
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
	err := homeTmpl.Execute(w, nil)
	if err != nil {
		http.Error(w, "internal server error", 500)
		return
	}
}

func searchReplyHandler(w http.ResponseWriter, r *http.Request) {
	name := r.FormValue("name")

	for _, p := range pets {
		if p.Name == name {
			err := searchReplyTmpl.Execute(w, p)
			if err != nil {
				http.Error(w, "internal server error", 500)
				return
			}
			return
		}
	}

	err := searchReplyTmpl.Execute(w, "No pet found")
	if err != nil {
		http.Error(w, "internal server error", 500)
		return
	}

}

const (
	baseTemplate = `
<!DOCTYPE html>

<meta charset="UTF-8">
<title>Secure web app</title>

	{{.}}

`

	formTemplate = `
<form action="/form" method="GET">
	<input name="name">
	<input type="submit" value="Search for pet">
 </form>
`
	searchReplyTemplate = `
Name: {{.Name}}

Age: {{.Age}}
`
)
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"

	"github.com/goreleaser/goreleaser/config"
	"github.com/goreleaser/goreleaser/context"
	"github.com/goreleaser/goreleaser/pipeline"
	"github.com/goreleaser/goreleaser/pipeline/archive"
	"github.com/goreleaser/goreleaser/pipeline/brew"
	"github.com/goreleaser/goreleaser/pipeline/build"
	"github.com/goreleaser/goreleaser/pipeline/checksums"
	"github.com/goreleaser/goreleaser/pipeline/defaults"
	"github.com/goreleaser/goreleaser/pipeline/env"
	"github.com/goreleaser/goreleaser/pipeline/fpm"
	"github.com/goreleaser/goreleaser/pipeline/git"
	"github.com/goreleaser/goreleaser/pipeline/release"
	"github.com/urfave/cli"
)

var (
	version = "dev"
	commit  = "none"
	date    = "unknown"
)

func main() {
	var app = cli.NewApp()
	app.Name = "goreleaser"
	app.Version = version + ", commit " + commit + ", built at " + date
	app.Usage = "Deliver Go binaries as fast and easily as possible"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "config, file, c, f",
			Usage: "Load configuration from `FILE`",
			Value: "goreleaser.yml",
		},
		cli.BoolFlag{
			Name:  "build-only, skip-release, no-release, nr",
			Usage: "Skip all the release processes and run only the build and packaging steps",
		},
	}
	app.Action = func(c *cli.Context) (err error) {
		var file = c.String("config")
		cfg, err := config.Load(file)
		// Allow failing to load the config file if file is not explicitly specified
		if err != nil && c.IsSet("config") {
			return cli.NewExitError(err.Error(), 1)
		}
		ctx := context.New(cfg)
		log.SetFlags(0)
		for _, pipe := range pipes(c.Bool("build-only")) {
			log.Println(pipe.Description())
			log.SetPrefix(" -> ")
			if err := pipe.Run(ctx); err != nil {
				return cli.NewExitError(err.Error(), 1)
			}
			log.SetPrefix("")
		}
		log.Println("Done!")
		return
	}
	if err := app.Run(os.Args); err != nil {
		log.Fatalln(err)
	}
}

func pipes(buildOnly bool) []pipeline.Pipe {
	var pipes = []pipeline.Pipe{
		defaults.Pipe{}, // load default configs
	}
	if !buildOnly {
		pipes = append(
			pipes,
			git.Pipe{}, // get and validate git repo state
			env.Pipe{}, // load and validate environment variables
		)
	}
	pipes = append(
		pipes,
		build.Pipe{},     // build
		archive.Pipe{},   // archive (tar.gz, zip, etc)
		fpm.Pipe{},       // archive via fpm (deb, rpm, etc)
		checksums.Pipe{}, // checksums of the files
	)
	if !buildOnly {
		pipes = append(
			pipes,
			release.Pipe{}, // release to github
			brew.Pipe{},    // push to brew tap
		)
	}
	return pipes
}
<commit_msg>fixed config validation<commit_after>package main

import (
	"log"
	"os"

	"github.com/goreleaser/goreleaser/config"
	"github.com/goreleaser/goreleaser/context"
	"github.com/goreleaser/goreleaser/pipeline"
	"github.com/goreleaser/goreleaser/pipeline/archive"
	"github.com/goreleaser/goreleaser/pipeline/brew"
	"github.com/goreleaser/goreleaser/pipeline/build"
	"github.com/goreleaser/goreleaser/pipeline/checksums"
	"github.com/goreleaser/goreleaser/pipeline/defaults"
	"github.com/goreleaser/goreleaser/pipeline/env"
	"github.com/goreleaser/goreleaser/pipeline/fpm"
	"github.com/goreleaser/goreleaser/pipeline/git"
	"github.com/goreleaser/goreleaser/pipeline/release"
	"github.com/urfave/cli"
)

var (
	version = "dev"
	commit  = "none"
	date    = "unknown"
)

func main() {
	var app = cli.NewApp()
	app.Name = "goreleaser"
	app.Version = version + ", commit " + commit + ", built at " + date
	app.Usage = "Deliver Go binaries as fast and easily as possible"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "config, file, c, f",
			Usage: "Load configuration from `FILE`",
			Value: "goreleaser.yml",
		},
		cli.BoolFlag{
			Name:  "build-only, skip-release, no-release, nr",
			Usage: "Skip all the release processes and run only the build and packaging steps",
		},
	}
	app.Action = func(c *cli.Context) (err error) {
		var file = c.String("config")
		cfg, err := config.Load(file)
		if err != nil {
			// Allow file not found errors if config file was not
			// explicitly specified
			_, statErr := os.Stat(file)
			if !os.IsNotExist(statErr) || c.IsSet("config") {
				return cli.NewExitError(err.Error(), 1)
			}
		}
		var ctx = context.New(cfg)
		log.SetFlags(0)
		for _, pipe := range pipes(c.Bool("build-only")) {
			log.Println(pipe.Description())
			log.SetPrefix(" -> ")
			if err := pipe.Run(ctx); err != nil {
				return cli.NewExitError(err.Error(), 1)
			}
			log.SetPrefix("")
		}
		log.Println("Done!")
		return
	}
	if err := app.Run(os.Args); err != nil {
		log.Fatalln(err)
	}
}

func pipes(buildOnly bool) []pipeline.Pipe {
	var pipes = []pipeline.Pipe{
		defaults.Pipe{}, // load default configs
	}
	if !buildOnly {
		pipes = append(
			pipes,
			git.Pipe{}, // get and validate git repo state
			env.Pipe{}, // load and validate environment variables
		)
	}
	pipes = append(
		pipes,
		build.Pipe{},     // build
		archive.Pipe{},   // archive (tar.gz, zip, etc)
		fpm.Pipe{},       // archive via fpm (deb, rpm, etc)
		checksums.Pipe{}, // checksums of the files
	)
	if !buildOnly {
		pipes = append(
			pipes,
			release.Pipe{}, // release to github
			brew.Pipe{},    // push to brew tap
		)
	}
	return pipes
}
<|endoftext|>


<commit_before>// Package main defines a command line interface for the sqlboiler package
package main

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

	"github.com/friendsofgo/errors"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"github.com/volatiletech/sqlboiler/v4/boilingcore"
	"github.com/volatiletech/sqlboiler/v4/drivers"
	"github.com/volatiletech/sqlboiler/v4/importers"
)

//go:generate go-bindata -nometadata -pkg templatebin -o templatebin/bindata.go templates templates/singleton templates_test templates_test/singleton

const sqlBoilerVersion = "4.1.1"

var (
	flagConfigFile string
	cmdState       *boilingcore.State
	cmdConfig      *boilingcore.Config
)

func initConfig() {
	if len(flagConfigFile) != 0 {
		viper.SetConfigFile(flagConfigFile)
		if err := viper.ReadInConfig(); err != nil {
			fmt.Println("Can't read config:", err)
			os.Exit(1)
		}
		return
	}

	var err error
	viper.SetConfigName("sqlboiler")

	configHome := os.Getenv("XDG_CONFIG_HOME")
	homePath := os.Getenv("HOME")
	wd, err := os.Getwd()
	if err != nil {
		wd = "."
	}

	configPaths := []string{wd}
	if len(configHome) > 0 {
		configPaths = append(configPaths, filepath.Join(configHome, "sqlboiler"))
	} else {
		configPaths = append(configPaths, filepath.Join(homePath, ".config/sqlboiler"))
	}

	for _, p := range configPaths {
		viper.AddConfigPath(p)
	}

	// Ignore errors here, fallback to other validation methods.
	// Users can use environment variables if a config is not found.
	_ = viper.ReadInConfig()
}

func main() {
	// Too much happens between here and cobra's argument handling, for
	// something so simple just do it immediately.
	for _, arg := range os.Args {
		if arg == "--version" {
			fmt.Println("SQLBoiler v" + sqlBoilerVersion)
			return
		}
	}

	// Set up the cobra root command
	var rootCmd = &cobra.Command{
		Use:   "sqlboiler [flags] <driver>",
		Short: "SQL Boiler generates an ORM tailored to your database schema.",
		Long: "SQL Boiler generates a Go ORM from template files, tailored to your database schema.\n" +
			`Complete documentation is available at http://github.com/volatiletech/sqlboiler`,
		Example:       `sqlboiler psql`,
		PreRunE:       preRun,
		RunE:          run,
		PostRunE:      postRun,
		SilenceErrors: true,
		SilenceUsage:  true,
	}

	cobra.OnInitialize(initConfig)

	// Set up the cobra root command flags
	rootCmd.PersistentFlags().StringVarP(&flagConfigFile, "config", "c", "", "Filename of config file to override default lookup")
	rootCmd.PersistentFlags().StringP("output", "o", "models", "The name of the folder to output to")
	rootCmd.PersistentFlags().StringP("pkgname", "p", "models", "The name you wish to assign to your generated package")
	rootCmd.PersistentFlags().StringSliceP("templates", "", nil, "A templates directory, overrides the bindata'd template folders in sqlboiler")
	rootCmd.PersistentFlags().StringSliceP("tag", "t", nil, "Struct tags to be included on your models in addition to json, yaml, toml")
	rootCmd.PersistentFlags().StringSliceP("replace", "", nil, "Replace templates by directory: relpath/to_file.tpl:relpath/to_replacement.tpl")
	rootCmd.PersistentFlags().BoolP("debug", "d", false, "Debug mode prints stack traces on error")
	rootCmd.PersistentFlags().BoolP("no-context", "", false, "Disable context.Context usage in the generated code")
	rootCmd.PersistentFlags().BoolP("no-tests", "", false, "Disable generated go test files")
	rootCmd.PersistentFlags().BoolP("no-hooks", "", false, "Disable hooks feature for your models")
	rootCmd.PersistentFlags().BoolP("no-rows-affected", "", false, "Disable rows affected in the generated API")
	rootCmd.PersistentFlags().BoolP("no-auto-timestamps", "", false, "Disable automatic timestamps for created_at/updated_at")
	rootCmd.PersistentFlags().BoolP("no-driver-templates", "", false, "Disable parsing of templates defined by the database driver")
	rootCmd.PersistentFlags().BoolP("no-back-referencing", "", false, "Disable back referencing in the loaded relationship structs")
	rootCmd.PersistentFlags().BoolP("add-global-variants", "", false, "Enable generation for global variants")
	rootCmd.PersistentFlags().BoolP("add-panic-variants", "", false, "Enable generation for panic variants")
	rootCmd.PersistentFlags().BoolP("add-soft-deletes", "", false, "Enable soft deletion by updating deleted_at timestamp")
	rootCmd.PersistentFlags().BoolP("version", "", false, "Print the version")
	rootCmd.PersistentFlags().BoolP("wipe", "", false, "Delete the output folder (rm -rf) before generation to ensure sanity")
	rootCmd.PersistentFlags().StringP("struct-tag-casing", "", "snake", "Decides the casing for go structure tag names. camel, title or snake (default snake)")
	rootCmd.PersistentFlags().StringP("relation-tag", "r", "-", "Relationship struct tag name")
	rootCmd.PersistentFlags().StringSliceP("tag-ignore", "", nil, "List of column names that should have tags values set to '-' (ignored during parsing)")

	// hide flags not recommended for use
	rootCmd.PersistentFlags().MarkHidden("replace")

	viper.BindPFlags(rootCmd.PersistentFlags())
	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	viper.AutomaticEnv()

	if err := rootCmd.Execute(); err != nil {
		if e, ok := err.(commandFailure); ok {
			fmt.Printf("Error: %v\n\n", string(e))
			rootCmd.Help()
		} else if !viper.GetBool("debug") {
			fmt.Printf("Error: %v\n", err)
		} else {
			fmt.Printf("Error: %+v\n", err)
		}

		os.Exit(1)
	}
}

type commandFailure string

func (c commandFailure) Error() string {
	return string(c)
}

func preRun(cmd *cobra.Command, args []string) error {
	var err error

	if len(args) == 0 {
		return commandFailure("must provide a driver name")
	}

	driverName := args[0]
	driverPath := args[0]

	if strings.ContainsRune(driverName, os.PathSeparator) {
		driverName = strings.Replace(filepath.Base(driverName), "sqlboiler-", "", 1)
		driverName = strings.Replace(driverName, ".exe", "", 1)
	} else {
		driverPath = "sqlboiler-" + driverPath
		if p, err := exec.LookPath(driverPath); err == nil {
			driverPath = p
		}
	}

	driverPath, err = filepath.Abs(driverPath)
	if err != nil {
		return errors.Wrap(err, "could not find absolute path to driver")
	}
	drivers.RegisterBinary(driverName, driverPath)

	cmdConfig = &boilingcore.Config{
		DriverName:        driverName,
		OutFolder:         viper.GetString("output"),
		PkgName:           viper.GetString("pkgname"),
		Debug:             viper.GetBool("debug"),
		AddGlobal:         viper.GetBool("add-global-variants"),
		AddPanic:          viper.GetBool("add-panic-variants"),
		AddSoftDeletes:    viper.GetBool("add-soft-deletes"),
		NoContext:         viper.GetBool("no-context"),
		NoTests:           viper.GetBool("no-tests"),
		NoHooks:           viper.GetBool("no-hooks"),
		NoRowsAffected:    viper.GetBool("no-rows-affected"),
		NoAutoTimestamps:  viper.GetBool("no-auto-timestamps"),
		NoDriverTemplates: viper.GetBool("no-driver-templates"),
		NoBackReferencing: viper.GetBool("no-back-referencing"),
		Wipe:              viper.GetBool("wipe"),
		StructTagCasing:   strings.ToLower(viper.GetString("struct-tag-casing")), // camel | snake | title
		TagIgnore:         viper.GetStringSlice("tag-ignore"),
		RelationTag:       viper.GetString("relation-tag"),
		TemplateDirs:      viper.GetStringSlice("templates"),
		Tags:              viper.GetStringSlice("tag"),
		Replacements:      viper.GetStringSlice("replace"),
		Aliases:           boilingcore.ConvertAliases(viper.Get("aliases")),
		TypeReplaces:      boilingcore.ConvertTypeReplace(viper.Get("types")),
		Version:           sqlBoilerVersion,
	}

	if cmdConfig.Debug {
		fmt.Fprintln(os.Stderr, "using driver:", driverPath)
	}

	// Configure the driver
	cmdConfig.DriverConfig = map[string]interface{}{
		"whitelist": viper.GetStringSlice(driverName + ".whitelist"),
		"blacklist": viper.GetStringSlice(driverName + ".blacklist"),
	}

	keys := allKeys(driverName)
	for _, key := range keys {
		prefixedKey := fmt.Sprintf("%s.%s", driverName, key)
		cmdConfig.DriverConfig[key] = viper.Get(prefixedKey)
	}

	cmdConfig.Imports = configureImports()

	cmdState, err = boilingcore.New(cmdConfig)
	return err
}

func configureImports() importers.Collection {
	imports := importers.NewDefaultImports()

	mustMap := func(m importers.Map, err error) importers.Map {
		if err != nil {
			panic("failed to change viper interface into importers.Map: " + err.Error())
		}

		return m
	}

	if viper.IsSet("imports.all.standard") {
		imports.All.Standard = viper.GetStringSlice("imports.all.standard")
	}
	if viper.IsSet("imports.all.third_party") {
		imports.All.ThirdParty = viper.GetStringSlice("imports.all.third_party")
	}
	if viper.IsSet("imports.test.standard") {
		imports.Test.Standard = viper.GetStringSlice("imports.test.standard")
	}
	if viper.IsSet("imports.test.third_party") {
		imports.Test.ThirdParty = viper.GetStringSlice("imports.test.third_party")
	}
	if viper.IsSet("imports.singleton") {
		imports.Singleton = mustMap(importers.MapFromInterface(viper.Get("imports.singleton")))
	}
	if viper.IsSet("imports.test_singleton") {
		imports.TestSingleton = mustMap(importers.MapFromInterface(viper.Get("imports.test_singleton")))
	}
	if viper.IsSet("imports.based_on_type") {
		imports.BasedOnType = mustMap(importers.MapFromInterface(viper.Get("imports.based_on_type")))
	}

	return imports
}

func run(cmd *cobra.Command, args []string) error {
	return cmdState.Run()
}

func postRun(cmd *cobra.Command, args []string) error {
	return cmdState.Cleanup()
}

func allKeys(prefix string) []string {
	keys := make(map[string]bool)

	prefix += "."

	for _, e := range os.Environ() {
		splits := strings.SplitN(e, "=", 2)
		key := strings.ReplaceAll(strings.ToLower(splits[0]), "_", ".")

		if strings.HasPrefix(key, prefix) {
			keys[strings.ReplaceAll(key, prefix, "")] = true
		}
	}

	for _, key := range viper.AllKeys() {
		if strings.HasPrefix(key, prefix) {
			keys[strings.ReplaceAll(key, prefix, "")] = true
		}
	}

	keySlice := make([]string, 0, len(keys))
	for k := range keys {
		keySlice = append(keySlice, k)
	}
	return keySlice
}
<commit_msg>Bump version<commit_after>// Package main defines a command line interface for the sqlboiler package
package main

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

	"github.com/friendsofgo/errors"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"github.com/volatiletech/sqlboiler/v4/boilingcore"
	"github.com/volatiletech/sqlboiler/v4/drivers"
	"github.com/volatiletech/sqlboiler/v4/importers"
)

//go:generate go-bindata -nometadata -pkg templatebin -o templatebin/bindata.go templates templates/singleton templates_test templates_test/singleton

const sqlBoilerVersion = "4.1.2"

var (
	flagConfigFile string
	cmdState       *boilingcore.State
	cmdConfig      *boilingcore.Config
)

func initConfig() {
	if len(flagConfigFile) != 0 {
		viper.SetConfigFile(flagConfigFile)
		if err := viper.ReadInConfig(); err != nil {
			fmt.Println("Can't read config:", err)
			os.Exit(1)
		}
		return
	}

	var err error
	viper.SetConfigName("sqlboiler")

	configHome := os.Getenv("XDG_CONFIG_HOME")
	homePath := os.Getenv("HOME")
	wd, err := os.Getwd()
	if err != nil {
		wd = "."
	}

	configPaths := []string{wd}
	if len(configHome) > 0 {
		configPaths = append(configPaths, filepath.Join(configHome, "sqlboiler"))
	} else {
		configPaths = append(configPaths, filepath.Join(homePath, ".config/sqlboiler"))
	}

	for _, p := range configPaths {
		viper.AddConfigPath(p)
	}

	// Ignore errors here, fallback to other validation methods.
	// Users can use environment variables if a config is not found.
	_ = viper.ReadInConfig()
}

func main() {
	// Too much happens between here and cobra's argument handling, for
	// something so simple just do it immediately.
	for _, arg := range os.Args {
		if arg == "--version" {
			fmt.Println("SQLBoiler v" + sqlBoilerVersion)
			return
		}
	}

	// Set up the cobra root command
	var rootCmd = &cobra.Command{
		Use:   "sqlboiler [flags] <driver>",
		Short: "SQL Boiler generates an ORM tailored to your database schema.",
		Long: "SQL Boiler generates a Go ORM from template files, tailored to your database schema.\n" +
			`Complete documentation is available at http://github.com/volatiletech/sqlboiler`,
		Example:       `sqlboiler psql`,
		PreRunE:       preRun,
		RunE:          run,
		PostRunE:      postRun,
		SilenceErrors: true,
		SilenceUsage:  true,
	}

	cobra.OnInitialize(initConfig)

	// Set up the cobra root command flags
	rootCmd.PersistentFlags().StringVarP(&flagConfigFile, "config", "c", "", "Filename of config file to override default lookup")
	rootCmd.PersistentFlags().StringP("output", "o", "models", "The name of the folder to output to")
	rootCmd.PersistentFlags().StringP("pkgname", "p", "models", "The name you wish to assign to your generated package")
	rootCmd.PersistentFlags().StringSliceP("templates", "", nil, "A templates directory, overrides the bindata'd template folders in sqlboiler")
	rootCmd.PersistentFlags().StringSliceP("tag", "t", nil, "Struct tags to be included on your models in addition to json, yaml, toml")
	rootCmd.PersistentFlags().StringSliceP("replace", "", nil, "Replace templates by directory: relpath/to_file.tpl:relpath/to_replacement.tpl")
	rootCmd.PersistentFlags().BoolP("debug", "d", false, "Debug mode prints stack traces on error")
	rootCmd.PersistentFlags().BoolP("no-context", "", false, "Disable context.Context usage in the generated code")
	rootCmd.PersistentFlags().BoolP("no-tests", "", false, "Disable generated go test files")
	rootCmd.PersistentFlags().BoolP("no-hooks", "", false, "Disable hooks feature for your models")
	rootCmd.PersistentFlags().BoolP("no-rows-affected", "", false, "Disable rows affected in the generated API")
	rootCmd.PersistentFlags().BoolP("no-auto-timestamps", "", false, "Disable automatic timestamps for created_at/updated_at")
	rootCmd.PersistentFlags().BoolP("no-driver-templates", "", false, "Disable parsing of templates defined by the database driver")
	rootCmd.PersistentFlags().BoolP("no-back-referencing", "", false, "Disable back referencing in the loaded relationship structs")
	rootCmd.PersistentFlags().BoolP("add-global-variants", "", false, "Enable generation for global variants")
	rootCmd.PersistentFlags().BoolP("add-panic-variants", "", false, "Enable generation for panic variants")
	rootCmd.PersistentFlags().BoolP("add-soft-deletes", "", false, "Enable soft deletion by updating deleted_at timestamp")
	rootCmd.PersistentFlags().BoolP("version", "", false, "Print the version")
	rootCmd.PersistentFlags().BoolP("wipe", "", false, "Delete the output folder (rm -rf) before generation to ensure sanity")
	rootCmd.PersistentFlags().StringP("struct-tag-casing", "", "snake", "Decides the casing for go structure tag names. camel, title or snake (default snake)")
	rootCmd.PersistentFlags().StringP("relation-tag", "r", "-", "Relationship struct tag name")
	rootCmd.PersistentFlags().StringSliceP("tag-ignore", "", nil, "List of column names that should have tags values set to '-' (ignored during parsing)")

	// hide flags not recommended for use
	rootCmd.PersistentFlags().MarkHidden("replace")

	viper.BindPFlags(rootCmd.PersistentFlags())
	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	viper.AutomaticEnv()

	if err := rootCmd.Execute(); err != nil {
		if e, ok := err.(commandFailure); ok {
			fmt.Printf("Error: %v\n\n", string(e))
			rootCmd.Help()
		} else if !viper.GetBool("debug") {
			fmt.Printf("Error: %v\n", err)
		} else {
			fmt.Printf("Error: %+v\n", err)
		}

		os.Exit(1)
	}
}

type commandFailure string

func (c commandFailure) Error() string {
	return string(c)
}

func preRun(cmd *cobra.Command, args []string) error {
	var err error

	if len(args) == 0 {
		return commandFailure("must provide a driver name")
	}

	driverName := args[0]
	driverPath := args[0]

	if strings.ContainsRune(driverName, os.PathSeparator) {
		driverName = strings.Replace(filepath.Base(driverName), "sqlboiler-", "", 1)
		driverName = strings.Replace(driverName, ".exe", "", 1)
	} else {
		driverPath = "sqlboiler-" + driverPath
		if p, err := exec.LookPath(driverPath); err == nil {
			driverPath = p
		}
	}

	driverPath, err = filepath.Abs(driverPath)
	if err != nil {
		return errors.Wrap(err, "could not find absolute path to driver")
	}
	drivers.RegisterBinary(driverName, driverPath)

	cmdConfig = &boilingcore.Config{
		DriverName:        driverName,
		OutFolder:         viper.GetString("output"),
		PkgName:           viper.GetString("pkgname"),
		Debug:             viper.GetBool("debug"),
		AddGlobal:         viper.GetBool("add-global-variants"),
		AddPanic:          viper.GetBool("add-panic-variants"),
		AddSoftDeletes:    viper.GetBool("add-soft-deletes"),
		NoContext:         viper.GetBool("no-context"),
		NoTests:           viper.GetBool("no-tests"),
		NoHooks:           viper.GetBool("no-hooks"),
		NoRowsAffected:    viper.GetBool("no-rows-affected"),
		NoAutoTimestamps:  viper.GetBool("no-auto-timestamps"),
		NoDriverTemplates: viper.GetBool("no-driver-templates"),
		NoBackReferencing: viper.GetBool("no-back-referencing"),
		Wipe:              viper.GetBool("wipe"),
		StructTagCasing:   strings.ToLower(viper.GetString("struct-tag-casing")), // camel | snake | title
		TagIgnore:         viper.GetStringSlice("tag-ignore"),
		RelationTag:       viper.GetString("relation-tag"),
		TemplateDirs:      viper.GetStringSlice("templates"),
		Tags:              viper.GetStringSlice("tag"),
		Replacements:      viper.GetStringSlice("replace"),
		Aliases:           boilingcore.ConvertAliases(viper.Get("aliases")),
		TypeReplaces:      boilingcore.ConvertTypeReplace(viper.Get("types")),
		Version:           sqlBoilerVersion,
	}

	if cmdConfig.Debug {
		fmt.Fprintln(os.Stderr, "using driver:", driverPath)
	}

	// Configure the driver
	cmdConfig.DriverConfig = map[string]interface{}{
		"whitelist": viper.GetStringSlice(driverName + ".whitelist"),
		"blacklist": viper.GetStringSlice(driverName + ".blacklist"),
	}

	keys := allKeys(driverName)
	for _, key := range keys {
		prefixedKey := fmt.Sprintf("%s.%s", driverName, key)
		cmdConfig.DriverConfig[key] = viper.Get(prefixedKey)
	}

	cmdConfig.Imports = configureImports()

	cmdState, err = boilingcore.New(cmdConfig)
	return err
}

func configureImports() importers.Collection {
	imports := importers.NewDefaultImports()

	mustMap := func(m importers.Map, err error) importers.Map {
		if err != nil {
			panic("failed to change viper interface into importers.Map: " + err.Error())
		}

		return m
	}

	if viper.IsSet("imports.all.standard") {
		imports.All.Standard = viper.GetStringSlice("imports.all.standard")
	}
	if viper.IsSet("imports.all.third_party") {
		imports.All.ThirdParty = viper.GetStringSlice("imports.all.third_party")
	}
	if viper.IsSet("imports.test.standard") {
		imports.Test.Standard = viper.GetStringSlice("imports.test.standard")
	}
	if viper.IsSet("imports.test.third_party") {
		imports.Test.ThirdParty = viper.GetStringSlice("imports.test.third_party")
	}
	if viper.IsSet("imports.singleton") {
		imports.Singleton = mustMap(importers.MapFromInterface(viper.Get("imports.singleton")))
	}
	if viper.IsSet("imports.test_singleton") {
		imports.TestSingleton = mustMap(importers.MapFromInterface(viper.Get("imports.test_singleton")))
	}
	if viper.IsSet("imports.based_on_type") {
		imports.BasedOnType = mustMap(importers.MapFromInterface(viper.Get("imports.based_on_type")))
	}

	return imports
}

func run(cmd *cobra.Command, args []string) error {
	return cmdState.Run()
}

func postRun(cmd *cobra.Command, args []string) error {
	return cmdState.Cleanup()
}

func allKeys(prefix string) []string {
	keys := make(map[string]bool)

	prefix += "."

	for _, e := range os.Environ() {
		splits := strings.SplitN(e, "=", 2)
		key := strings.ReplaceAll(strings.ToLower(splits[0]), "_", ".")

		if strings.HasPrefix(key, prefix) {
			keys[strings.ReplaceAll(key, prefix, "")] = true
		}
	}

	for _, key := range viper.AllKeys() {
		if strings.HasPrefix(key, prefix) {
			keys[strings.ReplaceAll(key, prefix, "")] = true
		}
	}

	keySlice := make([]string, 0, len(keys))
	for k := range keys {
		keySlice = append(keySlice, k)
	}
	return keySlice
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"

	"github.com/davecgh/go-spew/spew"
)

func main() {
	switches := [...]statusSwitch{
		statusSwitch{os.Getenv("ONEON"), os.Getenv("ONEOFF"), "🌇"},
		statusSwitch{os.Getenv("TWOON"), os.Getenv("TWOOFF"), "💡"},
		statusSwitch{os.Getenv("THREEON"), os.Getenv("THREEOFF"), "🔦"},
		statusSwitch{os.Getenv("FOURON"), os.Getenv("FOUROFF"), "🛰 "},
		statusSwitch{os.Getenv("ONEAON"), os.Getenv("ONEAOFF"), "👍🏻"},
		statusSwitch{os.Getenv("TWOAON"), os.Getenv("TWOAOFF"), "🐕"},
		statusSwitch{os.Getenv("THREEAON"), os.Getenv("THREEAOFF"), "🌎"},
		statusSwitch{os.Getenv("FOURAON"), os.Getenv("FOURAOFF"), "📬"},
		//	statusSwitch{os.Getenv("AON"), os.Getenv("AOFF"), "🎤"},
	}
	switchMap := make(map[string]switcher)

	for _, s := range switches {
		spew.Dump(s)
		switchMap[s.name] = s
	}
	switchMap["all"] = multiswitch{switches[:]}
	//spew.Dump(switchMap)

	key := os.Getenv("RFKEY")

	switchHandler := func(w http.ResponseWriter, r *http.Request) {
		var dat struct {
			Switch string
			Action string
		}
		secret := r.Header.Get("badlykeptsecret")

		if secret != key {
			fmt.Fprintln(w, "⛔")
			return
		}
		d := json.NewDecoder(r.Body)
		d.Decode(&dat)
		fmt.Println(dat)
		s, exists := switchMap[dat.Switch]
		if !exists {
			fmt.Println(w, dat.Switch)
			fmt.Fprintln(w, "🔕")
			return
		}
		if dat.Action == "on" {
			s.On()
			fmt.Fprintln(w, "👍💡")
			return
		}
		if dat.Action == "off" {
			s.Off()
			fmt.Fprintln(w, "👍🌆")
			return
		}
		fmt.Fprintln(w, "👾")
		return
	}
	listSwitchesHandler := func(w http.ResponseWriter, r *http.Request) {
		s, _ := json.Marshal(switchMap)
		fmt.Fprint(w, string(s))
	}

	http.HandleFunc("/switch/", switchHandler)
	http.HandleFunc("/list/", listSwitchesHandler)
	http.Handle("/", http.FileServer(http.Dir("./public/")))
	fmt.Println("HANDLING HTTP")
	http.ListenAndServe(":8080", nil)
}
<commit_msg>disable some switches for a bit<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"

	"github.com/davecgh/go-spew/spew"
)

func main() {
	switches := [...]statusSwitch{
		statusSwitch{os.Getenv("ONEON"), os.Getenv("ONEOFF"), "🌇"},
		statusSwitch{os.Getenv("TWOON"), os.Getenv("TWOOFF"), "💡"},
		//statusSwitch{os.Getenv("THREEON"), os.Getenv("THREEOFF"), "🔦"},
		//statusSwitch{os.Getenv("FOURON"), os.Getenv("FOUROFF"), "🛰 "},
		statusSwitch{os.Getenv("ONEAON"), os.Getenv("ONEAOFF"), "👍🏻"},
		statusSwitch{os.Getenv("TWOAON"), os.Getenv("TWOAOFF"), "🐕"},
		//statusSwitch{os.Getenv("THREEAON"), os.Getenv("THREEAOFF"), "🌎"},
		//statusSwitch{os.Getenv("FOURAON"), os.Getenv("FOURAOFF"), "📬"},
		//	statusSwitch{os.Getenv("AON"), os.Getenv("AOFF"), "🎤"},
	}
	switchMap := make(map[string]switcher)

	for _, s := range switches {
		spew.Dump(s)
		switchMap[s.name] = s
	}
	switchMap["all"] = multiswitch{switches[:]}
	//spew.Dump(switchMap)

	key := os.Getenv("RFKEY")

	switchHandler := func(w http.ResponseWriter, r *http.Request) {
		var dat struct {
			Switch string
			Action string
		}
		secret := r.Header.Get("badlykeptsecret")

		if secret != key {
			fmt.Fprintln(w, "⛔")
			return
		}
		d := json.NewDecoder(r.Body)
		d.Decode(&dat)
		fmt.Println(dat)
		s, exists := switchMap[dat.Switch]
		if !exists {
			fmt.Println(w, dat.Switch)
			fmt.Fprintln(w, "🔕")
			return
		}
		if dat.Action == "on" {
			s.On()
			fmt.Fprintln(w, "👍💡")
			return
		}
		if dat.Action == "off" {
			s.Off()
			fmt.Fprintln(w, "👍🌆")
			return
		}
		fmt.Fprintln(w, "👾")
		return
	}
	listSwitchesHandler := func(w http.ResponseWriter, r *http.Request) {
		s, _ := json.Marshal(switchMap)
		fmt.Fprint(w, string(s))
	}

	http.HandleFunc("/switch/", switchHandler)
	http.HandleFunc("/list/", listSwitchesHandler)
	http.Handle("/", http.FileServer(http.Dir("./public/")))
	fmt.Println("HANDLING HTTP")
	http.ListenAndServe(":8080", nil)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/elb"
	"github.com/iamthemuffinman/logsip"
)

var log = logsip.New(os.Stdout)

func main() {
	// Set config options.
	sourceElb := "<sourceELB_name_here>"
	destElb := "<destELB_name_here>"

	// Create a new aws session.
	stsSvc := session.New()

	// Get new temporary STS credentials for assumed role.
	getCreds := stscreds.NewCredentials(stsSvc, "<roleARNhere>")

	// Open a new elb session with the aws-sdk and pass in temporary sts credentials.
	svc := elb.New(session.New(&aws.Config{Region: aws.String("us-east-1"), Credentials: getCreds}))

	// Define parameters to pass to DescribeInstanceHealth
	params := &elb.DescribeInstanceHealthInput{LoadBalancerName: aws.String(sourceElb), Instances: []*elb.Instance{}}

	result, err := svc.DescribeInstanceHealth(params)
	if err != nil {
		log.Fatal("Failed to describe ELB: \n", err.Error())
	}

	// See instances currently registered with sourceElb.
	fmt.Printf("Currently registered instances with %s: \n", sourceElb)
	fmt.Println(result)

	// Loop through registered instances to get instance ids and register them with the destElb.
	for _, instances := range result.InstanceStates {

		id := aws.StringValue(instances.InstanceId)
		_, err := svc.RegisterInstancesWithLoadBalancer(&elb.RegisterInstancesWithLoadBalancerInput{Instances: []*elb.Instance{{InstanceId: aws.String(id)}}, LoadBalancerName: aws.String(destElb)})
		if err != nil {
			log.Fatal("Failed to register instance", err.Error())
		}

	}
	// Sleep for 20 seconds to allow instance registration in the destElb.
	fmt.Println("Going to sleep for 20 seconds before checking instance registration status ... ")
	time.Sleep(20 * time.Second)

	// Define parameters to pass to DescribeInstanceHealth for destElb
	paramsDest := &elb.DescribeInstanceHealthInput{LoadBalancerName: aws.String(destElb), Instances: []*elb.Instance{}}

	resultDest, err := svc.DescribeInstanceHealth(paramsDest)
	if err != nil {
		log.Fatal("Failed to describe ELBs", err.Error())
	}
	// Loop through Instance states for destELB and check if state is InService.
	for _, instances := range resultDest.InstanceStates {
		id := aws.StringValue(instances.InstanceId)
		state := aws.StringValue(instances.State)
		if state != "InService" {
			log.Fatalf("%s is not registered successfully with the load balancer", id)
		} else {
			fmt.Printf("%s registered successfully with the load balancer.\n", id)
		}
	}

}

<commit_msg>resolve issue #1 Fix call to logsip.New Add flag parameters to sourceElb and destElb<commit_after>package main

import (
	"flag"
	"fmt"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/elb"
	"github.com/iamthemuffinman/logsip"
)

var log = logsip.New()

func main() {
	// Config options.
	var sourceElb string
	var destElb string
	flag.StringVar(&sourceElb, "source", "", "Source ELB")
	flag.StringVar(&destElb, "dest", "", "Destination ELB")
	flag.Parse()

	// Halt if parameters are not specified.
	if sourceElb == "" {
		log.Fatal("No source ELB specified, swapELB -h to help")
	}
	if destElb == "" {
		log.Fatal("No destination ELB specified, swapELB -h to help")
	}

	// Create a new aws session.
	stsSvc := session.New()

	// Get new temporary STS credentials for assumed role.
	getCreds := stscreds.NewCredentials(stsSvc, "<roleARNhere>")

	// Open a new elb session with the aws-sdk and pass in temporary sts credentials.
	svc := elb.New(session.New(&aws.Config{Region: aws.String("us-east-1"), Credentials: getCreds}))

	// Define parameters to pass to DescribeInstanceHealth
	params := &elb.DescribeInstanceHealthInput{LoadBalancerName: aws.String(sourceElb), Instances: []*elb.Instance{}}

	result, err := svc.DescribeInstanceHealth(params)
	if err != nil {
		log.Fatal("Failed to describe ELB: \n", err.Error())
	}

	// See instances currently registered with sourceElb.
	fmt.Printf("Currently registered instances with %s: \n", sourceElb)
	fmt.Println(result)

	// Loop through registered instances to get instance ids and register them with the destElb.
	for _, instances := range result.InstanceStates {

		id := aws.StringValue(instances.InstanceId)
		_, err := svc.RegisterInstancesWithLoadBalancer(&elb.RegisterInstancesWithLoadBalancerInput{Instances: []*elb.Instance{{InstanceId: aws.String(id)}}, LoadBalancerName: aws.String(destElb)})
		if err != nil {
			log.Fatal("Failed to register instance", err.Error())
		}

	}
	// Sleep for 20 seconds to allow instance registration in the destElb.
	fmt.Println("Going to sleep for 20 seconds before checking instance registration status ... ")
	time.Sleep(20 * time.Second)

	// Define parameters to pass to DescribeInstanceHealth for destElb
	paramsDest := &elb.DescribeInstanceHealthInput{LoadBalancerName: aws.String(destElb), Instances: []*elb.Instance{}}

	resultDest, err := svc.DescribeInstanceHealth(paramsDest)
	if err != nil {
		log.Fatal("Failed to describe ELBs", err.Error())
	}
	// Loop through Instance states for destELB and check if state is InService.
	for _, instances := range resultDest.InstanceStates {
		id := aws.StringValue(instances.InstanceId)
		state := aws.StringValue(instances.State)
		if state != "InService" {
			log.Fatalf("%s is not registered successfully with the load balancer", id)
		} else {
			fmt.Printf("%s registered successfully with the load balancer.\n", id)
		}
	}

}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/rdwilliamson/aws"
	"github.com/rdwilliamson/aws/glacier"
	"os"
)

var (
	connection *glacier.Connection
)

func main() {
	flag.Parse()
	// TODO print usage

	// get keys
	// TODO other ways to supply them
	secret, access := aws.KeysFromEnviroment()
	if secret == "" || access == "" {
		fmt.Println("could not get keys")
		os.Exit(1)
	}

	// connection to region
	args := flag.Args()
	if len(args) < 1 {
		fmt.Println("no region argument")
		os.Exit(1)
	}

	var region *aws.Region
	for _, v := range aws.Regions {
		if v.Name == args[0] {
			region = v
			break
		}
	}
	if region == nil {
		fmt.Println("could not find region:", args[0])
		os.Exit(1)
	}
	args = args[1:]
	connection = glacier.NewConnection(secret, access, region)

	if len(args) < 1 {
		fmt.Println("no command argument")
		os.Exit(1)
	}
	command := args[0]
	args = args[1:]

	switch command {
	case "vault":
		vault(args)
	case "archive":
		archive(args)
	case "multipart":
		multipart(args)
	case "job":
		job(args)
	default:
		fmt.Println("unknown command:", command)
	}
}
<commit_msg>Added code to profile program.<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/rdwilliamson/aws"
	"github.com/rdwilliamson/aws/glacier"
	"os"
	"runtime/pprof"
)

var (
	connection *glacier.Connection
)

func main() {
	cpu := flag.String("cpuprofile", "", "cpu profile file")
	flag.Parse()
	// TODO print usage

	if *cpu != "" {
		f, err := os.Create(*cpu)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		defer f.Close()
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	// get keys
	// TODO other ways to supply them
	secret, access := aws.KeysFromEnviroment()
	if secret == "" || access == "" {
		fmt.Println("could not get keys")
		os.Exit(1)
	}

	// connection to region
	args := flag.Args()
	if len(args) < 1 {
		fmt.Println("no region argument")
		os.Exit(1)
	}

	var region *aws.Region
	for _, v := range aws.Regions {
		if v.Name == args[0] {
			region = v
			break
		}
	}
	if region == nil {
		fmt.Println("could not find region:", args[0])
		os.Exit(1)
	}
	args = args[1:]
	connection = glacier.NewConnection(secret, access, region)

	if len(args) < 1 {
		fmt.Println("no command argument")
		os.Exit(1)
	}
	command := args[0]
	args = args[1:]

	switch command {
	case "vault":
		vault(args)
	case "archive":
		archive(args)
	case "multipart":
		multipart(args)
	case "job":
		job(args)
	default:
		fmt.Println("unknown command:", command)
	}
}
<|endoftext|>


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

// tsuru-admin is under development.
package main

import (
	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/cmd/tsuru-base"
	"github.com/tsuru/tsuru/provision"
	_ "github.com/tsuru/tsuru/provision/docker"
	"os"
)

const (
	version = "0.4.0"
	header  = "Supported-Tsuru-Admin"
)

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header, nil)
	m.Register(tsuru.AppList{})
	m.Register(&tsuru.SetCName{})
	m.Register(&tsuru.UnsetCName{})
	m.Register(&tokenGen{})
	m.Register(&logRemove{})
	m.Register(&changeQuota{})
	m.Register(&platformAdd{})
	m.Register(&platformUpdate{})
	registerProvisionersCommands(m)
	return m
}

func registerProvisionersCommands(m *cmd.Manager) {
	provisioners := provision.Registry()
	for _, p := range provisioners {
		if c, ok := p.(cmd.AdminCommandable); ok {
			commands := c.AdminCommands()
			for _, cmd := range commands {
				m.Register(cmd)
			}
		}
	}
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	args := os.Args[1:]
	manager.Run(args)
}
<commit_msg>cmd/tsuru-admin: version 0.4.1<commit_after>// Copyright 2014 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// tsuru-admin is under development.
package main

import (
	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/cmd/tsuru-base"
	"github.com/tsuru/tsuru/provision"
	_ "github.com/tsuru/tsuru/provision/docker"
	"os"
)

const (
	version = "0.4.1"
	header  = "Supported-Tsuru-Admin"
)

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header, nil)
	m.Register(tsuru.AppList{})
	m.Register(&tsuru.SetCName{})
	m.Register(&tsuru.UnsetCName{})
	m.Register(&tokenGen{})
	m.Register(&logRemove{})
	m.Register(&changeQuota{})
	m.Register(&platformAdd{})
	m.Register(&platformUpdate{})
	registerProvisionersCommands(m)
	return m
}

func registerProvisionersCommands(m *cmd.Manager) {
	provisioners := provision.Registry()
	for _, p := range provisioners {
		if c, ok := p.(cmd.AdminCommandable); ok {
			commands := c.AdminCommands()
			for _, cmd := range commands {
				m.Register(cmd)
			}
		}
	}
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	args := os.Args[1:]
	manager.Run(args)
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"

	"github.com/urfave/cli"
)

const (
	defaultEthernetConfig    = "wired.json"
	defaultWifiClientConfig  = "wireless.json"
	defaultAccessPointConfig = "access_point.json"
)

func main() {
	app := cli.NewApp()
	app.Version = "0.3.0"
	app.Name = "fconf"
	app.Usage = "fessbox configuration manager"
	app.Commands = []cli.Command{
		{
			Name:    "ethernet",
			Aliases: []string{"e"},
			Usage:   "configures ethernet with systemd",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "name",
					Usage: "The name of the unit file",
					Value: ethernetService,
				},
				cli.StringFlag{
					Name:  "dir",
					Usage: "The directory in which to write the file",
					Value: networkBase,
				},
				cli.StringFlag{
					Name:  "config",
					Usage: "The path to the json configuration file",
					Value: defaultEthernetConfig,
				},
				cli.BoolFlag{
					Name:  "enable",
					Usage: "Enables ethernet",
				},
				cli.BoolFlag{
					Name:  "disable",
					Usage: "Disable ethernet",
				},
				cli.BoolFlag{
					Name:  "remove",
					Usage: "Remove ethernet",
				},
			},
			Action: EthernetCMD,
		},
		{
			Name:    "wifi-client",
			Aliases: []string{"w"},
			Usage:   "configures wifi client with systemd",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "name",
					Usage: "The name of the unit file",
					Value: wirelessService,
				},
				cli.StringFlag{
					Name:  "dir",
					Usage: "The directory in which to write the file",
					Value: networkBase,
				},
				cli.StringFlag{
					Name:  "config",
					Usage: "The path to the json configuration file",
					Value: defaultWifiClientConfig,
				},
				cli.BoolFlag{
					Name:  "enable",
					Usage: "Enables wifi",
				},
				cli.BoolFlag{
					Name:  "disable",
					Usage: "Disable wifi",
				},
				cli.BoolFlag{
					Name:  "remove",
					Usage: "Remove wifi",
				},
			},
			Action: WifiClientCMD,
		},
		{
			Name:    "access-point",
			Aliases: []string{"a"},
			Usage:   "configures access point with systemd",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "name",
					Usage: "The name of the unit file",
					Value: apConfigFile,
				},
				cli.StringFlag{
					Name:  "dir",
					Usage: "The directory in which to write the file",
					Value: networkBase,
				},
				cli.StringFlag{
					Name:  "config",
					Usage: "The path to the json configuration file",
					Value: defaultAccessPointConfig,
				},
				cli.BoolFlag{
					Name:  "enable",
					Usage: "Enables wifi",
				},
				cli.BoolFlag{
					Name:  "disable",
					Usage: "Disable wifi",
				},
				cli.BoolFlag{
					Name:  "remove",
					Usage: "Remove wifi",
				},
			},
			Action: ApCMD,
		},
	}
	err := app.Run(os.Args)
	if err != nil {
		log.Fatalf("fconf: %v", err)
	}
}
<commit_msg>Fix default directory for access point config<commit_after>package main

import (
	"log"
	"os"

	"github.com/urfave/cli"
)

const (
	defaultEthernetConfig    = "wired.json"
	defaultWifiClientConfig  = "wireless.json"
	defaultAccessPointConfig = "access_point.json"
)

func main() {
	app := cli.NewApp()
	app.Version = "0.3.0"
	app.Name = "fconf"
	app.Usage = "fessbox configuration manager"
	app.Commands = []cli.Command{
		{
			Name:    "ethernet",
			Aliases: []string{"e"},
			Usage:   "configures ethernet with systemd",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "name",
					Usage: "The name of the unit file",
					Value: ethernetService,
				},
				cli.StringFlag{
					Name:  "dir",
					Usage: "The directory in which to write the file",
					Value: networkBase,
				},
				cli.StringFlag{
					Name:  "config",
					Usage: "The path to the json configuration file",
					Value: defaultEthernetConfig,
				},
				cli.BoolFlag{
					Name:  "enable",
					Usage: "Enables ethernet",
				},
				cli.BoolFlag{
					Name:  "disable",
					Usage: "Disable ethernet",
				},
				cli.BoolFlag{
					Name:  "remove",
					Usage: "Remove ethernet",
				},
			},
			Action: EthernetCMD,
		},
		{
			Name:    "wifi-client",
			Aliases: []string{"w"},
			Usage:   "configures wifi client with systemd",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "name",
					Usage: "The name of the unit file",
					Value: wirelessService,
				},
				cli.StringFlag{
					Name:  "dir",
					Usage: "The directory in which to write the file",
					Value: networkBase,
				},
				cli.StringFlag{
					Name:  "config",
					Usage: "The path to the json configuration file",
					Value: defaultWifiClientConfig,
				},
				cli.BoolFlag{
					Name:  "enable",
					Usage: "Enables wifi",
				},
				cli.BoolFlag{
					Name:  "disable",
					Usage: "Disable wifi",
				},
				cli.BoolFlag{
					Name:  "remove",
					Usage: "Remove wifi",
				},
			},
			Action: WifiClientCMD,
		},
		{
			Name:    "access-point",
			Aliases: []string{"a"},
			Usage:   "configures access point with systemd",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "name",
					Usage: "The name of the unit file",
					Value: apConfigFile,
				},
				cli.StringFlag{
					Name:  "dir",
					Usage: "The directory in which to write the file",
					Value: apConfigBase,
				},
				cli.StringFlag{
					Name:  "config",
					Usage: "The path to the json configuration file",
					Value: defaultAccessPointConfig,
				},
				cli.BoolFlag{
					Name:  "enable",
					Usage: "Enables wifi",
				},
				cli.BoolFlag{
					Name:  "disable",
					Usage: "Disable wifi",
				},
				cli.BoolFlag{
					Name:  "remove",
					Usage: "Remove wifi",
				},
			},
			Action: ApCMD,
		},
	}
	err := app.Run(os.Args)
	if err != nil {
		log.Fatalf("fconf: %v", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"bufio"
	"unicode"
	"fmt"
	"strconv"
)

type TokenType int

const (
	ErrorToken TokenType = iota
	KeywordToken
	IdentToken
	IntegerToken
)

type Keyword int

const (
	VarKeyword Keyword = iota // var
	AssignKeyword // =
	AddKeyword // +
	SubKeyword // -
	MulKeyword // *
	ModKeyword // %
	SemiColonKeyword // ;
)

type Token struct {
	Type TokenType
	Payload interface{}
	Line, Column int
}

type StateFunc func (l *Lexer) StateFunc

type Lexer struct {
	Input *bufio.Reader
	buffer string
	lastRuneWidth int
	Line, Column int
	State StateFunc
	Tokens chan *Token
}

func (l *Lexer) Emit() string {
	var n string
	b := l.buffer
	l.buffer = n
	return b
}

func (l *Lexer) Next() (rune, error) {
	r, w, err := l.Input.ReadRune()
	if err != nil {
		return r, err
	}
	l.lastRuneWidth = w
	l.buffer += string(r)
	if r == '\n' {
		l.Line++
		l.Column = 0
	} else {
		l.Column++
	}
	return r, nil
}

type RunePredicate func (rune) bool

// Reads up to unaccepted rune
func (l *Lexer) NextUpTo(pred RunePredicate) (r rune, err error) {
	for {
		r, err = l.Peek()
		if err != nil || !pred(r) {
			return r, err
		}
		l.Next()
	}
}

// Ignores up to unaccepted rune
func (l *Lexer) IgnoreUpTo(pred RunePredicate) (r rune, err error) {
	for {
		r, err = l.Peek()
		if err != nil || !pred(r) {
			return r, err
		}
		l.Ignore()
	}
}

func (l *Lexer) Ignore() (rune, error) {
	r, err := l.Next()
	if err != nil {
		return r, err
	}
	l.buffer = l.buffer[:len(l.buffer)-l.lastRuneWidth]
	return r, nil
}

func (l *Lexer) Back() error {
	err := l.Input.UnreadRune()
	if err != nil {
		return err
	}
	l.Column--
	l.buffer = l.buffer[:len(l.buffer)-l.lastRuneWidth]
	return nil
}

func (l *Lexer) Peek() (rune, error) {
	r, err := l.Next()
	if err != nil {
		return r, err
	}
	err = l.Back()
	if err != nil {
		return r, err
	}
	return r, nil
}

func (l *Lexer) emitToken(t *Token) {
	l.Tokens<- t
}

// utility whitespace lex function
func (l *Lexer) whitespace() error {
	r, err := l.Peek()
	if err != nil {
		return err
	}
	for unicode.Is(unicode.White_Space, r) {
		l.Next()
		r, err = l.Peek()
		if err != nil {
			return err
		}
	}
	l.Emit() // dump
	return nil
}

func floatState(l *Lexer) StateFunc {
	return nil
}

func numberState(l *Lexer) StateFunc {
	base := 10

	// possible prefix
	r, err := l.Peek()
	if err != nil {
		return nil
	}
	if r == '0' {
		l.Next()
		r, err := l.Next()
		if err != nil {
			return nil
		}
		switch r {
		case 'x':
			l.Emit()
			base = 16 // hexadecimal
		case 'c':
			l.Emit()
			base = 8 // octal
		case 'b':
			l.Emit()
			base = 2 // binary
		default:
			l.Back()
		}
	}

	r, _ = l.NextUpTo(func(r rune) bool {
		// allow '_' separator
		if base == 16 {
			return unicode.Is(unicode.Hex_Digit, r) || r == '_'
		} else {
			return unicode.IsDigit(r) || r == '_'
		}
	})

	if r == '.' {
		// floating point number
		return floatState
	} else {
		i, err := strconv.ParseInt(l.Emit(), base, 64)
		if err != nil {
			l.emitToken(&Token {
				Type: ErrorToken,
				Payload: fmt.Sprint(err),
				Line: l.Line,
				Column: l.Column,
			})
			return startState
		}
		l.emitToken(&Token {
			Type: IntegerToken,
			Payload: i,
			Line: l.Line,
			Column: l.Column,
		})
		return expressionState
	}
}

func expressionState(l *Lexer) StateFunc {
	if l.whitespace() != nil {
		return nil
	}
	r, err := l.Peek()
	if err != nil {
		return nil
	}
	switch {
	case unicode.IsDigit(r):
		return numberState
	case r == '+' || r == '-' || r == '*' || r == '%':
		l.Next()
		var k Keyword
		switch r {
		case '+':
			k = AddKeyword
		case '-':
			k = SubKeyword
		case '*':
			k = MulKeyword
		case '%':
			k = ModKeyword
		}
		l.emitToken(&Token {
			Type: KeywordToken,
			Payload: k,
			Line: l.Line,
			Column: l.Column,
		})
		return expressionState
	case r == ';':
		l.Next()
		l.emitToken(&Token {
			Type: KeywordToken,
			Payload: SemiColonKeyword,
			Line: l.Line,
			Column: l.Column,
		})
		return startState
	default:
		l.Next()
		l.Tokens<- (&Token {
			Type: ErrorToken,
			Payload: fmt.Sprintf("Unexpected rune '%c' in expression", r),
			Line: l.Line,
			Column: l.Column,
		})
		return startState
	}
}

// = 1+3*a
func assignExpressionState(l *Lexer) StateFunc {
	if l.whitespace() != nil {
		return nil
	}
	r, err := l.Ignore()
	if err != nil {
		return nil
	}
	if r != '=' {
		// error, missing equals sign
		l.emitToken(&Token {
			Type: ErrorToken,
			Payload: fmt.Sprintf("Expected '=', found %c\n", r),
			Line: l.Line,
			Column: l.Column,
		})
		return startState
	} else {
		l.emitToken(&Token {
			Type: KeywordToken,
			Payload: AssignKeyword,
			Line: l.Line,
			Column: l.Column,
		})
		return expressionState
	}
}

func varIdentState(l *Lexer) StateFunc {
	l.NextUpTo(func (r rune) bool {
		return unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_'
	})
	l.emitToken(&Token {
		Type: IdentToken,
		Payload: l.Emit(),
		Line: l.Line,
		Column: l.Column,
	})
	return assignExpressionState
}

func varState(l *Lexer) StateFunc {
	if l.whitespace() != nil {
		return nil
	}
	r, err := l.Peek()
	if err != nil {
		return nil
	}
	if unicode.IsLetter(r) || r == '_' {
		return varIdentState
	}
	return nil
}

func keywordState(l *Lexer) StateFunc {
	l.NextUpTo(unicode.IsLetter)
	l.emitToken(&Token {
		Type: KeywordToken,
		Payload: VarKeyword,
		Line: l.Line,
		Column: l.Column,
	})
	if l.Emit() == "var" {
		return varState
	}
	return nil
}

func startState(l *Lexer) StateFunc {
	if l.whitespace() != nil {
		return nil
	}
	r, err := l.Peek()
	if err != nil {
		return nil
	}
	if unicode.IsLetter(r) {
		return keywordState
	}
	return nil
}

func (l *Lexer) Run() {
	for l.State != nil {
		l.State = l.State(l)
	}
	close(l.Tokens)
}

// Prompting Reader
type Repl struct {
	Input *bufio.Reader
	Output *bufio.Writer
	lexer *Lexer
}

func (r *Repl) Init() chan *Token {
	r.lexer = &Lexer {
		State: startState,
		Input: bufio.NewReader(r),
		Tokens: make(chan *Token),
	}
	go r.lexer.Run()
	return r.lexer.Tokens
}

func (r *Repl) Read(p []byte) (n int, err error) {
	for i := 0; i < len(p); i++ {
		b, err := r.Input.ReadByte()
		if err != nil {
			return i, err
		}
		p[i] = b
		if b == '\n' {
			return i, nil
		}
	}
	return len(p), nil
}

type SyntaxTree struct {
	Tok *Token
	Left, Right *SyntaxTree
}

// recursive descent parser
// TODO: make a state machine with each
// state returning two subsequent states,
// one for each child.
type Parser struct {
	Input chan *Token
	tree *SyntaxTree
}

func (p *Parser) parseIdent() *SyntaxTree {
	tok := <-p.Input
	if tok.Type != IdentToken {
		fmt.Printf("Expected ident, not found!\n");
	}
	return &SyntaxTree {
		Tok: tok,
	}
}

func (p *Parser) parseExpression() *SyntaxTree {
	return nil
}

func (p *Parser) parseAssignment() {
	a := <-p.Input
	if a.Type != KeywordToken || a.Payload != AssignKeyword {
		fmt.Printf("Expected assignment, '=' not found!\n");
	}
}

func (p *Parser) parseKeyword() *SyntaxTree {
	t := new(SyntaxTree)
	t.Tok = <-p.Input
	if t.Tok.Type == KeywordToken {
		if t.Tok.Payload == VarKeyword {
			t.Right = p.parseIdent()
			p.parseAssignment()
			t.Left = p.parseExpression()
			return t
		}
	} else {
		fmt.Printf("Expected keyword, not found!\n");
	}
	return nil
}

func (p *Parser) Run() {
	p.tree = p.parseKeyword()
}

func (t *SyntaxTree) String() string {
	return fmt.Sprintf("{%v: %s, %s}", t.Tok, t.Right, t.Left)
}

func main() {
	r := Repl {
		Input: bufio.NewReader(os.Stdin),
		Output: bufio.NewWriter(os.Stdout),
	}
	p := Parser {
		Input: r.Init(),
	}
	p.Run()
	fmt.Println(p.tree)
}
<commit_msg>prefix notation parsing<commit_after>package main

import (
	"os"
	"bufio"
	"unicode"
	"fmt"
	"strconv"
)

type TokenType int

const (
	ErrorToken TokenType = iota
	KeywordToken
	IdentToken
	IntegerToken
)

type Keyword int

const (
	VarKeyword Keyword = iota // var
	AssignKeyword // =
	AddKeyword // +
	SubKeyword // -
	MulKeyword // *
	ModKeyword // %
	SemiColonKeyword // ;
)

type Token struct {
	Type TokenType
	Payload interface{}
	Line, Column int
}

type StateFunc func (l *Lexer) StateFunc

type Lexer struct {
	Input *bufio.Reader
	buffer string
	lastRuneWidth int
	Line, Column int
	State StateFunc
	Tokens chan *Token
}

func (l *Lexer) Emit() string {
	var n string
	b := l.buffer
	l.buffer = n
	return b
}

func (l *Lexer) Next() (rune, error) {
	r, w, err := l.Input.ReadRune()
	if err != nil {
		return r, err
	}
	l.lastRuneWidth = w
	l.buffer += string(r)
	if r == '\n' {
		l.Line++
		l.Column = 0
	} else {
		l.Column++
	}
	return r, nil
}

type RunePredicate func (rune) bool

// Reads up to unaccepted rune
func (l *Lexer) NextUpTo(pred RunePredicate) (r rune, err error) {
	for {
		r, err = l.Peek()
		if err != nil || !pred(r) {
			return r, err
		}
		l.Next()
	}
}

// Ignores up to unaccepted rune
func (l *Lexer) IgnoreUpTo(pred RunePredicate) (r rune, err error) {
	for {
		r, err = l.Peek()
		if err != nil || !pred(r) {
			return r, err
		}
		l.Ignore()
	}
}

func (l *Lexer) Ignore() (rune, error) {
	r, err := l.Next()
	if err != nil {
		return r, err
	}
	l.buffer = l.buffer[:len(l.buffer)-l.lastRuneWidth]
	return r, nil
}

func (l *Lexer) Back() error {
	err := l.Input.UnreadRune()
	if err != nil {
		return err
	}
	l.Column--
	l.buffer = l.buffer[:len(l.buffer)-l.lastRuneWidth]
	return nil
}

func (l *Lexer) Peek() (rune, error) {
	r, err := l.Next()
	if err != nil {
		return r, err
	}
	err = l.Back()
	if err != nil {
		return r, err
	}
	return r, nil
}

func (l *Lexer) emitToken(t *Token) {
	l.Tokens<- t
}

// utility whitespace lex function
func (l *Lexer) whitespace() error {
	r, err := l.Peek()
	if err != nil {
		return err
	}
	for unicode.Is(unicode.White_Space, r) {
		l.Next()
		r, err = l.Peek()
		if err != nil {
			return err
		}
	}
	l.Emit() // dump
	return nil
}

func floatState(l *Lexer) StateFunc {
	return nil
}

func numberState(l *Lexer) StateFunc {
	base := 10

	// possible prefix
	r, err := l.Peek()
	if err != nil {
		return nil
	}
	if r == '0' {
		l.Next()
		r, err := l.Next()
		if err != nil {
			return nil
		}
		switch r {
		case 'x':
			l.Emit()
			base = 16 // hexadecimal
		case 'c':
			l.Emit()
			base = 8 // octal
		case 'b':
			l.Emit()
			base = 2 // binary
		default:
			l.Back()
		}
	}

	r, _ = l.NextUpTo(func(r rune) bool {
		// allow '_' separator
		if base == 16 {
			return unicode.Is(unicode.Hex_Digit, r) || r == '_'
		} else {
			return unicode.IsDigit(r) || r == '_'
		}
	})

	if r == '.' {
		// floating point number
		return floatState
	} else {
		i, err := strconv.ParseInt(l.Emit(), base, 64)
		if err != nil {
			l.emitToken(&Token {
				Type: ErrorToken,
				Payload: fmt.Sprint(err),
				Line: l.Line,
				Column: l.Column,
			})
			return startState
		}
		l.emitToken(&Token {
			Type: IntegerToken,
			Payload: i,
			Line: l.Line,
			Column: l.Column,
		})
		return expressionState
	}
}

func expressionState(l *Lexer) StateFunc {
	if l.whitespace() != nil {
		return nil
	}
	r, err := l.Peek()
	if err != nil {
		return nil
	}
	switch {
	case unicode.IsDigit(r):
		return numberState
	case r == '+' || r == '-' || r == '*' || r == '%':
		l.Next()
		var k Keyword
		switch r {
		case '+':
			k = AddKeyword
		case '-':
			k = SubKeyword
		case '*':
			k = MulKeyword
		case '%':
			k = ModKeyword
		}
		l.emitToken(&Token {
			Type: KeywordToken,
			Payload: k,
			Line: l.Line,
			Column: l.Column,
		})
		return expressionState
	case r == ';':
		l.Next()
		l.emitToken(&Token {
			Type: KeywordToken,
			Payload: SemiColonKeyword,
			Line: l.Line,
			Column: l.Column,
		})
		return startState
	default:
		l.Next()
		l.Tokens<- (&Token {
			Type: ErrorToken,
			Payload: fmt.Sprintf("Unexpected rune '%c' in expression", r),
			Line: l.Line,
			Column: l.Column,
		})
		return startState
	}
}

// = 1+3*a
func assignExpressionState(l *Lexer) StateFunc {
	if l.whitespace() != nil {
		return nil
	}
	r, err := l.Ignore()
	if err != nil {
		return nil
	}
	if r != '=' {
		// error, missing equals sign
		l.emitToken(&Token {
			Type: ErrorToken,
			Payload: fmt.Sprintf("Expected '=', found %c\n", r),
			Line: l.Line,
			Column: l.Column,
		})
		return startState
	} else {
		l.emitToken(&Token {
			Type: KeywordToken,
			Payload: AssignKeyword,
			Line: l.Line,
			Column: l.Column,
		})
		return expressionState
	}
}

func varIdentState(l *Lexer) StateFunc {
	l.NextUpTo(func (r rune) bool {
		return unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_'
	})
	l.emitToken(&Token {
		Type: IdentToken,
		Payload: l.Emit(),
		Line: l.Line,
		Column: l.Column,
	})
	return assignExpressionState
}

func varState(l *Lexer) StateFunc {
	if l.whitespace() != nil {
		return nil
	}
	r, err := l.Peek()
	if err != nil {
		return nil
	}
	if unicode.IsLetter(r) || r == '_' {
		return varIdentState
	}
	return nil
}

func keywordState(l *Lexer) StateFunc {
	l.NextUpTo(unicode.IsLetter)
	l.emitToken(&Token {
		Type: KeywordToken,
		Payload: VarKeyword,
		Line: l.Line,
		Column: l.Column,
	})
	if l.Emit() == "var" {
		return varState
	}
	return nil
}

func startState(l *Lexer) StateFunc {
	if l.whitespace() != nil {
		return nil
	}
	r, err := l.Peek()
	if err != nil {
		return nil
	}
	if unicode.IsLetter(r) {
		return keywordState
	}
	return nil
}

func (l *Lexer) Run() {
	for l.State != nil {
		l.State = l.State(l)
	}
	close(l.Tokens)
}

// Prompting Reader
type Repl struct {
	Input *bufio.Reader
	Output *bufio.Writer
	lexer *Lexer
}

func (r *Repl) Init() chan *Token {
	r.lexer = &Lexer {
		State: startState,
		Input: bufio.NewReader(r),
		Tokens: make(chan *Token),
	}
	go r.lexer.Run()
	return r.lexer.Tokens
}

func (r *Repl) Read(p []byte) (n int, err error) {
	for i := 0; i < len(p); i++ {
		b, err := r.Input.ReadByte()
		if err != nil {
			return i, err
		}
		p[i] = b
		if b == '\n' {
			return i, nil
		}
	}
	return len(p), nil
}

type SyntaxTree struct {
	Tok *Token
	Left, Right *SyntaxTree
}

// recursive descent parser
// TODO: make a state machine with each
// state returning two subsequent states,
// one for each child.
type Parser struct {
	Input chan *Token
	tree *SyntaxTree
}

func (p *Parser) parseIdent() *SyntaxTree {
	tok := <-p.Input
	if tok.Type != IdentToken {
		fmt.Printf("Expected ident, not found!\n");
	}
	return &SyntaxTree {
		Tok: tok,
	}
}

func (p *Parser) parseExpression() *SyntaxTree {
	a := <-p.Input
	s := &SyntaxTree {
		Tok: a,
	}
	if a.Type == IntegerToken {
		return s
	} else if a.Type == KeywordToken && (a.Payload == AddKeyword || a.Payload == SubKeyword || a.Payload == MulKeyword || a.Payload == ModKeyword) {
		s.Right = p.parseExpression()
		s.Left = p.parseExpression()
		return s
	} else {
		fmt.Printf("Expected expression, not found!\n");
		return nil
	}
}

func (p *Parser) parseAssignment() {
	a := <-p.Input
	if a.Type != KeywordToken || a.Payload != AssignKeyword {
		fmt.Printf("Expected assignment, '=' not found!\n");
	}
}

func (p *Parser) parseKeyword() *SyntaxTree {
	t := new(SyntaxTree)
	t.Tok = <-p.Input
	if t.Tok.Type == KeywordToken {
		if t.Tok.Payload == VarKeyword {
			t.Right = p.parseIdent()
			p.parseAssignment()
			t.Left = p.parseExpression()
			return t
		}
	} else {
		fmt.Printf("Expected keyword, not found!\n");
	}
	return nil
}

func (p *Parser) Run() {
	p.tree = p.parseKeyword()
}

func (t *SyntaxTree) String() string {
	return fmt.Sprintf("{%v: %s, %s}", t.Tok, t.Right, t.Left)
}

func main() {
	r := Repl {
		Input: bufio.NewReader(os.Stdin),
		Output: bufio.NewWriter(os.Stdout),
	}
	p := Parser {
		Input: r.Init(),
	}
	p.Run()
	fmt.Println(p.tree)
}
<|endoftext|>