<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"net"
	"os"
	"os/user"
	"path/filepath"
	"strconv"
	"syscall"
	"time"
)

const baseDir string = "muck"
const inFile string = "in"
const outFile string = "out"

var (
	connectionName   string
	connectionServer string
	connectionPort   uint
	useSSL           bool
	debugMode        bool
)

func debugLog(log ...interface{}) {
	if debugMode {
		fmt.Println(log)
	}
}

func checkError(err error) {
	if err != nil {
		debugLog("checkError caught", err.Error())
		s := fmt.Sprintln("fatal error", err.Error())
		panic(s)
	}
}

func getTimestamp() string {
	return time.Now().Format("2006-01-02T150405")
}

func initVars() {
	flag.BoolVar(&useSSL, "ssl", false, "Enable ssl")
	flag.BoolVar(&debugMode, "debug", false, "Enable debug")
	flag.Parse()

	args := flag.Args()
	if len(args) != 3 {
		fmt.Println("Usage: mm [--ssl] [--debug] <name> <server> <port>")
		os.Exit(1)
	}
	connectionName = args[0]
	connectionServer = args[1]
	p, err := strconv.Atoi(args[2])
	checkError(err)
	connectionPort = uint(p)

	debugLog("Name:", connectionName)
	debugLog("Server:", connectionServer)
	debugLog("Port:", connectionPort)
	debugLog("SSL?:", useSSL)
}

func getWorkingDir(main string, sub string) string {
	u, err := user.Current()
	checkError(err)
	h := u.HomeDir
	debugLog("Home directory", h)

	w := filepath.Join(h, main, sub)
	debugLog("working directory", w)
	return w
}

func setupConnection(s string) net.Conn {
	tcpAddr, err := net.ResolveTCPAddr("tcp4", s)
	checkError(err)
	debugLog("server resolves to", tcpAddr)
	connection, err := net.DialTCP("tcp", nil, tcpAddr)
	checkError(err)
	fmt.Println("~Connected at", getTimestamp())

	// We keep alive for mucks
	errSka := connection.SetKeepAlive(true)
	checkError(errSka)
	keepalive := 15 * time.Minute
	errSkap := connection.SetKeepAlivePeriod(keepalive)
	checkError(errSkap)
	return connection
}

func makeFIFO(file string) *os.File {
	if _, err := os.Stat(file); err == nil {
		fmt.Println("FIFO already exists. Unlink or exit")
		fmt.Println("if you run multiple connection with the same name you're gonna have a bad time")
		fmt.Print("Type YES to unlink and recreate: ")
		i := bufio.NewReader(os.Stdin)
		a, err := i.ReadString('\n')
		checkError(err)
		if a != "YES\n" {
			fmt.Println("Canceling. Please remove FIFO before running")
			panic("User Canceled at FIFO removal prompt")
		}
		errUn := syscall.Unlink(file)
		checkError(errUn)
		debugLog(file, "unlinked")
	}

	err := syscall.Mkfifo(file, 0644)
	checkError(err)
	debugLog("FIFO created as", file)
	f, err := os.OpenFile(file, syscall.O_RDONLY|syscall.O_NONBLOCK, 0666)
	checkError(err)
	debugLog("FIFO opened as", f.Name())
	return f
}

func readtoConn(f *os.File, c net.Conn, quit chan bool) {
	tmpError := fmt.Sprintf("read %v: resource temporarily unavailable", f.Name())
	for {
		select {
		case <-quit:
			debugLog("readtoConn got quit, returning")
			return
		default:
			buf := make([]byte, 512)
			bi, err := f.Read(buf)
			if err != nil && err.Error() != "EOF" && err.Error() != tmpError {
				checkError(err)
			} else if bi == 0 {
				continue
			}
			debugLog(bi, "bytes read from FIFO")
			bo, err := c.Write(buf[:bi])
			checkError(err)
			debugLog(bo, "bytes written to file")
		}
	}
}

func readToFile(c net.Conn, f *os.File, quit chan bool) {
	for {
		buf := make([]byte, 512)
		bi, err := c.Read(buf)
		if err != nil {
			fmt.Println("Connection broken,", err.Error())
			quit <- true
			return
		}
		debugLog(bi, "bytes read from connection")

		bo, err := f.Write(buf[:bi])
		checkError(err)
		debugLog(bo, "bytes written to file")
	}
}

func closeConnection(c net.Conn) {
	fmt.Println("~Closing connection at", getTimestamp())
	err := c.Close()
	if err != nil {
		debugLog(err.Error())
	}
	debugLog("Connection closed")
}

func closeFIFO(f *os.File) {
	n := f.Name()
	debugLog("closing and deleting FIFO", n)
	errC := f.Close()
	if errC != nil {
		debugLog(errC.Error())
	}
	errU := syscall.Unlink(n)
	if errU != nil {
		debugLog(errU.Error())
	}
	debugLog(n, "closed and deleted")
}

func closeLog(f *os.File) {
	n := f.Name()
	debugLog("closing and rotating file", n)
	errC := f.Close()
	if errC != nil {
		debugLog(errC.Error())
	}
	if _, err := os.Stat(n); err != nil {
		fmt.Println("out file doesn't exist? not rotating")
		return
	}
	errR := os.Rename(outFile, getTimestamp())
	if errR != nil {
		debugLog(errR.Error())
	}
	debugLog(n, "closed and rotated")
}

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Recovered", r)
		}
	}()

	fmt.Println("~Started at", getTimestamp())
	initVars()

	// Make and move to working directory
	workingDir := getWorkingDir(baseDir, connectionName)
	errMk := os.MkdirAll(workingDir, 0755)
	checkError(errMk)

	errCh := os.Chdir(workingDir)
	checkError(errCh)

	//create connection
	server := fmt.Sprintf("%s:%d", connectionServer, connectionPort)
	connection := setupConnection(server)
	defer closeConnection(connection)

	// Make the in FIFO
	in := makeFIFO(inFile)
	defer closeFIFO(in)

	// Make the out file
	out, err := os.Create(outFile)
	checkError(err)
	debugLog("Logfile created as", out.Name())
	defer closeLog(out)

	quit := make(chan bool)
	go readToFile(connection, out, quit)
	readtoConn(in, connection, quit)

	debugLog("End of main hit")
}
<commit_msg>Use a struct for server to be more sane<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"net"
	"os"
	"os/user"
	"path/filepath"
	"strconv"
	"syscall"
	"time"
)

// mostly hardcoded program settings
const baseDir string = "muck"
const inFile string = "in"
const outFile string = "out"

// Keep debug global
var debugMode bool

// Simple struct for our connection
type MuckServer struct {
	name string
	host string
	port uint
	ssl  bool
}

// Simplify returning connection strings by making it the String method
func (m *MuckServer) String() string {
	s := fmt.Sprintf("%s:%d", m.host, m.port)
	return s
}

func debugLog(log ...interface{}) {
	if debugMode {
		fmt.Print("DEBUG: ")
		fmt.Println(log...)
	}
}

func checkError(err error) {
	if err != nil {
		debugLog("checkError caught", err.Error())
		s := fmt.Sprintln("fatal error", err.Error())
		panic(s)
	}
}

func getTimestamp() string {
	return time.Now().Format("2006-01-02T150405")
}

func initArgs() MuckServer {
	flag.BoolVar(&debugMode, "debug", false, "Enable debug")
	ssl := flag.Bool("ssl", false, "Enable ssl")
	flag.Parse()

	args := flag.Args()
	if len(args) != 3 {
		fmt.Println("Usage: mm [--ssl] [--debug] <name> <server> <port>")
		os.Exit(1)
	}
	p, err := strconv.Atoi(args[2])
	checkError(err)

	s := MuckServer{name: args[0], host: args[1], port: uint(p), ssl: *ssl}

	debugLog("name:", s.name)
	debugLog("host:", s.host)
	debugLog("port:", s.port)
	debugLog("SSL?:", s.ssl)

	return s
}

func getWorkingDir(main string, sub string) string {
	u, err := user.Current()
	checkError(err)
	h := u.HomeDir
	debugLog("Home directory", h)

	w := filepath.Join(h, main, sub)
	debugLog("working directory", w)
	return w
}

func setupConnection(s *MuckServer) net.Conn {
	tcpAddr, err := net.ResolveTCPAddr("tcp4", s.String())
	checkError(err)
	debugLog("server resolves to", tcpAddr)
	connection, err := net.DialTCP("tcp", nil, tcpAddr)
	checkError(err)
	fmt.Println("~Connected at", getTimestamp())

	// We keep alive for mucks
	errSka := connection.SetKeepAlive(true)
	checkError(errSka)
	keepalive := 15 * time.Minute
	errSkap := connection.SetKeepAlivePeriod(keepalive)
	checkError(errSkap)
	return connection
}

func setupTLSConnextion(s *MuckServer) net.Conn {
	var connection net.Conn
	return connection

}

func makeFIFO(file string) *os.File {
	if _, err := os.Stat(file); err == nil {
		fmt.Println("FIFO already exists. Unlink or exit")
		fmt.Println("if you run multiple connection with the same name you're gonna have a bad time")
		fmt.Print("Type YES to unlink and recreate: ")
		i := bufio.NewReader(os.Stdin)
		a, err := i.ReadString('\n')
		checkError(err)
		if a != "YES\n" {
			fmt.Println("Canceling. Please remove FIFO before running")
			panic("User Canceled at FIFO removal prompt")
		}
		errUn := syscall.Unlink(file)
		checkError(errUn)
		debugLog(file, "unlinked")
	}

	err := syscall.Mkfifo(file, 0644)
	checkError(err)
	debugLog("FIFO created as", file)
	f, err := os.OpenFile(file, syscall.O_RDONLY|syscall.O_NONBLOCK, 0666)
	checkError(err)
	debugLog("FIFO opened as", f.Name())
	return f
}

func readtoConn(f *os.File, c net.Conn, quit chan bool) {
	tmpError := fmt.Sprintf("read %v: resource temporarily unavailable", f.Name())
	for {
		select {
		case <-quit:
			debugLog("readtoConn got quit, returning")
			return
		default:
			buf := make([]byte, 512)
			bi, err := f.Read(buf)
			if err != nil && err.Error() != "EOF" && err.Error() != tmpError {
				checkError(err)
			} else if bi == 0 {
				continue
			}
			debugLog(bi, "bytes read from FIFO")
			bo, err := c.Write(buf[:bi])
			checkError(err)
			debugLog(bo, "bytes written to file")
		}
	}
}

func readToFile(c net.Conn, f *os.File, quit chan bool) {
	for {
		buf := make([]byte, 512)
		bi, err := c.Read(buf)
		if err != nil {
			fmt.Println("Connection broken,", err.Error())
			quit <- true
			return
		}
		debugLog(bi, "bytes read from connection")

		bo, err := f.Write(buf[:bi])
		checkError(err)
		debugLog(bo, "bytes written to file")
	}
}

func closeConnection(c net.Conn) {
	fmt.Println("~Closing connection at", getTimestamp())
	err := c.Close()
	if err != nil {
		debugLog(err.Error())
	}
	debugLog("Connection closed")
}

func closeFIFO(f *os.File) {
	n := f.Name()
	debugLog("closing and deleting FIFO", n)
	errC := f.Close()
	if errC != nil {
		debugLog(errC.Error())
	}
	errU := syscall.Unlink(n)
	if errU != nil {
		debugLog(errU.Error())
	}
	debugLog(n, "closed and deleted")
}

func closeLog(f *os.File) {
	n := f.Name()
	debugLog("closing and rotating file", n)
	errC := f.Close()
	if errC != nil {
		debugLog(errC.Error())
	}
	if _, err := os.Stat(n); err != nil {
		fmt.Println("out file doesn't exist? not rotating")
		return
	}
	errR := os.Rename(outFile, getTimestamp())
	if errR != nil {
		debugLog(errR.Error())
	}
	debugLog(n, "closed and rotated")
}

func main() {
	// checkError throws a panic, catch it at the end and return error to user
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("FATAL ERROR", r)
		}
	}()

	fmt.Println("~Started at", getTimestamp())
	server := initArgs()

	// Make and move to working directory
	workingDir := getWorkingDir(baseDir, server.name)
	errMk := os.MkdirAll(workingDir, 0755)
	checkError(errMk)

	errCh := os.Chdir(workingDir)
	checkError(errCh)

	//create connection
	var connection net.Conn
	if server.ssl == true {
		connection = setupTLSConnextion(&server)
	} else {
		connection = setupConnection(&server)
	}
	defer closeConnection(connection)

	// Make the in FIFO
	in := makeFIFO(inFile)
	defer closeFIFO(in)

	// Make the out file
	out, err := os.Create(outFile)
	checkError(err)
	debugLog("Logfile created as", out.Name())
	defer closeLog(out)

	quit := make(chan bool)
	go readToFile(connection, out, quit)
	readtoConn(in, connection, quit)

	debugLog("End of main hit")
}
<|endoftext|>


<commit_before>package main

import (
	log "github.com/cihub/seelog"
)

type Fetcher interface {
	// Fetch returns the body of URL and
	// a slice of URLs found on that page.
	Fetch(url string) (body string, urls []string, err error)
}

func main() {

	// Flush logs before exit
	defer log.Flush()

	fetcher := &HttpFetcher{}

	// Crawl the specified site
	Crawl("http://golang.org/", 4, fetcher)
}

// Crawl uses fetcher to recursively crawl
// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher) {

	_, urls, err := fetcher.Fetch(url)
	if err != nil {
		log.Errorf("Error:", err)
		return
	}

	log.Infof("URLs found: %+v", urls)
}
<commit_msg>Process flags, crawl specified domain<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	log "github.com/cihub/seelog"
)

type Fetcher interface {
	// Fetch returns the body of URL and
	// a slice of URLs found on that page.
	Fetch(url string) (body string, urls []string, err error)
}

func main() {
	// Flush logs before exit
	defer log.Flush()

	var target string

	// Process flags
	flag.StringVar(&target, "target", "", "Target URL to crawl")
	flag.Parse()

	// Good to go?
	if target == "" {
		fmt.Println("Please specify a target domain, eg. kraken -target=\"http://example.com\"")
		os.Exit(1)
	}
	log.Infof("Unleashing the Kraken at %s", target)

	// Use a HTTP based fetcher
	fetcher := &HttpFetcher{}

	// Crawl the specified site
	Crawl(target, 4, fetcher)
}

// Crawl uses fetcher to recursively crawl
// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher) {

	_, urls, err := fetcher.Fetch(url)
	if err != nil {
		log.Errorf("Error:", err)
		return
	}

	log.Infof("URLs found: %+v", urls)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/codegangsta/cli"
)

func format(cc string) {
	fmt.Printf("=> Writing formatted cloud-config to STDOUT...\n")
	file, err := os.Open(cc)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		fmt.Println("\"" + strings.Replace(scanner.Text(), "\"", "\\\"", -1) + "\\n\",")
	}
	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}
}

func formatOut(cc, outPath string) {
	fmt.Printf("=> Writing formatted cloud-config to %s...\n", cc)
	file, err := os.Open(cc)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	out, err := os.Create(outPath)
	if err != nil {
		log.Fatal(err)
	}
	defer out.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		out.WriteString("\"" + strings.Replace(scanner.Text(), "\"", "\\\"", -1) + "\\n\",\n")
	}
	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}
}

func inject(toInject, toReceive string, start, end int64) {
	fmt.Printf("=> Removing lines [%d:%d] in %s...\n", start, end, toReceive)
	// read in the lines to be received
	receiving, err := os.Open(toReceive)
	if err != nil {
		log.Fatal(err)
	}

	receivingScanner := bufio.NewScanner(receiving)
	lines := []string{}
	for receivingScanner.Scan() {
		lines = append(lines, receivingScanner.Text())
	}
	if err := receivingScanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}

	// read in the lines to be injected
	injecting, err := os.Open(toInject)
	if err != nil {
		log.Fatal(err)
	}
	defer injecting.Close()

	injectingScanner := bufio.NewScanner(injecting)
	linesToInject := []string{}
	for injectingScanner.Scan() {
		linesToInject = append(linesToInject, injectingScanner.Text())
	}
	if err := injectingScanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}

	// combine all parts of the file into one
	fmt.Printf("=> Injecting %s into %s...", toInject, toReceive)
	pre := lines[0 : start-1]
	post := lines[end:]
	injectedLines := append(pre, linesToInject...)
	injectedLines = append(injectedLines, post...)

	// write to the receiving file
	receiving.Close()
	receivingWrite, err := os.Create(toReceive)
	if err != nil {
		log.Fatal(err)
	}
	defer receivingWrite.Close()

	for _, s := range injectedLines {
		receivingWrite.WriteString(s + "\n")
	}
	receivingWrite.Sync()
}

func main() {
	app := cli.NewApp()
	app.Name = "cumulus"
	app.Authors = []cli.Author{
		{
			Name:  "Ben Bailey",
			Email: "bennettbailey@gmail.com",
		},
	}
	app.Usage = "inject cloud-configs into cloud-formation templates"
	app.Commands = []cli.Command{
		{
			Name:  "format",
			Usage: "format a cloud-config file into an acceptable JSON structure",
			Action: func(c *cli.Context) {
				if len(c.Args()) == 1 {
					format(c.Args().First())
				} else if len(c.Args()) == 2 {
					formatOut(c.Args().First(), c.Args().Get(1))
				} else {
					log.Fatal("Format takes one or two arguments.")
				}

			},
		},
		{
			Name:  "inject",
			Usage: "inject a file into another, first removing from line1 to line2",
			Action: func(c *cli.Context) {
				start, _ := strconv.ParseInt(c.Args().Get(2), 0, 0)
				end, _ := strconv.ParseInt(c.Args().Get(3), 0, 0)
				inject(c.Args().First(), c.Args().Get(1), start, end)
			},
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "format",
					Usage: "format the cloud-config before injecting it",
				},
			},
		},
	}
	app.Run(os.Args)
}
<commit_msg>update main<commit_after>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/codegangsta/cli"
)

func format(cc string) {
	fmt.Printf("=> Writing formatted cloud-config to STDOUT...\n")
	file, err := os.Open(cc)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		fmt.Println("\"" + strings.Replace(scanner.Text(), "\"", "\\\"", -1) + "\\n\",")
	}
	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}
}

func formatOut(cc, outPath string) {
	fmt.Printf("=> Writing formatted cloud-config to %s...\n", cc)
	file, err := os.Open(cc)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	out, err := os.Create(outPath)
	if err != nil {
		log.Fatal(err)
	}
	defer out.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		out.WriteString("\"" + strings.Replace(scanner.Text(), "\"", "\\\"", -1) + "\\n\",\n")
	}
	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}
}

func formatTmp(cc string) *os.File {
	fmt.Printf("=> Writing formatted cloud-config to a temporary file...\n")
	file, err := os.Open(cc)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	tmp, err := ioutil.TempFile("/tmp", "cloudcfg")
	if err != nil {
		log.Fatal(err)
	}

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		tmp.WriteString("\"" + strings.Replace(scanner.Text(), "\"", "\\\"", -1) + "\\n\",\n")
	}
	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}

	return tmp
}

func inject(toInject, toReceive string, start, end int64) {
	fmt.Printf("=> Removing lines [%d:%d] in %s...\n", start, end, toReceive)
	// read in the lines to be received
	receiving, err := os.Open(toReceive)
	if err != nil {
		log.Fatal(err)
	}

	receivingScanner := bufio.NewScanner(receiving)
	lines := []string{}
	for receivingScanner.Scan() {
		lines = append(lines, receivingScanner.Text())
	}
	if err := receivingScanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}

	// read in the lines to be injected
	injecting, err := os.Open(toInject)
	if err != nil {
		log.Fatal(err)
	}
	defer injecting.Close()

	injectingScanner := bufio.NewScanner(injecting)
	linesToInject := []string{}
	for injectingScanner.Scan() {
		linesToInject = append(linesToInject, injectingScanner.Text())
	}
	if err := injectingScanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}

	// combine all parts of the file into one
	fmt.Printf("=> Injecting %s into %s...", toInject, toReceive)
	pre := lines[0 : start-1]
	post := lines[end:]
	injectedLines := append(pre, linesToInject...)
	injectedLines = append(injectedLines, post...)

	// write to the receiving file
	receiving.Close()
	receivingWrite, err := os.Create(toReceive)
	if err != nil {
		log.Fatal(err)
	}
	defer receivingWrite.Close()

	for _, s := range injectedLines {
		receivingWrite.WriteString(s + "\n")
	}
	receivingWrite.Sync()
}

func injectAndFormat(toInject, toReceive string, start, end int64) {
	tmpFile := formatTmp(toInject).Name()
	inject(tmpFile, toReceive, start, end)
	defer os.Remove(tmpFile)
}

func main() {
	app := cli.NewApp()
	app.Name = "cumulus"
	app.Authors = []cli.Author{
		{
			Name:  "Ben Bailey",
			Email: "bennettbailey@gmail.com",
		},
	}
	app.Usage = "inject cloud-configs into cloud-formation templates"
	app.Commands = []cli.Command{
		{
			Name:  "format",
			Usage: "format a cloud-config file into an acceptable JSON structure",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "tmp",
					Usage: "write the cloud-config to a tmp file",
				},
				cli.StringFlag{
					Name:  "out",
					Usage: "write the cloud-config to this file",
				},
			},
			Action: func(c *cli.Context) {
				if c.String("out") != "" {
					formatOut(c.Args().First(), c.String("out"))
				} else if c.Bool("tmp") {
					formatTmp(c.Args().First())
				} else {
					format(c.Args().First())
				}

			},
		},
		{
			Name:  "inject",
			Usage: "inject a file into another, first removing from line1 to line2",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "format",
					Usage: "format the cloud-config before injecting it",
				},
			},
			Action: func(c *cli.Context) {
				start, _ := strconv.ParseInt(c.Args().Get(2), 0, 0)
				end, _ := strconv.ParseInt(c.Args().Get(3), 0, 0)
				if c.Bool("format") == true {
					injectAndFormat(c.Args().First(), c.Args().Get(1), start, end)
				} else {
					inject(c.Args().First(), c.Args().Get(1), start, end)
				}
			},
		},
	}
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"compress/gzip"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strings"
)

var (
	flagOut    = flag.String("o", "", "Output file, else stdout.")
	flagPkg    = flag.String("pkg", "main", "Package.")
	flagPrefix = flag.String("prefix", "", "Prefix to strip from filesnames.")
)

type file struct {
	data  []byte
	local string
}

func main() {
	flag.Parse()
	var err error
	var fnames []string
	content := make(map[string]file)
	prefix := filepath.ToSlash(*flagPrefix)
	for _, base := range flag.Args() {
		files := []string{base}
		for len(files) > 0 {
			fname := files[0]
			files = files[1:]
			f, err := os.Open(fname)
			if err != nil {
				log.Fatal(err)
			}
			fi, err := f.Stat()
			if err != nil {
				log.Fatal(err)
			}
			if fi.IsDir() {
				fis, err := f.Readdir(0)
				if err != nil {
					log.Fatal(err)
				}
				for _, fi := range fis {
					files = append(files, filepath.Join(fname, fi.Name()))
				}
			} else {
				b, err := ioutil.ReadAll(f)
				if err != nil {
					log.Fatal(err)
				}
				fpath := filepath.ToSlash(fname)
				n := strings.TrimPrefix(fpath, prefix)
				n = path.Join("/", n)
				content[n] = file{data: b, local: fpath}
				fnames = append(fnames, n)
			}
			f.Close()
		}
	}
	sort.Strings(fnames)
	w := os.Stdout
	if *flagOut != "" {
		if w, err = os.Create(*flagOut); err != nil {
			log.Fatal(err)
		}
		defer w.Close()
	}
	fmt.Fprintf(w, header, *flagPkg)
	for _, fname := range fnames {
		f := content[fname]
		var buf bytes.Buffer
		gw := gzip.NewWriter(&buf)
		if _, err := gw.Write(f.data); err != nil {
			log.Fatal(err)
		}
		if err := gw.Close(); err != nil {
			log.Fatal(err)
		}
		fmt.Fprintf(w, "\n\t%q: {compressed: %q, size: %v, local: %q},\n", fname, buf.String(), len(f.data), f.local)
	}
	fmt.Fprint(w, footer)
}

const (
	header = `package %s

import (
	"bytes"
	"compress/gzip"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"sync"
	"time"
)

type localFS struct{}

var local localFS

type staticFS struct{}

var static staticFS

type file struct {
	compressed string
	size       int64
	local      string

	data []byte
	once sync.Once
	name string
}

func (_ localFS) Open(name string) (http.File, error) {
	f, present := data[name]
	if !present {
		return nil, os.ErrNotExist
	}
	return os.Open(f.local)
}

func (_ staticFS) Open(name string) (http.File, error) {
	f, present := data[name]
	if !present {
		return nil, os.ErrNotExist
	}
	var err error
	f.once.Do(func() {
		var gr *gzip.Reader
		gr, err = gzip.NewReader(bytes.NewBufferString(f.compressed))
		if err != nil {
			return
		}
		f.data, err = ioutil.ReadAll(gr)
		f.name = path.Base(name)
	})
	return f.File()
}

func (f *file) File() (http.File, error) {
	return &httpFile{
		Reader: bytes.NewReader(f.data),
		file:   f,
	}, nil
}

type httpFile struct {
	*bytes.Reader
	*file
}

func (f *file) Close() error {
	return nil
}

func (f *file) Readdir(count int) ([]os.FileInfo, error) {
	return nil, nil
}

func (f *file) Stat() (os.FileInfo, error) {
	return f, nil
}

func (f *file) Name() string {
	return f.name
}

func (f *file) Size() int64 {
	return f.size
}

func (f *file) Mode() os.FileMode {
	return 0
}

func (f *file) ModTime() time.Time {
	return time.Time{}
}
func (f *file) IsDir() bool {
	return false
}
func (f *file) Sys() interface{} {
	return f
}

// FS returns a http.Filesystem for the embedded assets. If local is true,
// the filesystem's contents are instead used.
func FS(useLocal bool) http.FileSystem {
	if useLocal {
		return local
	}
	return static
}

var data = map[string]*file{
`
	footer = `}
`
)
<commit_msg>Accurate doc comment<commit_after>package main

import (
	"bytes"
	"compress/gzip"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strings"
)

var (
	flagOut    = flag.String("o", "", "Output file, else stdout.")
	flagPkg    = flag.String("pkg", "main", "Package.")
	flagPrefix = flag.String("prefix", "", "Prefix to strip from filesnames.")
)

type file struct {
	data  []byte
	local string
}

func main() {
	flag.Parse()
	var err error
	var fnames []string
	content := make(map[string]file)
	prefix := filepath.ToSlash(*flagPrefix)
	for _, base := range flag.Args() {
		files := []string{base}
		for len(files) > 0 {
			fname := files[0]
			files = files[1:]
			f, err := os.Open(fname)
			if err != nil {
				log.Fatal(err)
			}
			fi, err := f.Stat()
			if err != nil {
				log.Fatal(err)
			}
			if fi.IsDir() {
				fis, err := f.Readdir(0)
				if err != nil {
					log.Fatal(err)
				}
				for _, fi := range fis {
					files = append(files, filepath.Join(fname, fi.Name()))
				}
			} else {
				b, err := ioutil.ReadAll(f)
				if err != nil {
					log.Fatal(err)
				}
				fpath := filepath.ToSlash(fname)
				n := strings.TrimPrefix(fpath, prefix)
				n = path.Join("/", n)
				content[n] = file{data: b, local: fpath}
				fnames = append(fnames, n)
			}
			f.Close()
		}
	}
	sort.Strings(fnames)
	w := os.Stdout
	if *flagOut != "" {
		if w, err = os.Create(*flagOut); err != nil {
			log.Fatal(err)
		}
		defer w.Close()
	}
	fmt.Fprintf(w, header, *flagPkg)
	for _, fname := range fnames {
		f := content[fname]
		var buf bytes.Buffer
		gw := gzip.NewWriter(&buf)
		if _, err := gw.Write(f.data); err != nil {
			log.Fatal(err)
		}
		if err := gw.Close(); err != nil {
			log.Fatal(err)
		}
		fmt.Fprintf(w, "\n\t%q: {compressed: %q, size: %v, local: %q},\n", fname, buf.String(), len(f.data), f.local)
	}
	fmt.Fprint(w, footer)
}

const (
	header = `package %s

import (
	"bytes"
	"compress/gzip"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"sync"
	"time"
)

type localFS struct{}

var local localFS

type staticFS struct{}

var static staticFS

type file struct {
	compressed string
	size       int64
	local      string

	data []byte
	once sync.Once
	name string
}

func (_ localFS) Open(name string) (http.File, error) {
	f, present := data[name]
	if !present {
		return nil, os.ErrNotExist
	}
	return os.Open(f.local)
}

func (_ staticFS) Open(name string) (http.File, error) {
	f, present := data[name]
	if !present {
		return nil, os.ErrNotExist
	}
	var err error
	f.once.Do(func() {
		var gr *gzip.Reader
		gr, err = gzip.NewReader(bytes.NewBufferString(f.compressed))
		if err != nil {
			return
		}
		f.data, err = ioutil.ReadAll(gr)
		f.name = path.Base(name)
	})
	return f.File()
}

func (f *file) File() (http.File, error) {
	return &httpFile{
		Reader: bytes.NewReader(f.data),
		file:   f,
	}, nil
}

type httpFile struct {
	*bytes.Reader
	*file
}

func (f *file) Close() error {
	return nil
}

func (f *file) Readdir(count int) ([]os.FileInfo, error) {
	return nil, nil
}

func (f *file) Stat() (os.FileInfo, error) {
	return f, nil
}

func (f *file) Name() string {
	return f.name
}

func (f *file) Size() int64 {
	return f.size
}

func (f *file) Mode() os.FileMode {
	return 0
}

func (f *file) ModTime() time.Time {
	return time.Time{}
}
func (f *file) IsDir() bool {
	return false
}
func (f *file) Sys() interface{} {
	return f
}

// FS returns a http.Filesystem for the embedded assets. If useLocal is true,
// the filesystem's contents are instead used.
func FS(useLocal bool) http.FileSystem {
	if useLocal {
		return local
	}
	return static
}

var data = map[string]*file{
`
	footer = `}
`
)
<|endoftext|>


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

package main

import (
	"bytes"
	"database/sql"
	"flag"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"os"
	"os/signal"
	"path/filepath"
	"strings"
	"syscall"
	tmpltext "text/template"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
	"github.com/prometheus/common/route"

	"github.com/prometheus/alertmanager/config"
	"github.com/prometheus/alertmanager/notify"
	"github.com/prometheus/alertmanager/provider/sqlite"
	"github.com/prometheus/alertmanager/template"
	"github.com/prometheus/alertmanager/types"
	"github.com/prometheus/alertmanager/version"
)

var (
	showVersion = flag.Bool("version", false, "Print version information.")

	configFile = flag.String("config.file", "alertmanager.yml", "Alertmanager configuration file name.")
	dataDir    = flag.String("storage.path", "data/", "Base path for data storage.")

	externalURL   = flag.String("web.external-url", "", "The URL under which Alertmanager is externally reachable (for example, if Alertmanager is served via a reverse proxy). Used for generating relative and absolute links back to Alertmanager itself. If the URL has a path portion, it will be used to prefix all HTTP endpoints served by Alertmanager. If omitted, relevant URL components will be derived automatically.")
	listenAddress = flag.String("web.listen-address", ":9093", "Address to listen on for the web interface and API.")
)

var (
	configSuccess = prometheus.NewGauge(prometheus.GaugeOpts{
		Namespace: "alertmanager",
		Name:      "config_last_reload_successful",
		Help:      "Whether the last configuration reload attempt was successful.",
	})
	configSuccessTime = prometheus.NewGauge(prometheus.GaugeOpts{
		Namespace: "alertmanager",
		Name:      "config_last_reload_success_timestamp_seconds",
		Help:      "Timestamp of the last successful configuration reload.",
	})
)

func init() {
	prometheus.MustRegister(configSuccess)
	prometheus.MustRegister(configSuccessTime)
}

func main() {
	flag.Parse()

	printVersion()
	if *showVersion {
		os.Exit(0)
	}

	err := os.MkdirAll(*dataDir, 0777)
	if err != nil {
		log.Fatal(err)
	}
	db, err := sql.Open("sqlite3", filepath.Join(*dataDir, "am.db"))
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	marker := types.NewMarker()

	alerts, err := sqlite.NewAlerts(db)
	if err != nil {
		log.Fatal(err)
	}
	notifies, err := sqlite.NewNotifies(db)
	if err != nil {
		log.Fatal(err)
	}
	silences, err := sqlite.NewSilences(db, marker)
	if err != nil {
		log.Fatal(err)
	}

	var (
		inhibitor *Inhibitor
		tmpl      *template.Template
		disp      *Dispatcher
	)
	defer disp.Stop()

	api := NewAPI(alerts, silences, func() AlertOverview {
		return disp.Groups()
	})

	build := func(rcvs []*config.Receiver) notify.Notifier {
		var (
			router  = notify.Router{}
			fanouts = notify.Build(rcvs, tmpl)
		)
		for name, fo := range fanouts {
			for i, n := range fo {
				n = notify.Retry(n)
				n = notify.Log(n, log.With("step", "retry"))
				n = notify.Dedup(notifies, n)
				n = notify.Log(n, log.With("step", "dedup"))

				fo[i] = n
			}
			router[name] = fo
		}
		n := notify.Notifier(router)

		n = notify.Log(n, log.With("step", "route"))
		n = notify.Silence(silences, n, marker)
		n = notify.Log(n, log.With("step", "silence"))
		n = notify.Inhibit(inhibitor, n, marker)
		n = notify.Log(n, log.With("step", "inhibit"))

		return n
	}

	reload := func() (err error) {
		log.With("file", *configFile).Infof("Loading configuration file")
		defer func() {
			if err != nil {
				log.With("file", *configFile).Errorf("Loading configuration file failed: %s", err)
				configSuccess.Set(0)
			} else {
				configSuccess.Set(1)
				configSuccessTime.Set(float64(time.Now().Unix()))
			}
		}()

		conf, err := config.LoadFile(*configFile)
		if err != nil {
			return err
		}

		api.Update(conf.String(), time.Duration(conf.Global.ResolveTimeout))

		tmpl, err = template.FromGlobs(conf.Templates...)
		if err != nil {
			return err
		}
		if tmpl.ExternalURL, err = extURL(*externalURL); err != nil {
			return err
		}

		disp.Stop()

		inhibitor = NewInhibitor(alerts, conf.InhibitRules, marker)
		disp = NewDispatcher(alerts, NewRoute(conf.Route, nil), build(conf.Receivers), marker)

		go disp.Run()

		return nil
	}

	if err := reload(); err != nil {
		os.Exit(1)
	}

	router := route.New()

	RegisterWeb(router)
	api.Register(router.WithPrefix("/api"))

	go listen(router)

	var (
		hup  = make(chan os.Signal)
		term = make(chan os.Signal)
	)
	signal.Notify(hup, syscall.SIGHUP)
	signal.Notify(term, os.Interrupt, syscall.SIGTERM)

	go func() {
		for range hup {
			reload()
		}
	}()

	<-term

	log.Infoln("Received SIGTERM, exiting gracefully...")
}

var versionInfoTmpl = `
alertmanager, version {{.version}} (branch: {{.branch}}, revision: {{.revision}})
  build user:       {{.buildUser}}
  build date:       {{.buildDate}}
  go version:       {{.goVersion}}
`

func printVersion() {
	t := tmpltext.Must(tmpltext.New("version").Parse(versionInfoTmpl))

	var buf bytes.Buffer
	if err := t.ExecuteTemplate(&buf, "version", version.Map); err != nil {
		panic(err)
	}
	fmt.Fprintln(os.Stdout, strings.TrimSpace(buf.String()))
}

func extURL(s string) (*url.URL, error) {
	if s == "" {
		hostname, err := os.Hostname()
		if err != nil {
			return nil, err
		}
		_, port, err := net.SplitHostPort(*listenAddress)
		if err != nil {
			return nil, err
		}

		s = fmt.Sprintf("http://%s:%s/", hostname, port)
	}

	u, err := url.Parse(s)
	if err != nil {
		return nil, err
	}

	ppref := strings.TrimRight(u.Path, "/")
	if ppref != "" && !strings.HasPrefix(ppref, "/") {
		ppref = "/" + ppref
	}
	u.Path = ppref

	return u, nil
}

func listen(router *route.Router) {
	if err := http.ListenAndServe(*listenAddress, router); err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Provide feedback in console about port<commit_after>// Copyright 2015 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"bytes"
	"database/sql"
	"flag"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"os"
	"os/signal"
	"path/filepath"
	"strings"
	"syscall"
	tmpltext "text/template"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
	"github.com/prometheus/common/route"

	"github.com/prometheus/alertmanager/config"
	"github.com/prometheus/alertmanager/notify"
	"github.com/prometheus/alertmanager/provider/sqlite"
	"github.com/prometheus/alertmanager/template"
	"github.com/prometheus/alertmanager/types"
	"github.com/prometheus/alertmanager/version"
)

var (
	showVersion = flag.Bool("version", false, "Print version information.")

	configFile = flag.String("config.file", "alertmanager.yml", "Alertmanager configuration file name.")
	dataDir    = flag.String("storage.path", "data/", "Base path for data storage.")

	externalURL   = flag.String("web.external-url", "", "The URL under which Alertmanager is externally reachable (for example, if Alertmanager is served via a reverse proxy). Used for generating relative and absolute links back to Alertmanager itself. If the URL has a path portion, it will be used to prefix all HTTP endpoints served by Alertmanager. If omitted, relevant URL components will be derived automatically.")
	listenAddress = flag.String("web.listen-address", ":9093", "Address to listen on for the web interface and API.")
)

var (
	configSuccess = prometheus.NewGauge(prometheus.GaugeOpts{
		Namespace: "alertmanager",
		Name:      "config_last_reload_successful",
		Help:      "Whether the last configuration reload attempt was successful.",
	})
	configSuccessTime = prometheus.NewGauge(prometheus.GaugeOpts{
		Namespace: "alertmanager",
		Name:      "config_last_reload_success_timestamp_seconds",
		Help:      "Timestamp of the last successful configuration reload.",
	})
)

func init() {
	prometheus.MustRegister(configSuccess)
	prometheus.MustRegister(configSuccessTime)
}

func main() {
	flag.Parse()

	printVersion()
	if *showVersion {
		os.Exit(0)
	}

	err := os.MkdirAll(*dataDir, 0777)
	if err != nil {
		log.Fatal(err)
	}
	db, err := sql.Open("sqlite3", filepath.Join(*dataDir, "am.db"))
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	marker := types.NewMarker()

	alerts, err := sqlite.NewAlerts(db)
	if err != nil {
		log.Fatal(err)
	}
	notifies, err := sqlite.NewNotifies(db)
	if err != nil {
		log.Fatal(err)
	}
	silences, err := sqlite.NewSilences(db, marker)
	if err != nil {
		log.Fatal(err)
	}

	var (
		inhibitor *Inhibitor
		tmpl      *template.Template
		disp      *Dispatcher
	)
	defer disp.Stop()

	api := NewAPI(alerts, silences, func() AlertOverview {
		return disp.Groups()
	})

	build := func(rcvs []*config.Receiver) notify.Notifier {
		var (
			router  = notify.Router{}
			fanouts = notify.Build(rcvs, tmpl)
		)
		for name, fo := range fanouts {
			for i, n := range fo {
				n = notify.Retry(n)
				n = notify.Log(n, log.With("step", "retry"))
				n = notify.Dedup(notifies, n)
				n = notify.Log(n, log.With("step", "dedup"))

				fo[i] = n
			}
			router[name] = fo
		}
		n := notify.Notifier(router)

		n = notify.Log(n, log.With("step", "route"))
		n = notify.Silence(silences, n, marker)
		n = notify.Log(n, log.With("step", "silence"))
		n = notify.Inhibit(inhibitor, n, marker)
		n = notify.Log(n, log.With("step", "inhibit"))

		return n
	}

	reload := func() (err error) {
		log.With("file", *configFile).Infof("Loading configuration file")
		defer func() {
			if err != nil {
				log.With("file", *configFile).Errorf("Loading configuration file failed: %s", err)
				configSuccess.Set(0)
			} else {
				configSuccess.Set(1)
				configSuccessTime.Set(float64(time.Now().Unix()))
			}
		}()

		conf, err := config.LoadFile(*configFile)
		if err != nil {
			return err
		}

		api.Update(conf.String(), time.Duration(conf.Global.ResolveTimeout))

		tmpl, err = template.FromGlobs(conf.Templates...)
		if err != nil {
			return err
		}
		if tmpl.ExternalURL, err = extURL(*externalURL); err != nil {
			return err
		}

		disp.Stop()

		inhibitor = NewInhibitor(alerts, conf.InhibitRules, marker)
		disp = NewDispatcher(alerts, NewRoute(conf.Route, nil), build(conf.Receivers), marker)

		go disp.Run()

		return nil
	}

	if err := reload(); err != nil {
		os.Exit(1)
	}

	router := route.New()

	RegisterWeb(router)
	api.Register(router.WithPrefix("/api"))

	log.Infof("Listening on %s", *listenAddress)
	go listen(router)

	var (
		hup  = make(chan os.Signal)
		term = make(chan os.Signal)
	)
	signal.Notify(hup, syscall.SIGHUP)
	signal.Notify(term, os.Interrupt, syscall.SIGTERM)

	go func() {
		for range hup {
			reload()
		}
	}()

	<-term

	log.Infoln("Received SIGTERM, exiting gracefully...")
}

var versionInfoTmpl = `
alertmanager, version {{.version}} (branch: {{.branch}}, revision: {{.revision}})
  build user:       {{.buildUser}}
  build date:       {{.buildDate}}
  go version:       {{.goVersion}}
`

func printVersion() {
	t := tmpltext.Must(tmpltext.New("version").Parse(versionInfoTmpl))

	var buf bytes.Buffer
	if err := t.ExecuteTemplate(&buf, "version", version.Map); err != nil {
		panic(err)
	}
	fmt.Fprintln(os.Stdout, strings.TrimSpace(buf.String()))
}

func extURL(s string) (*url.URL, error) {
	if s == "" {
		hostname, err := os.Hostname()
		if err != nil {
			return nil, err
		}
		_, port, err := net.SplitHostPort(*listenAddress)
		if err != nil {
			return nil, err
		}

		s = fmt.Sprintf("http://%s:%s/", hostname, port)
	}

	u, err := url.Parse(s)
	if err != nil {
		return nil, err
	}

	ppref := strings.TrimRight(u.Path, "/")
	if ppref != "" && !strings.HasPrefix(ppref, "/") {
		ppref = "/" + ppref
	}
	u.Path = ppref

	return u, nil
}

func listen(router *route.Router) {
	if err := http.ListenAndServe(*listenAddress, router); err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/hackebrot/amelia/amelia"
)

func loadFromEnv(keys ...string) (map[string]string, error) {
	env := make(map[string]string)

	for _, key := range keys {
		v := os.Getenv(key)
		if v == "" {
			return nil, fmt.Errorf("environment variable %q is required", key)
		}
		env[key] = v
	}

	return env, nil
}

func main() {
	description := flag.String(
		"description",
		"Amelia Gist",
		"A description of the gist.",
	)

	public := flag.Bool(
		"public",
		false,
		"Indicates whether the gist is public. (default false)",
	)

	flag.Parse()

	files := flag.Args()

	if len(files) == 0 {
		fmt.Fprintf(os.Stderr, "ERROR: %v\n", "no files given")
		os.Exit(1)
	}

	env, err := loadFromEnv("AMELIA_USERNAME", "AMELIA_TOKEN")
	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
		os.Exit(1)
	}

	n, err := amelia.NewGist(description, public, files)
	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
		os.Exit(1)
	}

	client := &amelia.GitHubClient{
		Username: env["AMELIA_USERNAME"],
		Token:    env["AMELIA_TOKEN"],
	}

	g, err := client.CreateGist(n)
	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("gist created at %s\n", *g.HTMLURL)
}
<commit_msg>Add support for shorthand CLI flags<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/hackebrot/amelia/amelia"
)

var description string
var public bool

func init() {
	const (
		dDefault = "Amelia Gist"
		dUsage   = "description of the gist"
	)
	flag.StringVar(&description, "description", dDefault, dUsage)
	flag.StringVar(&description, "d", dDefault, dUsage)

	const (
		pDefault = false
		pUsage   = "indicates whether the gist is public"
	)
	flag.BoolVar(&public, "public", pDefault, pUsage)
	flag.BoolVar(&public, "p", pDefault, pUsage)
}

func loadFromEnv(keys ...string) (map[string]string, error) {
	env := make(map[string]string)

	for _, key := range keys {
		v := os.Getenv(key)
		if v == "" {
			return nil, fmt.Errorf("environment variable %q is required", key)
		}
		env[key] = v
	}

	return env, nil
}

func main() {
	flag.Parse()

	files := flag.Args()

	if len(files) == 0 {
		fmt.Fprintf(os.Stderr, "ERROR: %v\n", "no files given")
		os.Exit(1)
	}

	env, err := loadFromEnv("AMELIA_USERNAME", "AMELIA_TOKEN")
	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
		os.Exit(1)
	}

	n, err := amelia.NewGist(&description, &public, files)
	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
		os.Exit(1)
	}

	client := &amelia.GitHubClient{
		Username: env["AMELIA_USERNAME"],
		Token:    env["AMELIA_TOKEN"],
	}

	g, err := client.CreateGist(n)
	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("gist created at %s\n", *g.HTMLURL)
}
<|endoftext|>


<commit_before>package main

import (
  "flag"
  "fmt"
  "os"
  "os/exec"
  "strings"
  "strconv"
  "syscall"
  "time"
)

const VERSION="v0.0.1"

func main() {
  var i string
  flag.StringVar(&i, "i", "1s", "Interval to wait between executions in seconds")
  flag.StringVar(&i, "interval", "1s", "Interval to wait between executions in seconds")

  var interrupt bool
  flag.BoolVar(&interrupt, "x", false, "Exit and elevate status code if the command fails")
  flag.BoolVar(&interrupt, "exit", false, "Exit and elevate status code if the command fails")

  var version bool
  flag.BoolVar(&version, "v", false, "Print out version")
  flag.BoolVar(&version, "version", false, "Print out version")

  var usage bool
  flag.BoolVar(&usage, "h", false, "Print out version")
  flag.BoolVar(&usage, "help", false, "Print out version")

  flag.Parse()

  if version {
    die(0, VERSION)
  }

  command := flag.Args()

  if usage || len(command) == 0 {
    help()
    die(0, "")
  }

  interval := parseInterval(i)

  loop(intervalToTime(interval), func () {
    reset()
    status := run(command)
    if(interrupt && status != 0) {
      die(status, "")
    }
  })
}

func intervalSuffixes() []string {
  return []string{ "ms", "s", "MS", "S" }
}

func unitToFactor(s string) float64 {
  if s == "ms" || s == "MS" { return 1.0 }
  if s == "S" || s == "S" { return 1000.0 }
  return 1000.0
}

func suffixToInterval (s string, i string) (float64, bool) {
  is_unit := strings.HasSuffix(i, s)
  if is_unit {
    n, err := strconv.ParseFloat(i[:len(i)-len(s)], 64)
    dieIf(err, -1, "Invalid interval")
    return n*unitToFactor(s), true
  }
  return 0, false
}

func parseInterval(i string) float64 {
  suffixes := intervalSuffixes()
  for j := 0; j < len(suffixes); j++ {
    if val, is := suffixToInterval(suffixes[j], i); is  {
      return val
    }
  }
  return 0
}

func help() {
  br := func () { fmt.Println("") }
  _p  := func (p string, t string) { fmt.Println(p, t) }
  p := func(t string) { _p("  ", t) }
  pp := func(t string) { _p("    ", t) }

  br()
  p("Usage: watch [options] <cmd>")
  br()
  p("Sample: watch -i=100ms make")
  br()
  p("Options:")
  br()
  pp("-i, --interval\t\tinterval in seconds or ms, defaulting to 1s")
  pp("-x, --exit\t\t\texit on failure")
  pp("-v, --version\t\tprint out version")
  pp("-h, --help\t\t\tthis help page")
  br()
}

func dieIf(err error, status int, message string) {
  if err != nil {
    die(status, message)
  }
}

func die(status int, message string) {
  if len(message) > 0 {
    fmt.Println(message)
  }
  os.Exit(status)
}

func intervalToTime(i float64) time.Duration {
  return time.Duration(i) * time.Millisecond
}

func reset() {
  run([]string {"clear"})
}

func makeCmd(bin string, args []string) *exec.Cmd {
  cmd := exec.Command(bin, args...)
  cmd.Env = os.Environ()
  cmd.Stdout = os.Stdout
  cmd.Stderr = os.Stderr
  return cmd
}

func getExitStatus(cmd *exec.Cmd) int {
  status, _ := cmd.ProcessState.Sys().(syscall.WaitStatus)
  return status.ExitStatus()
}

func commandExists(command []string) bool {
  _, result := exec.LookPath(command[0])
  return result == nil
}

func run(command []string) int {
  path, _ := exec.LookPath(command[0])
  cmd := makeCmd(path, command[1:])
  cmd.Run()
  return getExitStatus(cmd)
}

func loop(d time.Duration, fn func()) {
  fn()
  for range time.Tick(d) {
    fn()
  }
}
<commit_msg>Short-circuit if command isn't found<commit_after>package main

import (
  "flag"
  "fmt"
  "os"
  "os/exec"
  "strings"
  "strconv"
  "syscall"
  "time"
)

const VERSION="v0.0.1"

func main() {
  var i string
  flag.StringVar(&i, "i", "1s", "Interval to wait between executions in seconds")
  flag.StringVar(&i, "interval", "1s", "Interval to wait between executions in seconds")

  var interrupt bool
  flag.BoolVar(&interrupt, "x", false, "Exit and elevate status code if the command fails")
  flag.BoolVar(&interrupt, "exit", false, "Exit and elevate status code if the command fails")

  var version bool
  flag.BoolVar(&version, "v", false, "Print out version")
  flag.BoolVar(&version, "version", false, "Print out version")

  var usage bool
  flag.BoolVar(&usage, "h", false, "Print out version")
  flag.BoolVar(&usage, "help", false, "Print out version")

  flag.Parse()

  if version {
    die(0, VERSION)
  }

  command := flag.Args()

  if usage || len(command) == 0 {
    help()
    die(0, "")
  }

  if ! commandExists(command) {
    die(0, "Executable not found in PATH")
  }

  interval := parseInterval(i)

  loop(intervalToTime(interval), func () {
    reset()
    status := run(command)
    if(interrupt && status != 0) {
      die(status, "")
    }
  })
}

func intervalSuffixes() []string {
  return []string{ "ms", "s", "MS", "S" }
}

func unitToFactor(s string) float64 {
  if s == "ms" || s == "MS" { return 1.0 }
  if s == "S" || s == "S" { return 1000.0 }
  return 1000.0
}

func suffixToInterval (s string, i string) (float64, bool) {
  is_unit := strings.HasSuffix(i, s)
  if is_unit {
    n, err := strconv.ParseFloat(i[:len(i)-len(s)], 64)
    dieIf(err, -1, "Invalid interval")
    return n*unitToFactor(s), true
  }
  return 0, false
}

func parseInterval(i string) float64 {
  suffixes := intervalSuffixes()
  for j := 0; j < len(suffixes); j++ {
    if val, is := suffixToInterval(suffixes[j], i); is  {
      return val
    }
  }
  return 0
}

func help() {
  br := func () { fmt.Println("") }
  _p  := func (p string, t string) { fmt.Println(p, t) }
  p := func(t string) { _p("  ", t) }
  pp := func(t string) { _p("    ", t) }

  br()
  p("Usage: watch [options] <cmd>")
  br()
  p("Sample: watch -i=100ms make")
  br()
  p("Options:")
  br()
  pp("-i, --interval\t\tinterval in seconds or ms, defaulting to 1s")
  pp("-x, --exit\t\t\texit on failure")
  pp("-v, --version\t\tprint out version")
  pp("-h, --help\t\t\tthis help page")
  br()
}

func dieIf(err error, status int, message string) {
  if err != nil {
    die(status, message)
  }
}

func die(status int, message string) {
  if len(message) > 0 {
    fmt.Println(message)
  }
  os.Exit(status)
}

func intervalToTime(i float64) time.Duration {
  return time.Duration(i) * time.Millisecond
}

func reset() {
  run([]string {"clear"})
}

func makeCmd(bin string, args []string) *exec.Cmd {
  cmd := exec.Command(bin, args...)
  cmd.Env = os.Environ()
  cmd.Stdout = os.Stdout
  cmd.Stderr = os.Stderr
  return cmd
}

func getExitStatus(cmd *exec.Cmd) int {
  status, _ := cmd.ProcessState.Sys().(syscall.WaitStatus)
  return status.ExitStatus()
}

func commandExists(command []string) bool {
  _, result := exec.LookPath(command[0])
  return result == nil
}

func run(command []string) int {
  path, _ := exec.LookPath(command[0])
  cmd := makeCmd(path, command[1:])
  cmd.Run()
  return getExitStatus(cmd)
}

func loop(d time.Duration, fn func()) {
  fn()
  for range time.Tick(d) {
    fn()
  }
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"

	"github.com/abiosoft/dockward/tcpforward"
)

var dockerBin string
var dockerMode bool

const NAME = "dockward"

func init() {
	if len(os.Args) > 1 && os.Args[1] == "docker" {
		dockerMode = true
		return
	}
	d, err := exec.LookPath("docker")
	if err != nil {
		exitWithErr(errors.New("Docker binary not found in PATH"))
	}
	dockerBin = d
	if err := run(args("version").Mute()); err != nil {
		exitWithErr(err)
	}
}

func main() {
	testContainer()
}

func testContainer() {
	if dockerMode {
		forwardToContainer()
		return
	}

	if len(os.Args) < 3 {
		exitWithErr(errors.New("Port and container id/name missing."))
	}

	port := os.Args[1]
	dest := os.Args[2]
	destPort := port
	if len(os.Args) > 3 {
		destPort = os.Args[3]
	}

	ip, err := ipFromContainer(dest)
	if ip == "" {
		if err = connectContainer(dest); err == nil {
			ip, err = ipFromContainer(dest)
		}
	}
	if err != nil {
		exitWithErr(err)
	} else if ip == "" {
		exitWithErr(errors.New("Error communicating with container"))
	}
	dest = ip + ":" + destPort
	opt := &options{
		args: []string{"run", "-it", "-p", port + ":" + port, "--net", NAME, NAME, "docker", port, dest},
	}

	fmt.Println("Forwarding", port, "to", dest)
	err = run(opt)
	exitWithErr(err)

}

func ipFromContainer(name string) (string, error) {

	buf := bytes.NewBuffer(nil)
	opt := &options{
		args:   []string{"inspect", name},
		stdout: buf,
	}
	err := run(opt)
	if err != nil {
		return "", err
	}
	var container []struct {
		NetworkSettings struct {
			Networks struct {
				Dockward struct {
					IPAddress string
				} `json:"dockward"`
			}
		}
	}

	err = json.NewDecoder(buf).Decode(&container)
	if err != nil {
		return "", err
	}
	return container[0].NetworkSettings.Networks.Dockward.IPAddress, nil
}

func connectContainer(name string) error {
	//network ls -q -f name=dockward
	b := bytes.NewBuffer(nil)
	opts := &options{
		stdout: b,
		args:   []string{"network", "ls", "-q", "-f", "name=" + NAME},
	}
	if err := run(opts); err != nil {
		return err
	} else if b.Len() == 0 {
		if err := run(args("network", "create", NAME).Mute()); err != nil {
			return err
		}
	}
	return run(args("network", "connect", NAME, name))
}

func forwardToContainer() {
	if len(os.Args) < 4 {
		exitWithErr(errors.New("Port and remote address missing."))
	}
	port := os.Args[2]
	dest := os.Args[3]
	err := tcpforward.Forward(port, dest)
	exitWithErr(err)
}

func exitWithErr(err error) {
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func run(options *options) error {
	cmd := exec.Command(dockerBin, options.args...)
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	cmd.Stdin = os.Stdin
	if options.stdin != nil {
		cmd.Stdin = options.stdin
	}
	if options.stdout != nil {
		cmd.Stdout = options.stdout
	}
	if options.stderr != nil {
		cmd.Stderr = options.stderr
	}
	return cmd.Run()
}

type options struct {
	args   []string
	stdin  io.Reader
	stdout io.Writer
	stderr io.Writer
}

func (o *options) Mute() *options {
	o.stdout = ioutil.Discard
	return o
}

func args(a ...string) *options {
	return &options{args: a}
}
<commit_msg>Monitor prototype<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"

	"github.com/abiosoft/dockward/tcpforward"
	docker "github.com/docker/engine-api/client"
	"github.com/docker/engine-api/types"
	"golang.org/x/net/context"
)

var dockerBin string
var dockerMode bool
var monitorMode bool

const NAME = "dockward"

func init() {
	if len(os.Args) > 1 && os.Args[1] == "docker" {
		dockerMode = true
		return
	} else if len(os.Args) > 1 && os.Args[1] == "monitor" {
		monitorMode = true
	}
	d, err := exec.LookPath("docker")
	if err != nil {
		exitWithErr(errors.New("Docker binary not found in PATH"))
	}
	dockerBin = d
	if err := run(args("version").Mute()); err != nil {
		exitWithErr(err)
	}
}

func main() {
	testContainer()
}

const (
	Die       = "die"
	Start     = "start"
	Container = "container"
)

type Event struct {
	Status string `json:"status"`
	Type   string
	Id     string `json:"id"`
	Actor  struct {
		Attributes map[string]string
	}
}

func monitor() {
	client, err := docker.NewEnvClient()
	exitWithErr(err)
	resp, err := client.Events(context.Background(), types.EventsOptions{})
	exitWithErr(err)
	decoder := json.NewDecoder(resp)
	var e Event
	for {
		err := decoder.Decode(&e)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			continue
		}
		fmt.Println(e)
	}
}

func testContainer() {
	if dockerMode {
		forwardToContainer()
		return
	} else if monitorMode {
		monitor()
		return
	}

	if len(os.Args) < 3 {
		exitWithErr(errors.New("Port and container id/name missing."))
	}

	port := os.Args[1]
	dest := os.Args[2]
	destPort := port
	if len(os.Args) > 3 {
		destPort = os.Args[3]
	}

	ip, err := ipFromContainer(dest)
	if ip == "" {
		if err = connectContainer(dest); err == nil {
			ip, err = ipFromContainer(dest)
		}
	}
	if err != nil {
		exitWithErr(err)
	} else if ip == "" {
		exitWithErr(errors.New("Error communicating with container"))
	}
	dest = ip + ":" + destPort
	opt := &options{
		args: []string{"run", "-it", "-p", port + ":" + port, "--net", NAME, NAME, "docker", port, dest},
	}

	fmt.Println("Forwarding", port, "to", dest)
	err = run(opt)
	exitWithErr(err)

}

func ipFromContainer(name string) (string, error) {
	buf := bytes.NewBuffer(nil)
	opt := &options{
		args:   []string{"inspect", name},
		stdout: buf,
	}
	err := run(opt)
	if err != nil {
		return "", err
	}
	var container []struct {
		NetworkSettings struct {
			Networks struct {
				Dockward struct {
					IPAddress string
				} `json:"dockward"`
			}
		}
	}

	err = json.NewDecoder(buf).Decode(&container)
	if err != nil {
		return "", err
	}
	return container[0].NetworkSettings.Networks.Dockward.IPAddress, nil
}

func connectContainer(name string) error {
	b := bytes.NewBuffer(nil)
	opts := &options{
		stdout: b,
		args:   []string{"network", "ls", "-q", "-f", "name=" + NAME},
	}
	if err := run(opts); err != nil {
		return err
	} else if b.Len() == 0 {
		if err := run(args("network", "create", NAME).Mute()); err != nil {
			return err
		}
	}
	return run(args("network", "connect", NAME, name))
}

func forwardToContainer() {
	if len(os.Args) < 4 {
		exitWithErr(errors.New("Port and remote address missing."))
	}
	port := os.Args[2]
	dest := os.Args[3]
	err := tcpforward.Forward(port, dest)
	exitWithErr(err)
}

func exitWithErr(err error) {
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func run(options *options) error {
	cmd := exec.Command(dockerBin, options.args...)
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	cmd.Stdin = os.Stdin
	if options.stdin != nil {
		cmd.Stdin = options.stdin
	}
	if options.stdout != nil {
		cmd.Stdout = options.stdout
	}
	if options.stderr != nil {
		cmd.Stderr = options.stderr
	}
	return cmd.Run()
}

type options struct {
	args   []string
	stdin  io.Reader
	stdout io.Writer
	stderr io.Writer
}

func (o *options) Mute() *options {
	o.stdout = ioutil.Discard
	return o
}

func args(a ...string) *options {
	return &options{args: a}
}
<|endoftext|>


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

/*
The wgo tool is a small wrapper around the go tool. It adds the concept
of a workspace, in addition to that of GOPATH, and several new commands
to manage that workspace.
*/
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
)

const (
	ConfigDirName = ".gocfg"
)

var Debug bool

const getFlag = "--vendor-gopath"

var usageMessage = fmt.Sprintf(`wgo is a tool for managing Go workspaces.

usage: wgo init [%s=VENDOR_GOPATH] [ADDITIONAL_GOPATH+]
       wgo restore
       wgo save [--godeps] [PACKAGE+]
       wgo vendor [PACKAGE+]

       wgo <go command>  # run a go command with the workspace's gopaths
`, getFlag)

func usage() {
	fmt.Print(usageMessage)
	os.Exit(1)
}

func init() {
	log.SetFlags(0)
	Debug = os.Getenv("WGO_DEBUG") == "1"
	if !Debug {
		log.SetOutput(ioutil.Discard)
	}
	log.Println("debug mode on")
}

func orExit(err error) {
	if err == nil {
		return
	}
	fmt.Fprintf(os.Stderr, "%s\n", err)
	os.Exit(1)
}

func main() {
	if len(os.Args) == 1 {
		fmt.Println(usageMessage)
		shellOutToGo(os.Args)
	}
	var err error
	switch os.Args[1] {
	case "init":
		if err = initWgo(os.Args[2:]); err != nil {
			fmt.Fprintf(os.Stderr, "%s\n", err)
		}
	case "vendor":
		w, err := getCurrentWorkspace()
		orExit(err)
		vendor(w, os.Args[2:])
	case "restore":
		if len(os.Args) != 2 {
			usage()
		}
		w, err := getCurrentWorkspace()
		orExit(err)
		restore(w)
	case "save":
		w, err := getCurrentWorkspace()
		orExit(err)
		save(w, os.Args[2:])
	default:
		w, err := getCurrentWorkspace()
		orExit(err)
		w.shellOutToGo(os.Args)
	}
}

func initWgo(args []string) error {
	for _, arg := range args {
		if arg != getFlag && strings.HasPrefix(arg, "-") {
			fmt.Fprintf(os.Stderr, "unrecognized flag: %s\n\n", arg)
			usage()
		}
	}

	wd, err := os.Getwd()
	if err != nil {
		return err
	}

	w, err := getCurrentWorkspace()
	if err == nil && (w.Root == wd && len(args) == 0) {
		return fmt.Errorf("%q is already a workspace", w.Root)
	}

	fi, err := os.Stat(wd)
	if err != nil {
		return err
	}

	if err := os.MkdirAll(filepath.Join(wd, ConfigDirName), fi.Mode()); err != nil {
		return err
	}
	if err := os.MkdirAll(filepath.Join(wd, "src"), fi.Mode()); err != nil {
		return err
	}

	if w, err = getCurrentWorkspace(); err != nil {
		return err
	}

	if len(args) == 0 {
		args = []string{getFlag, "vendor"}
	}

	gopathsPath := filepath.Join(wd, ConfigDirName, "gopaths")
	// if there is no gopaths yet, stick '.' in there.
	if _, err := os.Stat(gopathsPath); err != nil {
		args = append([]string{"."}, args...)
	}

	var fout *os.File
	if fout, err = os.Create(gopathsPath); err != nil {
		return err
	}
	defer fout.Close()

	checkGopath := func(gopath string) {
		if filepath.IsAbs(gopath) {
			fmt.Fprintf(os.Stderr, "%q is not a relative path\n", gopath)
		}
	}

	goGetDir := ""

	var gopathArgs []string
	for i := 0; i < len(args); i++ {
		if args[i] == getFlag {
			if i+1 >= len(args) {
				usage()
			}
			goGetDir = args[i+1]
			checkGopath(goGetDir)
			fmt.Fprintln(fout, goGetDir)
			i++
			continue
		}

		if strings.HasPrefix(args[i], getFlag+"=") {
			goGetDir = args[i][len(getFlag+"="):]

			checkGopath(goGetDir)
			fmt.Fprintln(fout, goGetDir)
			continue
		}

		checkGopath(args[i])
		gopathArgs = append(gopathArgs, args[i])
	}

	alreadyListed := map[string]bool{
		goGetDir: true,
	}

	for _, gopath := range w.Gopaths {
		if _, ok := alreadyListed[gopath]; ok {
			continue
		}
		alreadyListed[gopath] = true
		fmt.Fprintln(fout, gopath)
	}
	for _, gopath := range gopathArgs {
		if _, ok := alreadyListed[gopath]; ok {
			continue
		}
		alreadyListed[gopath] = true
		fmt.Fprintln(fout, gopath)
	}

	return nil
}

func clone(args []string) error {
	return nil
}
<commit_msg>When not in a workspace, shelling out to go can happen without setting GOPATH<commit_after>/*
Copyright 2015 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/*
The wgo tool is a small wrapper around the go tool. It adds the concept
of a workspace, in addition to that of GOPATH, and several new commands
to manage that workspace.
*/
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
)

const (
	ConfigDirName = ".gocfg"
)

var Debug bool

const getFlag = "--vendor-gopath"

var usageMessage = fmt.Sprintf(`wgo is a tool for managing Go workspaces.

usage: wgo init [%s=VENDOR_GOPATH] [ADDITIONAL_GOPATH+]
       wgo restore
       wgo save [--godeps] [PACKAGE+]
       wgo vendor [PACKAGE+]

       wgo <go command>  # run a go command with the workspace's gopaths
`, getFlag)

func usage() {
	fmt.Print(usageMessage)
	os.Exit(1)
}

func init() {
	log.SetFlags(0)
	Debug = os.Getenv("WGO_DEBUG") == "1"
	if !Debug {
		log.SetOutput(ioutil.Discard)
	}
	log.Println("debug mode on")
}

func orExit(err error) {
	if err == nil {
		return
	}
	fmt.Fprintf(os.Stderr, "%s\n", err)
	os.Exit(1)
}

func main() {
	if len(os.Args) == 1 {
		fmt.Println(usageMessage)
		shellOutToGo(os.Args)
	}
	var err error
	switch os.Args[1] {
	case "init":
		if err = initWgo(os.Args[2:]); err != nil {
			fmt.Fprintf(os.Stderr, "%s\n", err)
		}
	case "vendor":
		w, err := getCurrentWorkspace()
		orExit(err)
		vendor(w, os.Args[2:])
	case "restore":
		if len(os.Args) != 2 {
			usage()
		}
		w, err := getCurrentWorkspace()
		orExit(err)
		restore(w)
	case "save":
		w, err := getCurrentWorkspace()
		orExit(err)
		save(w, os.Args[2:])
	default:
		w, err := getCurrentWorkspace()
		if err == nil {
			w.shellOutToGo(os.Args)
		} else {
			shellOutToGo(os.Args)
		}
	}
}

func initWgo(args []string) error {
	for _, arg := range args {
		if arg != getFlag && strings.HasPrefix(arg, "-") {
			fmt.Fprintf(os.Stderr, "unrecognized flag: %s\n\n", arg)
			usage()
		}
	}

	wd, err := os.Getwd()
	if err != nil {
		return err
	}

	w, err := getCurrentWorkspace()
	if err == nil && (w.Root == wd && len(args) == 0) {
		return fmt.Errorf("%q is already a workspace", w.Root)
	}

	fi, err := os.Stat(wd)
	if err != nil {
		return err
	}

	if err := os.MkdirAll(filepath.Join(wd, ConfigDirName), fi.Mode()); err != nil {
		return err
	}
	if err := os.MkdirAll(filepath.Join(wd, "src"), fi.Mode()); err != nil {
		return err
	}

	if w, err = getCurrentWorkspace(); err != nil {
		return err
	}

	if len(args) == 0 {
		args = []string{getFlag, "vendor"}
	}

	gopathsPath := filepath.Join(wd, ConfigDirName, "gopaths")
	// if there is no gopaths yet, stick '.' in there.
	if _, err := os.Stat(gopathsPath); err != nil {
		args = append([]string{"."}, args...)
	}

	var fout *os.File
	if fout, err = os.Create(gopathsPath); err != nil {
		return err
	}
	defer fout.Close()

	checkGopath := func(gopath string) {
		if filepath.IsAbs(gopath) {
			fmt.Fprintf(os.Stderr, "%q is not a relative path\n", gopath)
		}
	}

	goGetDir := ""

	var gopathArgs []string
	for i := 0; i < len(args); i++ {
		if args[i] == getFlag {
			if i+1 >= len(args) {
				usage()
			}
			goGetDir = args[i+1]
			checkGopath(goGetDir)
			fmt.Fprintln(fout, goGetDir)
			i++
			continue
		}

		if strings.HasPrefix(args[i], getFlag+"=") {
			goGetDir = args[i][len(getFlag+"="):]

			checkGopath(goGetDir)
			fmt.Fprintln(fout, goGetDir)
			continue
		}

		checkGopath(args[i])
		gopathArgs = append(gopathArgs, args[i])
	}

	alreadyListed := map[string]bool{
		goGetDir: true,
	}

	for _, gopath := range w.Gopaths {
		if _, ok := alreadyListed[gopath]; ok {
			continue
		}
		alreadyListed[gopath] = true
		fmt.Fprintln(fout, gopath)
	}
	for _, gopath := range gopathArgs {
		if _, ok := alreadyListed[gopath]; ok {
			continue
		}
		alreadyListed[gopath] = true
		fmt.Fprintln(fout, gopath)
	}

	return nil
}

func clone(args []string) error {
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"time"
)

func main() {
	var (
		depth = flag.Int("depth", 4, "the search depth")
		fen   = flag.String("fen", InitialPositionFEN, "the FEN record of the starting position")
	)
	flag.Parse()
	if *depth < 1 {
		panic("invalid search depth")
	}

	pos, err := ParseFEN(*fen)
	if err != nil {
		panic(err)
	}

	players := []Player{Computer{*depth}, Computer{*depth}}

	startTime := time.Now()
	var movesText string
	posZobrists := make(map[Zobrist]int)

	for !IsTerminal(pos) {
		moveTime := time.Now()

		score, move := players[pos.ToMove].Play(pos)

		alg := Algebraic(pos, move)
		movenum := fmt.Sprintf("%v.", pos.FullMove)
		switch pos.ToMove {
		case White:
			movesText += movenum
		case Black:
			movenum += ".."
		}
		movesText += alg + " "

		pos = Make(pos, move)

		fmt.Printf("%v%v %.2f %v\n", movenum, alg, float64(score)/100, time.Since(moveTime).Truncate(time.Millisecond))
		fmt.Println(pos.String())

		// Check for threefold repetition
		posZobrists[pos.z]++
		if posZobrists[pos.z] == 3 {
			movesText += "1/2-1/2"
			break
		}
	}

	fmt.Println(movesText, time.Since(startTime).Truncate(time.Millisecond))
}

type Player interface {
	Play(Position) (int, Move)
}

type Computer struct{ depth int }

func (c Computer) Play(pos Position) (int, Move) {
	_, results := SearchPosition(pos, c.depth)
	return results[0].score, results[0].move
}
<commit_msg>create Human<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"time"
)

func main() {
	var (
		depth = flag.Int("depth", 4, "the search depth")
		fen   = flag.String("fen", InitialPositionFEN, "the FEN record of the starting position")
	)
	flag.Parse()
	if *depth < 1 {
		panic("invalid search depth")
	}

	pos, err := ParseFEN(*fen)
	if err != nil {
		panic(err)
	}

	stdin := bufio.NewScanner(os.Stdin)
	players := []Player{Human{stdin}, Computer{*depth}}

	startTime := time.Now()
	var movesText string
	posZobrists := make(map[Zobrist]int)

	for !IsTerminal(pos) {
		moveTime := time.Now()

		score, move := players[pos.ToMove].Play(pos)

		alg := Algebraic(pos, move)
		movenum := fmt.Sprintf("%v.", pos.FullMove)
		switch pos.ToMove {
		case White:
			movesText += movenum
		case Black:
			movenum += ".."
		}
		movesText += alg + " "

		pos = Make(pos, move)

		fmt.Printf("%v%v %.2f %v\n", movenum, alg, float64(score)/100, time.Since(moveTime).Truncate(time.Millisecond))
		fmt.Println(pos.String())

		// Check for threefold repetition
		posZobrists[pos.z]++
		if posZobrists[pos.z] == 3 {
			movesText += "1/2-1/2"
			break
		}
	}

	fmt.Println(movesText, time.Since(startTime).Truncate(time.Millisecond))
}

type Player interface {
	Play(Position) (int, Move)
}

type Computer struct{ depth int }

func (c Computer) Play(pos Position) (int, Move) {
	_, results := SearchPosition(pos, c.depth)
	return results[0].score, results[0].move
}

type Human struct{ s *bufio.Scanner }

func (h Human) Play(pos Position) (int, Move) {
	fmt.Printf("> ")
	if ok := h.s.Scan(); !ok {
		panic(h.s.Err())
	}
	from, to, err := ParseUserMove(h.s.Text())
	if err != nil {
		panic(err)
	}
	c, p := pos.PieceOn(from)
	if p == None {
		panic(fmt.Sprintf("No piece on square %v", from))
	}
	if c != pos.ToMove {
		panic(fmt.Sprintf("%v piece on square %v", c, from))
	}
	cc, cp := pos.PieceOn(to)
	if cp != None && cc == c {
		panic(fmt.Sprintf("%v piece on square %v", cc, to))
	}
	var cs Square
	if cp != None {
		cs = to
	} // TODO: en passant, promotion
	m := Move{From: from, To: to, Piece: p, CapturePiece: cp, CaptureSquare: cs}
	if !IsPseudoLegal(pos, m) || !IsLegal(Make(pos, m)) {
		panic(fmt.Sprintf("%v is illegal", m))
	}
	return 0, m
}
<|endoftext|>


<commit_before>package main

import term "github.com/nsf/termbox-go"

func main() {
	err := term.Init()
	if err != nil {
		panic(err)
	}
	defer term.Close()

	event_loop()
}

func event_loop() {
	for exit := false; !exit; {
		event := term.PollEvent()
		switch event.Type {
		case term.EventKey:
			if event.Key == term.KeyEsc {
				exit = true
			}
		case term.EventResize:
		case term.EventMouse:
		case term.EventError:
		case term.EventInterrupt:
		case term.EventRaw:
		case term.EventNone:
		}
	}
}
<commit_msg>simple user input and rendering<commit_after>package main

import term "github.com/nsf/termbox-go"

func main() {
	err := term.Init()
	if err != nil {
		panic(err)
	}
	defer term.Close()

	var st state
	for st.input() {
		st.render()
	}
}

type state struct {
	path   [][]rune
	buffer []rune
}

func (st *state) input() bool {
	event := term.PollEvent()
	switch event.Type {
	case term.EventKey:
		switch event.Ch {
		case 0:
			switch event.Key {
			case term.KeyEsc:
				return false
			case term.KeyBackspace, term.KeyBackspace2, term.KeyDelete:
				if len(st.buffer) > 0 {
					st.buffer = st.buffer[0 : len(st.buffer)-1]
				} else {
					if len(st.path) > 0 {
						st.buffer = st.path[len(st.path)-1]
						st.path = st.path[0 : len(st.path)-1]
					}
				}
			}
		case '/':
			st.path = append(st.path, st.buffer)
			st.buffer = []rune{}
		default:
			st.buffer = append(st.buffer, event.Ch)
		}
	case term.EventResize:
	case term.EventMouse:
	case term.EventError:
	case term.EventInterrupt:
	case term.EventRaw:
	case term.EventNone:
	}
	return true
}

func (st state) render() {
	term.Clear(term.ColorDefault, term.ColorDefault)
	var i int
	for _, component := range st.path {
		for _, ch := range component {
			term.SetCell(i, 0, ch, term.ColorDefault, term.ColorDefault)
			i++
		}
		term.SetCell(i, 0, '/', term.ColorDefault, term.ColorDefault)
		i++
	}
	for _, ch := range st.buffer {
		term.SetCell(i, 0, ch, term.ColorDefault, term.ColorDefault)
		i++
	}
	term.SetCursor(i, 0)
	term.Flush()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"flag"
	"os"
	"github.com/51idc/port-agent/g"
	"github.com/51idc/port-agent/funcs"
	"github.com/51idc/port-agent/cron"
	"github.com/51idc/port-agent/http"
)

func main() {
	cfg := flag.String("c", "cfg.json", "configuration file")
	version := flag.Bool("v", false, "show version")
	check := flag.Bool("check", false, "check collector")
	flag.Parse()

	if *version {
		fmt.Println(g.VERSION)
		os.Exit(0)
	}

	if *check {
		funcs.CheckCollector()
		os.Exit(0)
	}

	g.ParseConfig(*cfg)
	g.InitRootDir()
	g.InitLocalIps()
	g.InitRpcClients()
	funcs.BuildMappers()
	cron.Collect()
	go http.Start()

	select {}

}

<commit_msg>test pull request<commit_after>package main

import (
	"fmt"
	"flag"
	"os"
	"github.com/51idc/port-agent/g"
	"github.com/51idc/port-agent/funcs"
	"github.com/51idc/port-agent/cron"
	"github.com/51idc/port-agent/http"
)

func main() {
	cfg := flag.String("c", "cfg.json", "configuration file")
	version := flag.Bool("v", false, "show version")
	check := flag.Bool("check", false, "check collector")
	flag.Parse()

	if *version {
		fmt.Println(g.VERSION)
		os.Exit(0)
	}

	if *check {
		funcs.CheckCollector()
		os.Exit(0)
	}

	g.ParseConfig(*cfg)
	g.InitRootDir()
	g.InitLocalIps()
	g.InitRpcClients()
	funcs.BuildMappers()
	cron.Collect()

	go http.Start()

	select {}

}

<|endoftext|>


<commit_before>/*
Bloggy is a fast and simple blogging environment.

Usage:
	bloggy [flags]

Available flags are:

	--reset
		Resets the blog folder and deletes all files.

	--blog="my-blog"
		Sets the source folder for templates and posts.
*/
package main

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
)

// DefaultBlogRepository is the default example blog repository.
const DefaultBlogRepository = "https://github.com/mooxmirror/example-blog"

var (
	// GlobalConfig is the global app configuration.
	GlobalConfig BlogConfig
	// BlogFolder is the source folder.
	BlogFolder string
	// Trace logger
	Trace *log.Logger
	// Info logger
	Info *log.Logger
	// Warning logger
	Warning *log.Logger
	// Error logger
	Error *log.Logger
	// Logging flags
	logFlags = log.Ltime | log.Lshortfile
)

func runCLI() {
	for {
		fmt.Print("> ")
		var command, arg string
		fmt.Scanln(&command, &arg)

		switch command {
		case "reload":
			// Reload all templates and posts
			LoadTemplates()
			LoadPosts()
			Info.Println("Reloaded posts and templates")
		case "stop":
			// Stops the server
			Info.Println("Forcing shutdown")
			os.Exit(1)
		case "debug":
			switch arg {
			case "on":
				logFlags = log.Ldate | log.Ltime | log.Lshortfile
				initLogger(os.Stdout)
				Info.Println("Activated debug mode")
			case "off":
				logFlags = log.Ldate | log.Ltime
				initLogger(ioutil.Discard)
				Info.Println("Deactivated debug mode")
			}
		}
	}
}

func initLogger(traceOutput io.Writer) {
	Trace = log.New(traceOutput, "[Trace] ", log.Ltime|log.Lshortfile)
	Info = log.New(os.Stdout, "[Info] ", log.Ltime|log.Lshortfile)
	Warning = log.New(os.Stdout, "[Warning] ", log.Ltime|log.Lshortfile)
	Error = log.New(os.Stderr, "[Error] ", log.Ltime|log.Lshortfile)
}

// ResetBlog resets the blog, deletes all files and clones the source repo.
func ResetBlog(repository string) error {
	// delete existing folder
	remError := os.RemoveAll(BlogFolder)
	if remError != nil && !os.IsNotExist(remError) {
		return remError
	}

	cloneCmd := exec.Command("git", "clone", repository, BlogFolder)
	// run git
	cloneStartError := cloneCmd.Start()
	// failed to run git
	if cloneStartError != nil {
		return cloneStartError
	}
	// wait for git to finish
	cloneWaitError := cloneCmd.Wait()
	// git runtime error
	if cloneWaitError != nil {
		return cloneWaitError
	}

	return nil
}

func main() {
	initLogger(ioutil.Discard)

	// parse command line arguments
	resetFlag := flag.Bool("reset", false, "Resets the blog data")
	folderFlag := flag.String("blog", "my-blog", "Sets the data source folder")
	repositoryFlag := flag.String("repo", DefaultBlogRepository, "Change the git source repository for resets")
	flag.Parse()

	BlogFolder = *folderFlag
	// check if reset
	if *resetFlag {
		Info.Println("Resetting blog folder:", BlogFolder)
		resetError := ResetBlog(*repositoryFlag)
		if resetError != nil {
			Error.Println("Failed to reset blog:", resetError)
			os.Exit(1)
		}
	}

	// load configuration file from disk
	loadError := LoadConfig()
	if loadError != nil {
		Error.Println("Failed to load configuration:", loadError)
		os.Exit(1)
	}
	LoadTemplates()
	LoadPosts()

	go runCLI()
	router := LoadRoutes()
	serverError := http.ListenAndServe(GlobalConfig.HostAddress, router)

	if serverError != nil {
		Error.Println("Server error:", serverError)
	}
}
<commit_msg>Add doc for new command line options<commit_after>/*
Bloggy is a fast and simple blogging environment.

Usage:
	bloggy [flags]

Available flags are:

	--reset
		Reset the blog folder and deletes all files.

	--blog="my-blog"
		Set the source folder for templates and posts.

	--repo="https://github.com/lnsp/example-blog"
		Change the git source repository for new blogs
*/
package main

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
)

// DefaultBlogRepository is the default example blog repository.
const DefaultBlogRepository = "https://github.com/mooxmirror/example-blog"

var (
	// GlobalConfig is the global app configuration.
	GlobalConfig BlogConfig
	// BlogFolder is the source folder.
	BlogFolder string
	// Trace logger
	Trace *log.Logger
	// Info logger
	Info *log.Logger
	// Warning logger
	Warning *log.Logger
	// Error logger
	Error *log.Logger
	// Logging flags
	logFlags = log.Ltime | log.Lshortfile
)

func runCLI() {
	for {
		fmt.Print("> ")
		var command, arg string
		fmt.Scanln(&command, &arg)

		switch command {
		case "reload":
			// Reload all templates and posts
			LoadTemplates()
			LoadPosts()
			Info.Println("Reloaded posts and templates")
		case "stop":
			// Stops the server
			Info.Println("Forcing shutdown")
			os.Exit(1)
		case "debug":
			switch arg {
			case "on":
				logFlags = log.Ldate | log.Ltime | log.Lshortfile
				initLogger(os.Stdout)
				Info.Println("Activated debug mode")
			case "off":
				logFlags = log.Ldate | log.Ltime
				initLogger(ioutil.Discard)
				Info.Println("Deactivated debug mode")
			}
		}
	}
}

func initLogger(traceOutput io.Writer) {
	Trace = log.New(traceOutput, "[Trace] ", log.Ltime|log.Lshortfile)
	Info = log.New(os.Stdout, "[Info] ", log.Ltime|log.Lshortfile)
	Warning = log.New(os.Stdout, "[Warning] ", log.Ltime|log.Lshortfile)
	Error = log.New(os.Stderr, "[Error] ", log.Ltime|log.Lshortfile)
}

// ResetBlog resets the blog, deletes all files and clones the source repo.
func ResetBlog(repository string) error {
	// delete existing folder
	remError := os.RemoveAll(BlogFolder)
	if remError != nil && !os.IsNotExist(remError) {
		return remError
	}

	cloneCmd := exec.Command("git", "clone", repository, BlogFolder)
	// run git
	cloneStartError := cloneCmd.Start()
	// failed to run git
	if cloneStartError != nil {
		return cloneStartError
	}
	// wait for git to finish
	cloneWaitError := cloneCmd.Wait()
	// git runtime error
	if cloneWaitError != nil {
		return cloneWaitError
	}

	return nil
}

func main() {
	initLogger(ioutil.Discard)

	// parse command line arguments
	resetFlag := flag.Bool("reset", false, "Resets the blog data")
	folderFlag := flag.String("blog", "my-blog", "Sets the data source folder")
	repositoryFlag := flag.String("repo", DefaultBlogRepository, "Change the git source repository for resets")
	flag.Parse()

	BlogFolder = *folderFlag
	// check if reset
	if *resetFlag {
		Info.Println("Resetting blog folder:", BlogFolder)
		resetError := ResetBlog(*repositoryFlag)
		if resetError != nil {
			Error.Println("Failed to reset blog:", resetError)
			os.Exit(1)
		}
	}

	// load configuration file from disk
	loadError := LoadConfig()
	if loadError != nil {
		Error.Println("Failed to load configuration:", loadError)
		os.Exit(1)
	}
	LoadTemplates()
	LoadPosts()

	go runCLI()
	router := LoadRoutes()
	serverError := http.ListenAndServe(GlobalConfig.HostAddress, router)

	if serverError != nil {
		Error.Println("Server error:", serverError)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/csv"
	"fmt"
	"os"
	"time"

	"github.com/olekukonko/tablewriter"
)

var (
	idx = map[string]int{
		"start":        1,
		"end":          2,
		"title":        3,
		"description":  4,
		"speakers":     5,
		"organization": 6,
	}
)

type event []string
type schedule [][]string

func main() {
	fmt.Println("\nReading CSV")
	csvFile, err := os.Open("schedule.csv")
	if err != nil {
		panic(err)
	}

	csvr := csv.NewReader(csvFile)
	csvr.Comma = ','
	csvr.Comment = '#'

	records, err := csvr.ReadAll()
	if err != nil {
		fmt.Printf("error with csv: %v\n", err)
	}

	f, err := os.Create("schedule.txt")
	if err != nil {
		panic(fmt.Sprintf("Can't create schedule.txt in the current folder: %e", err))
	}
	defer f.Close()

	table := tablewriter.NewWriter(f)
	table.SetHeader([]string{"Day", "Start", "End", "Title", "Speaker", "Organization"})
	table.SetRowLine(true)

	s := genSchedule(records)

	table.AppendBulk(s)
	table.Render()
}

func genSchedule(recs [][]string) schedule {
	var s schedule
	var d string
	for _, r := range recs {
		e := genEvent(r)
		if e[0] != d && d != "" {
			s = append(s, event{"----", "----", "----", "----", "----", "----"})
		}
		d = e[0]
		s = append(s, e)
	}

	return s
}

func genEvent(r []string) event {
	d, ts, te, _ := getTimeInfo(r[idx["start"]], r[idx["end"]])
	e := event{fmt.Sprintf("%s/%s", d[9:], d[5:7]), ts, te, r[idx["title"]], r[idx["speakers"]], r[idx["organization"]]}
	return e
}

func getTimeInfo(start, end string) (d, ts, te, dur string) {
	// Format: 11/5/15 11:25
	tFmt := "01/2/06 15:04"
	var s, e time.Time
	var err error
	if s, err = time.Parse(tFmt, start); err != nil {
		fmt.Printf("Could not parse start time: %v", err)
	}
	if e, err = time.Parse(tFmt, end); err != nil {
		fmt.Printf("Could not parse end time: %v", err)
	}

	dFmt := "2006-01-02"
	d = s.Format(dFmt)
	tFmt = "15:04"
	ts = s.Format(tFmt)
	te = e.Format(tFmt)
	diff := e.Sub(s)
	dur = fmt.Sprintf("00:%2.f", diff.Minutes())
	return d, ts, te, dur
}
<commit_msg>Add plurals to speaker and org headers<commit_after>package main

import (
	"encoding/csv"
	"fmt"
	"os"
	"time"

	"github.com/olekukonko/tablewriter"
)

var (
	idx = map[string]int{
		"start":        1,
		"end":          2,
		"title":        3,
		"description":  4,
		"speakers":     5,
		"organization": 6,
	}
)

type event []string
type schedule [][]string

func main() {
	fmt.Println("\nReading CSV")
	csvFile, err := os.Open("schedule.csv")
	if err != nil {
		panic(err)
	}

	csvr := csv.NewReader(csvFile)
	csvr.Comma = ','
	csvr.Comment = '#'

	records, err := csvr.ReadAll()
	if err != nil {
		fmt.Printf("error with csv: %v\n", err)
	}

	f, err := os.Create("schedule.txt")
	if err != nil {
		panic(fmt.Sprintf("Can't create schedule.txt in the current folder: %e", err))
	}
	defer f.Close()

	table := tablewriter.NewWriter(f)
	table.SetHeader([]string{"Day", "Start", "End", "Title", "Speaker(s)", "Organization(s)"})
	table.SetRowLine(true)

	s := genSchedule(records)

	table.AppendBulk(s)
	table.Render()
}

func genSchedule(recs [][]string) schedule {
	var s schedule
	var d string
	for _, r := range recs {
		e := genEvent(r)
		if e[0] != d && d != "" {
			s = append(s, event{"----", "----", "----", "----", "----", "----"})
		}
		d = e[0]
		s = append(s, e)
	}

	return s
}

func genEvent(r []string) event {
	d, ts, te, _ := getTimeInfo(r[idx["start"]], r[idx["end"]])
	e := event{fmt.Sprintf("%s/%s", d[9:], d[5:7]), ts, te, r[idx["title"]], r[idx["speakers"]], r[idx["organization"]]}
	return e
}

func getTimeInfo(start, end string) (d, ts, te, dur string) {
	// Format: 11/5/15 11:25
	tFmt := "01/2/06 15:04"
	var s, e time.Time
	var err error
	if s, err = time.Parse(tFmt, start); err != nil {
		fmt.Printf("Could not parse start time: %v", err)
	}
	if e, err = time.Parse(tFmt, end); err != nil {
		fmt.Printf("Could not parse end time: %v", err)
	}

	dFmt := "2006-01-02"
	d = s.Format(dFmt)
	tFmt = "15:04"
	ts = s.Format(tFmt)
	te = e.Format(tFmt)
	diff := e.Sub(s)
	dur = fmt.Sprintf("00:%2.f", diff.Minutes())
	return d, ts, te, dur
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"regexp"
	"time"

	"github.com/bo0mer/yamt/metric/riemann"
	"github.com/bo0mer/yamt/netstat"
)

var (
	host      string
	port      int
	eventHost string
)

func init() {
	flag.StringVar(&host, "h", "localhost", "Riemann host (shorthand)")
	flag.StringVar(&host, "host", "localhost", "Riemann host")
	flag.IntVar(&port, "p", 5555, "Riemann port (shorthand)")
	flag.IntVar(&port, "port", 5555, "Riemann port")
	flag.StringVar(&eventHost, "e", "", "Event hostname (shorthand)")
	flag.StringVar(&eventHost, "event-host", "", "Event hostname")
}

func main() {
	flag.Parse()

	emitter := riemann.NewEmitter(fmt.Sprintf("%s:%d", host, port),
		riemann.Host(eventHost))

	re := regexp.MustCompile("lo")
	r := netstat.NewReporter(emitter,
		netstat.Interval(time.Second),
		netstat.Except(re))
	r.Start()
	time.Sleep(time.Second * 30)
	r.Close()
}
<commit_msg>main: add more configuration flags<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"regexp"
	"time"

	"github.com/bo0mer/yamt/metric/riemann"
	"github.com/bo0mer/yamt/netstat"
)

var (
	host      string
	port      int
	eventHost string
	interval  int
	ignoreIfs string
)

func init() {
	flag.StringVar(&host, "h", "localhost", "Riemann host (shorthand)")
	flag.StringVar(&host, "host", "localhost", "Riemann host")
	flag.IntVar(&port, "p", 5555, "Riemann port (shorthand)")
	flag.IntVar(&port, "port", 5555, "Riemann port")
	flag.StringVar(&eventHost, "e", "", "Event hostname (shorthand)")
	flag.StringVar(&eventHost, "event-host", "", "Event hostname")
	flag.IntVar(&interval, "i", 5, "Seconds between updates (shorthand)")
	flag.IntVar(&interval, "interval", 5, "Seconds between updates")
	flag.StringVar(&ignoreIfs, "g", "lo", "Interfaces to ignore (shorthand)")
	flag.StringVar(&ignoreIfs, "ignore-interfaces", "lo", "Interfaces to ignore")
}

func main() {
	flag.Parse()

	emitter := riemann.NewEmitter(fmt.Sprintf("%s:%d", host, port),
		riemann.Host(eventHost))

	re, err := regexp.Compile(ignoreIfs)
	if err != nil {
		log.Fatalf("yamt: invalid regular expression: %s\n", err)
	}
	r := netstat.NewReporter(emitter,
		netstat.Interval(time.Second*time.Duration(interval)),
		netstat.Except(re))
	r.Start()
	select {}
	defer r.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"net"
	"os"
	"path"
	"time"

	"github.com/getlantern/systray"
	quic "github.com/lucas-clemente/quic-go"
	"github.com/nange/easypool"
	"github.com/nange/easyss/utils"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
)

func init() {
	log.SetFormatter(&log.JSONFormatter{TimestampFormat: "2006-01-02 15:04:05.000"})
	log.SetLevel(log.InfoLevel)
}

func PrintVersion() {
	const version = "RC2"
	fmt.Println("easyss version", version)
}

type Easyss struct {
	config *Config
	quic   struct {
		localSess quic.Session
		sessChan  chan sessOpts
	}
	pac struct {
		ch   chan PACStatus
		url  string
		gurl string
	}
	tcpPool easypool.Pool
}

func New(config *Config) (*Easyss, error) {
	ss := &Easyss{config: config}
	if !config.ServerModel {
		ss.pac.ch = make(chan PACStatus)
		ss.pac.url = fmt.Sprintf("http://localhost:%d%s", ss.config.LocalPort+1, pacpath)
		ss.pac.gurl = fmt.Sprintf("http://localhost:%d%s?global=true", ss.config.LocalPort+1, pacpath)
	}
	if config.EnableQuic {
		ss.quic.sessChan = make(chan sessOpts, 10)
	}

	return ss, nil
}

func (ss *Easyss) InitTcpPool() error {
	factory := func() (net.Conn, error) {
		return net.Dial("tcp", fmt.Sprintf("%s:%d", ss.config.Server, ss.config.ServerPort))
	}
	pconfig := &easypool.PoolConfig{
		InitialCap:  10,
		MaxCap:      50,
		MaxIdle:     10,
		Idletime:    3 * time.Minute,
		MaxLifetime: 15 * time.Minute,
		Factory:     factory,
	}
	tcppool, err := easypool.NewHeapPool(pconfig)
	if err != nil {
		return err
	}
	ss.tcpPool = tcppool
	return nil
}

func main() {
	var configFile string
	var printVer, debug, godaemon bool
	var cmdConfig Config

	flag.BoolVar(&printVer, "version", false, "print version")
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.StringVar(&cmdConfig.Server, "s", "", "server address")
	flag.StringVar(&cmdConfig.Password, "k", "", "password")
	flag.IntVar(&cmdConfig.ServerPort, "p", 0, "server port")
	flag.IntVar(&cmdConfig.Timeout, "t", 300, "timeout in seconds")
	flag.IntVar(&cmdConfig.LocalPort, "l", 0, "local socks5 proxy port")
	flag.StringVar(&cmdConfig.Method, "m", "", "encryption method, default: aes-256-gcm")
	flag.BoolVar(&cmdConfig.EnableQuic, "quic", false, "enable quic if set this value to be true")
	flag.BoolVar(&debug, "d", false, "print debug message")
	flag.BoolVar(&cmdConfig.ServerModel, "server", false, "server model")
	flag.BoolVar(&godaemon, "daemon", true, "run app as a non-daemon with -daemon=false")

	flag.Parse()

	if printVer {
		PrintVersion()
		os.Exit(0)
	}
	// we starting easyss as daemon only in client model, and save logs to file
	if !cmdConfig.ServerModel {
		daemon(godaemon)
		fileout, err := utils.GetFileOutputWriter(os.Args[0])
		if err != nil {
			log.Errorf("get log file output writer err:%v", err)
		} else {
			log.SetOutput(fileout)
		}
	}

	if debug {
		log.SetLevel(log.DebugLevel)
	}

	exists, err := utils.FileExists(configFile)
	if !exists || err != nil {
		log.Debugf("config file err:%v", err)

		binDir := path.Dir(os.Args[0])
		configFile = path.Join(binDir, "config.json")

		log.Debugf("config file not found, try config file %s", configFile)
	}

	config, err := ParseConfig(configFile)
	if err != nil {
		config = &cmdConfig
		if !os.IsNotExist(errors.Cause(err)) {
			log.Errorf("error reading %s: %+v", configFile, err)
			os.Exit(1)
		}
	} else {
		UpdateConfig(config, &cmdConfig)
	}

	if config.Method == "" {
		config.Method = "aes-256-gcm"
	}

	ss, err := New(config)
	if err != nil {
		log.Fatalf("init Easyss err:%+v", err)
	}
	if config.ServerModel {
		if config.ServerPort == 0 || config.Password == "" {
			log.Fatalln("server port and password should not empty")
		}

		ss.Remote()
	} else {
		if config.Password == "" || config.Server == "" || config.ServerPort == 0 {
			log.Fatalln("server address, server port and password should not empty")
		}

		systray.Run(ss.trayReady, ss.trayExit) // system tray management
	}

}
<commit_msg>update version to 1.0<commit_after>package main

import (
	"flag"
	"fmt"
	"net"
	"os"
	"path"
	"time"

	"github.com/getlantern/systray"
	quic "github.com/lucas-clemente/quic-go"
	"github.com/nange/easypool"
	"github.com/nange/easyss/utils"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
)

func init() {
	log.SetFormatter(&log.JSONFormatter{TimestampFormat: "2006-01-02 15:04:05.000"})
	log.SetLevel(log.InfoLevel)
}

func PrintVersion() {
	const version = "1.0"
	fmt.Println("easyss version", version)
}

type Easyss struct {
	config *Config
	quic   struct {
		localSess quic.Session
		sessChan  chan sessOpts
	}
	pac struct {
		ch   chan PACStatus
		url  string
		gurl string
	}
	tcpPool easypool.Pool
}

func New(config *Config) (*Easyss, error) {
	ss := &Easyss{config: config}
	if !config.ServerModel {
		ss.pac.ch = make(chan PACStatus)
		ss.pac.url = fmt.Sprintf("http://localhost:%d%s", ss.config.LocalPort+1, pacpath)
		ss.pac.gurl = fmt.Sprintf("http://localhost:%d%s?global=true", ss.config.LocalPort+1, pacpath)
	}
	if config.EnableQuic {
		ss.quic.sessChan = make(chan sessOpts, 10)
	}

	return ss, nil
}

func (ss *Easyss) InitTcpPool() error {
	factory := func() (net.Conn, error) {
		return net.Dial("tcp", fmt.Sprintf("%s:%d", ss.config.Server, ss.config.ServerPort))
	}
	pconfig := &easypool.PoolConfig{
		InitialCap:  10,
		MaxCap:      50,
		MaxIdle:     10,
		Idletime:    3 * time.Minute,
		MaxLifetime: 15 * time.Minute,
		Factory:     factory,
	}
	tcppool, err := easypool.NewHeapPool(pconfig)
	if err != nil {
		return err
	}
	ss.tcpPool = tcppool
	return nil
}

func main() {
	var configFile string
	var printVer, debug, godaemon bool
	var cmdConfig Config

	flag.BoolVar(&printVer, "version", false, "print version")
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.StringVar(&cmdConfig.Server, "s", "", "server address")
	flag.StringVar(&cmdConfig.Password, "k", "", "password")
	flag.IntVar(&cmdConfig.ServerPort, "p", 0, "server port")
	flag.IntVar(&cmdConfig.Timeout, "t", 300, "timeout in seconds")
	flag.IntVar(&cmdConfig.LocalPort, "l", 0, "local socks5 proxy port")
	flag.StringVar(&cmdConfig.Method, "m", "", "encryption method, default: aes-256-gcm")
	flag.BoolVar(&cmdConfig.EnableQuic, "quic", false, "enable quic if set this value to be true")
	flag.BoolVar(&debug, "d", false, "print debug message")
	flag.BoolVar(&cmdConfig.ServerModel, "server", false, "server model")
	flag.BoolVar(&godaemon, "daemon", true, "run app as a non-daemon with -daemon=false")

	flag.Parse()

	if printVer {
		PrintVersion()
		os.Exit(0)
	}
	// we starting easyss as daemon only in client model, and save logs to file
	if !cmdConfig.ServerModel {
		daemon(godaemon)
		fileout, err := utils.GetFileOutputWriter(os.Args[0])
		if err != nil {
			log.Errorf("get log file output writer err:%v", err)
		} else {
			log.SetOutput(fileout)
		}
	}

	if debug {
		log.SetLevel(log.DebugLevel)
	}

	exists, err := utils.FileExists(configFile)
	if !exists || err != nil {
		log.Debugf("config file err:%v", err)

		binDir := path.Dir(os.Args[0])
		configFile = path.Join(binDir, "config.json")

		log.Debugf("config file not found, try config file %s", configFile)
	}

	config, err := ParseConfig(configFile)
	if err != nil {
		config = &cmdConfig
		if !os.IsNotExist(errors.Cause(err)) {
			log.Errorf("error reading %s: %+v", configFile, err)
			os.Exit(1)
		}
	} else {
		UpdateConfig(config, &cmdConfig)
	}

	if config.Method == "" {
		config.Method = "aes-256-gcm"
	}

	ss, err := New(config)
	if err != nil {
		log.Fatalf("init Easyss err:%+v", err)
	}
	if config.ServerModel {
		if config.ServerPort == 0 || config.Password == "" {
			log.Fatalln("server port and password should not empty")
		}

		ss.Remote()
	} else {
		if config.Password == "" || config.Server == "" || config.ServerPort == 0 {
			log.Fatalln("server address, server port and password should not empty")
		}

		systray.Run(ss.trayReady, ss.trayExit) // system tray management
	}

}
<|endoftext|>


<commit_before>package main

import (
	"./common"
	_ "./fetcher"
	"./model"
	"flag"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
	"github.com/op/go-logging"
)

var log *logging.Logger

func init() {
	orm.RegisterDriver("mysql", orm.DR_MySQL)
}

func initDatabase(config *common.Config) {
	orm.RegisterDataBase("default", "mysql", config.ConnectString())
}

func invokeFeedFetcher() bool {
	feeds, err := model.RdfFeeds()
	if err != nil {
		log.Error("err: %v\n", err)
		return false
	}

	for _, feed := range feeds {
		log.Info("%s\n", feed.Url)
	}

	return true
}

func main() {
	log = common.GetLogger()

	path := flag.String("c", "./config.toml", "path to config.tml")
	flag.Parse()

	var config, err = common.LoadConfig(*path)
	if err != nil {
		panic(err)
	}

	initDatabase(config)

	// invoke fetcher
	invokeFeedFetcher()
}
<commit_msg>remove panic<commit_after>package main

import (
	"./common"
	_ "./fetcher"
	"./model"
	"flag"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
	"github.com/op/go-logging"
	"os"
)

var log *logging.Logger

func init() {
	orm.RegisterDriver("mysql", orm.DR_MySQL)
}

func initDatabase(config *common.Config) {
	orm.RegisterDataBase("default", "mysql", config.ConnectString())
}

func invokeFeedFetcher() bool {
	feeds, err := model.RdfFeeds()
	if err != nil {
		log.Error("err: %v\n", err)
		return false
	}

	for _, feed := range feeds {
		log.Info("%s\n", feed.Url)
	}

	return true
}

func main() {
	log = common.GetLogger()

	path := flag.String("c", "./config.toml", "path to config.tml")
	flag.Parse()

	var config, err = common.LoadConfig(*path)
	if err != nil {
		os.Exit(1)
	}

	initDatabase(config)

	// invoke fetcher
	invokeFeedFetcher()
}
<|endoftext|>