<commit_before>/*
Quick and simple monitoring system

Usage:
 jsonmon config.yml
 jsonmon -v # Prints version to stdout and exits

Environment:
 HOST
  - defaults to localhost
  - the JSON API network interface
 PORT
  - defaults to 3000
  - the JSON API port
 GOMAXPROCS
  - defaults to CPU number + 1
  - number of threads to start
*/
package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"gopkg.in/yaml.v2"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path"
	"regexp"
	"runtime"
	"strconv"
	"sync"
	"time"
)

// Application version.
const Version = "1.2"

// This one is for internal use.
type ver struct {
	App  string `json:"jsonmon"`
	Go   string `json:"runtime"`
	Os   string `json:"os"`
	Arch string `json:"arch"`
}

var version ver

// Check details.
type Check struct {
	Name   string      `json:"name,omitempty" yaml:"name"`
	Web    string      `json:"web,omitempty" yaml:"web"`
	Shell  string      `json:"shell,omitempty" yaml:"shell"`
	Match  string      `json:"-" yaml:"match"`
	Return int         `json:"-" yaml:"return"`
	Notify interface{} `json:"-" yaml:"notify"`
	Alert  interface{} `json:"-", yaml:"alert`
	Tries  int         `json:"-" yaml:"tries"`
	Repeat int         `json:"-" yaml:"repeat"`
	Failed bool        `json:"failed" yaml:"-"`
	Since  string      `json:"since,omitempty" yaml:"-"`
}

// Global checks list. Need to share it with workers and Web UI.
var checks []Check

// Global last modified date for HTTP caching.
var modified = time.Now()

// The main loop.
func main() {
	// Parse CLI args.
	usage := "Usage: " + path.Base(os.Args[0]) + " config.yml\n" +
		"Docs:  https://github.com/chillum/jsonmon/wiki"
	if len(os.Args) != 2 {
		fmt.Fprintln(os.Stderr, usage)
		os.Exit(1)
	}
	// -v for version.
	version.App = Version
	version.Go = runtime.Version()
	version.Os = runtime.GOOS
	version.Arch = runtime.GOARCH
	switch os.Args[1] {
	case "-h":
		fallthrough
	case "-help":
		fallthrough
	case "--help":
		fmt.Fprintln(os.Stderr, usage)
		os.Exit(0)
	case "-v":
		fallthrough
	case "-version":
		fallthrough
	case "--version":
		json, _ := json.MarshalIndent(&version, "", "  ")
		fmt.Println(string(json))
		os.Exit(0)
	}
	// Tune concurrency.
	if os.Getenv("GOMAXPROCS") == "" {
		runtime.GOMAXPROCS(runtime.NumCPU() + 1)
	}
	// Read config file or exit with error.
	config, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		fmt.Fprintln(os.Stderr, "ERROR:", err)
		os.Exit(3)
	}
	err = yaml.Unmarshal(config, &checks)
	if err != nil {
		fmt.Fprintln(os.Stderr, "ERROR:", config[0], err)
		os.Exit(3)
	}
	// Run checks.
	var wg sync.WaitGroup
	wg.Add(1)
	for i := range checks {
		go worker(&checks[i])
	}
	// Launch the JSON API.
	host := os.Getenv("HOST")
	port := os.Getenv("PORT")
	if host == "" {
		host = "localhost"
	}
	if port == "" {
		port = "3000"
	}
	http.HandleFunc("/version", getVersion)
	http.HandleFunc("/", getChecks)
	err = http.ListenAndServe(host+":"+port, nil)
	if err != nil {
		fmt.Fprintln(os.Stderr, "ERROR:", err)
	}
	// Wait forever.
	wg.Wait()
}

// Background worker.
func worker(check *Check) {
	for {
		if check.Repeat == 0 { // Set default timeout.
			check.Repeat = 60
		}
		if check.Tries == 0 { // Default to 1 attempt.
			check.Tries = 1
		}
		if check.Web != "" {
			web(check)
		}
		if check.Shell != "" {
			shell(check)
		}
		time.Sleep(time.Second * time.Duration(check.Repeat))
	}
}

// Shell worker.
func shell(check *Check) {
	// Set check's display name.
	var name string
	if check.Name != "" {
		name = check.Name
	} else {
		name = check.Shell
	}
	// Execute with shell in N attemps.
	var out []byte
	var err error
	for i := 0; i < check.Tries; i++ {
		out, err = exec.Command("/bin/sh", "-c", check.Shell).CombinedOutput()
		if err == nil {
			if check.Match != "" { // Match regexp.
				var regex *regexp.Regexp
				regex, err = regexp.Compile(check.Match)
				if err == nil && !regex.Match(out) {
					err = errors.New("ERROR: output did not match " + check.Match)
				}
			}
			break
		}
	}
	// Process results.
	if err == nil {
		if check.Failed {
			check.Failed = false
			check.Since = time.Now().Format(time.RFC3339)
			modified = time.Now()
			notify(check.Notify, "Fixed: "+name, nil)
			alert(check, &name, nil)
		}
	} else {
		if !check.Failed {
			check.Failed = true
			check.Since = time.Now().Format(time.RFC3339)
			modified = time.Now()
			msg := string(out) + err.Error()
			notify(check.Notify, "Failed: "+name, &msg)
			alert(check, &name, &msg)
		}
	}
}

// Web worker.
func web(check *Check) {
	// Set check's display name.
	var name string
	if check.Name != "" {
		name = check.Name
	} else {
		name = check.Web
	}
	if check.Return == 0 { // Successful HTTP return code is 200.
		check.Return = 200
	}
	// Get the URL in N attempts.
	var err error
	for i := 0; i < check.Tries; i++ {
		err = fetch(check.Web, check.Match, check.Return)
		if err == nil {
			break
		}
	}
	// Process results.
	if err == nil {
		if check.Failed {
			check.Failed = false
			check.Since = time.Now().Format(time.RFC3339)
			modified = time.Now()
			notify(check.Notify, "Fixed: "+name, nil)
			alert(check, &name, nil)

		}
	} else {
		if !check.Failed {
			check.Failed = true
			check.Since = time.Now().Format(time.RFC3339)
			modified = time.Now()
			msg := err.Error()
			notify(check.Notify, "Failed: "+name, &msg)
			alert(check, &name, &msg)
		}
	}
}

// The actual HTTP GET.
func fetch(url string, match string, code int) error {
	var err error
	var resp *http.Response
	resp, err = http.Get(url)
	if err == nil {
		if resp.StatusCode != code { // Check status code.
			err = errors.New(url + " returned " + strconv.Itoa(resp.StatusCode))
		} else { // Match regexp.
			if resp != nil && match != "" {
				var regex *regexp.Regexp
				regex, err = regexp.Compile(match)
				if err == nil {
					var body []byte
					body, _ = ioutil.ReadAll(resp.Body)
					if !regex.Match(body) {
						err = errors.New(url + " output did not match " + match)
					}
				}
			}
		}
	}
	if resp != nil {
		resp.Body.Close()
	}
	return err
}

// Logs and mail alerting.
func notify(mail interface{}, subject string, message *string) {
	// Log the alerts.
	if message == nil {
		fmt.Println(subject)
	} else {
		fmt.Println(subject + "\n" + *message)
	}
	// Mail the alerts.
	if mail != nil {
		// Make the message.
		var rcpt string
		var ok bool
		if rcpt, ok = mail.(string); !ok {
			for i, v := range mail.([]interface{}) {
				if i != 0 {
					rcpt += ", "
				}
				rcpt += v.(string)
			}
		}
		msg := "To: " + rcpt + "\nSubject: " + subject + "\n\n"
		if message != nil {
			msg += *message
		}
		msg += "\n.\n"
		// And send it.
		sendmail := exec.Command("/usr/sbin/sendmail", "-t")
		stdin, _ := sendmail.StdinPipe()
		err := sendmail.Start()
		if err != nil {
			fmt.Fprintln(os.Stderr, "ERROR:", err)
		}
		io.WriteString(stdin, msg)
		sendmail.Wait()
	}
}

// Executes callback. Passes args: true/false, check's name, message.
func alert(check *Check, name *string, msg *string) {
	if check.Alert != nil {
		plugin, ok := check.Alert.(string)
		if ok { // check.Alert is a string.
			out, err := exec.Command(plugin, strconv.FormatBool(check.Failed), *name, *msg).CombinedOutput()
			if err != nil {
				fmt.Fprintln(os.Stderr, "ERROR:", string(out)+err.Error())
			}
		} else { // check.Alert is a list.
			for _, i := range check.Alert.([]interface{}) {
				out, err := exec.Command(i.(string), strconv.FormatBool(check.Failed), *name, *msg).CombinedOutput()
				if err != nil {
					fmt.Fprintln(os.Stderr, "ERROR:", string(out)+err.Error())
				}
			}
		}
	}
}

// Display checks' details.
func getChecks(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path != "/" { // Serve for root page only, 404 otherwise.
		w.Header().Set("Server", "jsonmon")
		http.NotFound(w, r)
		return
	}
	displayJSON(w, r, &checks)
}

// Display application version.
func getVersion(w http.ResponseWriter, r *http.Request) {
	displayJSON(w, r, &version)
}

// Output JSON.
func displayJSON(w http.ResponseWriter, r *http.Request, data interface{}) {
	h := w.Header()
	h.Set("Server", "jsonmon")
	if t, err := time.Parse(time.RFC1123, r.Header.Get("If-Modified-Since")); err == nil && modified.Before(t.Add(1*time.Second)) {
		delete(h, "Content-Type")
		delete(h, "Content-Length")
		w.WriteHeader(http.StatusNotModified)
	} else {
		h.Set("Cache-Control", "no-cache")
		h.Set("Last-Modified", modified.UTC().Format(time.RFC1123))
		h.Set("Access-Control-Allow-Origin", "*")
		h.Set("Content-Type", "application/json; charset=utf-8")
		json, _ := json.MarshalIndent(&data, "", "  ")
		w.Write(json)
		fmt.Fprintln(w, "") // Trailing newline.
	}
}
<commit_msg>ETag support<commit_after>/*
Quick and simple monitoring system

Usage:
 jsonmon config.yml
 jsonmon -v # Prints version to stdout and exits

Environment:
 HOST
  - defaults to localhost
  - the JSON API network interface
 PORT
  - defaults to 3000
  - the JSON API port
 GOMAXPROCS
  - defaults to CPU number + 1
  - number of threads to start
*/
package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"gopkg.in/yaml.v2"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path"
	"regexp"
	"runtime"
	"strconv"
	"sync"
	"time"
)

// Application version.
const Version = "1.2.1"

// This one is for internal use.
type ver struct {
	App  string `json:"jsonmon"`
	Go   string `json:"runtime"`
	Os   string `json:"os"`
	Arch string `json:"arch"`
}

var version ver

// Check details.
type Check struct {
	Name   string      `json:"name,omitempty" yaml:"name"`
	Web    string      `json:"web,omitempty" yaml:"web"`
	Shell  string      `json:"shell,omitempty" yaml:"shell"`
	Match  string      `json:"-" yaml:"match"`
	Return int         `json:"-" yaml:"return"`
	Notify interface{} `json:"-" yaml:"notify"`
	Alert  interface{} `json:"-", yaml:"alert`
	Tries  int         `json:"-" yaml:"tries"`
	Repeat int         `json:"-" yaml:"repeat"`
	Failed bool        `json:"failed" yaml:"-"`
	Since  string      `json:"since,omitempty" yaml:"-"`
}

// Global checks list. Need to share it with workers and Web UI.
var checks []Check

// Global last modified date for HTTP caching.
var modified string

// Construct the last modified string.
func etag() {
	modified = "\"" + strconv.FormatInt(time.Now().UnixNano(), 10) + "\""
}

// The main loop.
func main() {
	// Parse CLI args.
	usage := "Usage: " + path.Base(os.Args[0]) + " config.yml\n" +
		"Docs:  https://github.com/chillum/jsonmon/wiki"
	if len(os.Args) != 2 {
		fmt.Fprintln(os.Stderr, usage)
		os.Exit(1)
	}
	// -v for version.
	version.App = Version
	version.Go = runtime.Version()
	version.Os = runtime.GOOS
	version.Arch = runtime.GOARCH
	switch os.Args[1] {
	case "-h":
		fallthrough
	case "-help":
		fallthrough
	case "--help":
		fmt.Fprintln(os.Stderr, usage)
		os.Exit(0)
	case "-v":
		fallthrough
	case "-version":
		fallthrough
	case "--version":
		json, _ := json.MarshalIndent(&version, "", "  ")
		fmt.Println(string(json))
		os.Exit(0)
	}
	// Tune concurrency.
	if os.Getenv("GOMAXPROCS") == "" {
		runtime.GOMAXPROCS(runtime.NumCPU() + 1)
	}
	// Read config file or exit with error.
	config, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		fmt.Fprintln(os.Stderr, "ERROR:", err)
		os.Exit(3)
	}
	err = yaml.Unmarshal(config, &checks)
	if err != nil {
		fmt.Fprintln(os.Stderr, "ERROR:", config[0], err)
		os.Exit(3)
	}
	// Run checks.
	var wg sync.WaitGroup
	wg.Add(1)
	etag()
	for i := range checks {
		go worker(&checks[i])
	}
	// Launch the JSON API.
	host := os.Getenv("HOST")
	port := os.Getenv("PORT")
	if host == "" {
		host = "localhost"
	}
	if port == "" {
		port = "3000"
	}
	http.HandleFunc("/version", getVersion)
	http.HandleFunc("/", getChecks)
	err = http.ListenAndServe(host+":"+port, nil)
	if err != nil {
		fmt.Fprintln(os.Stderr, "ERROR:", err)
	}
	// Wait forever.
	wg.Wait()
}

// Background worker.
func worker(check *Check) {
	for {
		if check.Repeat == 0 { // Set default timeout.
			check.Repeat = 60
		}
		if check.Tries == 0 { // Default to 1 attempt.
			check.Tries = 1
		}
		if check.Web != "" {
			web(check)
		}
		if check.Shell != "" {
			shell(check)
		}
		time.Sleep(time.Second * time.Duration(check.Repeat))
	}
}

// Shell worker.
func shell(check *Check) {
	// Set check's display name.
	var name string
	if check.Name != "" {
		name = check.Name
	} else {
		name = check.Shell
	}
	// Execute with shell in N attemps.
	var out []byte
	var err error
	for i := 0; i < check.Tries; i++ {
		out, err = exec.Command("/bin/sh", "-c", check.Shell).CombinedOutput()
		if err == nil {
			if check.Match != "" { // Match regexp.
				var regex *regexp.Regexp
				regex, err = regexp.Compile(check.Match)
				if err == nil && !regex.Match(out) {
					err = errors.New("ERROR: output did not match " + check.Match)
				}
			}
			break
		}
	}
	// Process results.
	if err == nil {
		if check.Failed {
			check.Failed = false
			check.Since = time.Now().Format(time.RFC3339)
			etag()
			notify(check.Notify, "Fixed: "+name, nil)
			alert(check, &name, nil)
		}
	} else {
		if !check.Failed {
			check.Failed = true
			check.Since = time.Now().Format(time.RFC3339)
			etag()
			msg := string(out) + err.Error()
			notify(check.Notify, "Failed: "+name, &msg)
			alert(check, &name, &msg)
		}
	}
}

// Web worker.
func web(check *Check) {
	// Set check's display name.
	var name string
	if check.Name != "" {
		name = check.Name
	} else {
		name = check.Web
	}
	if check.Return == 0 { // Successful HTTP return code is 200.
		check.Return = 200
	}
	// Get the URL in N attempts.
	var err error
	for i := 0; i < check.Tries; i++ {
		err = fetch(check.Web, check.Match, check.Return)
		if err == nil {
			break
		}
	}
	// Process results.
	if err == nil {
		if check.Failed {
			check.Failed = false
			check.Since = time.Now().Format(time.RFC3339)
			etag()
			notify(check.Notify, "Fixed: "+name, nil)
			alert(check, &name, nil)

		}
	} else {
		if !check.Failed {
			check.Failed = true
			check.Since = time.Now().Format(time.RFC3339)
			etag()
			msg := err.Error()
			notify(check.Notify, "Failed: "+name, &msg)
			alert(check, &name, &msg)
		}
	}
}

// The actual HTTP GET.
func fetch(url string, match string, code int) error {
	var err error
	var resp *http.Response
	resp, err = http.Get(url)
	if err == nil {
		if resp.StatusCode != code { // Check status code.
			err = errors.New(url + " returned " + strconv.Itoa(resp.StatusCode))
		} else { // Match regexp.
			if resp != nil && match != "" {
				var regex *regexp.Regexp
				regex, err = regexp.Compile(match)
				if err == nil {
					var body []byte
					body, _ = ioutil.ReadAll(resp.Body)
					if !regex.Match(body) {
						err = errors.New(url + " output did not match " + match)
					}
				}
			}
		}
	}
	if resp != nil {
		resp.Body.Close()
	}
	return err
}

// Logs and mail alerting.
func notify(mail interface{}, subject string, message *string) {
	// Log the alerts.
	if message == nil {
		fmt.Println(subject)
	} else {
		fmt.Println(subject + "\n" + *message)
	}
	// Mail the alerts.
	if mail != nil {
		// Make the message.
		var rcpt string
		var ok bool
		if rcpt, ok = mail.(string); !ok {
			for i, v := range mail.([]interface{}) {
				if i != 0 {
					rcpt += ", "
				}
				rcpt += v.(string)
			}
		}
		msg := "To: " + rcpt + "\nSubject: " + subject + "\n\n"
		if message != nil {
			msg += *message
		}
		msg += "\n.\n"
		// And send it.
		sendmail := exec.Command("/usr/sbin/sendmail", "-t")
		stdin, _ := sendmail.StdinPipe()
		err := sendmail.Start()
		if err != nil {
			fmt.Fprintln(os.Stderr, "ERROR:", err)
		}
		io.WriteString(stdin, msg)
		sendmail.Wait()
	}
}

// Executes callback. Passes args: true/false, check's name, message.
func alert(check *Check, name *string, msg *string) {
	if check.Alert != nil {
		plugin, ok := check.Alert.(string)
		if ok { // check.Alert is a string.
			out, err := exec.Command(plugin, strconv.FormatBool(check.Failed), *name, *msg).CombinedOutput()
			if err != nil {
				fmt.Fprintln(os.Stderr, "ERROR:", string(out)+err.Error())
			}
		} else { // check.Alert is a list.
			for _, i := range check.Alert.([]interface{}) {
				out, err := exec.Command(i.(string), strconv.FormatBool(check.Failed), *name, *msg).CombinedOutput()
				if err != nil {
					fmt.Fprintln(os.Stderr, "ERROR:", string(out)+err.Error())
				}
			}
		}
	}
}

// Display checks' details.
func getChecks(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path != "/" { // Serve for root page only, 404 otherwise.
		w.Header().Set("Server", "jsonmon")
		http.NotFound(w, r)
		return
	}
	displayJSON(w, r, &checks)
}

// Display application version.
func getVersion(w http.ResponseWriter, r *http.Request) {
	displayJSON(w, r, &version)
}

// Output JSON.
func displayJSON(w http.ResponseWriter, r *http.Request, data interface{}) {
	h := w.Header()
	h.Set("Server", "jsonmon")
	if r.Header.Get("If-None-Match") == modified {
		delete(h, "Content-Type")
		delete(h, "Content-Length")
		w.WriteHeader(http.StatusNotModified)
	} else {
		h.Set("Cache-Control", "no-cache")
		h.Set("ETag", modified)
		h.Set("Access-Control-Allow-Origin", "*")
		h.Set("Content-Type", "application/json; charset=utf-8")
		json, _ := json.MarshalIndent(&data, "", "  ")
		w.Write(json)
		fmt.Fprintln(w, "") // Trailing newline.
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
)

var (
	listenAddr = flag.String("http", ":9000", "HTTP listen address")
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/", rootHandler)

	log.Printf("Listening on %s", *listenAddr)
	log.Print(http.ListenAndServe(*listenAddr, mux))
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	log.Printf("[r] %s %s", r.Method, r.RequestURI)
	fmt.Fprintf(w, "OK\n")
}
<commit_msg>Only respond to GET /<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
)

var (
	listenAddr = flag.String("http", ":9000", "HTTP listen address")
)

func main() {
	mux := http.NewServeMux()
	mux.Handle("/h/", &HookHandler{})
	mux.HandleFunc("/", rootHandler)

	log.Printf("Listening on %s", *listenAddr)
	log.Print(http.ListenAndServe(*listenAddr, mux))
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" || r.RequestURI != "/" {
		http.NotFound(w, r)
		return
	}
	log.Printf("[r] %s %s", r.Method, r.RequestURI)
	fmt.Fprintf(w, "OK\n")
}
<|endoftext|>


<commit_before>package main

import "io"
import "fmt"
import "net/http"
import "os"
import "os/exec"
import "flag"
import "strings"
import "strconv"

import "github.com/gorilla/websocket"
import "github.com/kr/pty"
import "github.com/creack/goterm/win"

func start() (*os.File, *exec.Cmd) {
	var err error

	cmdString := "/bin/bash"
	cmd := exec.Command(cmdString)
	ptym, err := pty.Start(cmd)
	if err != nil {
		fmt.Println("Failed to start command: ", err)
	}

	return ptym, cmd
}

func stop(ptym *os.File, cmd *exec.Cmd, conn *websocket.Conn) {
	ptym.Close()
	conn.Close()
	cmd.Wait()
}

// Read from the websocket, copying to the pty master.
func handleInput(ptym *os.File, conn *websocket.Conn) {
	for {
		mt, payload, err := conn.ReadMessage()
		if err != nil {
			if err != io.EOF {
				fmt.Println("conn.ReadMessage failed: ", err)
				return
			}
		}

		if mt == -1 {
			// The client has likely disconnected.
			return
		}

		switch mt {
		case websocket.BinaryMessage:
			ptym.Write(payload)
		default:
			fmt.Println("Invalid message type: ", mt)
			return
		}
	}
}

// Copy everything from the pty master to the websocket.
func handleOutput(ptym *os.File, conn *websocket.Conn) {
	buf := make([]byte, 512)
	// TODO: more graceful exit on socket close / process exit
	for {
		n, err := ptym.Read(buf)
		if err != nil {
			fmt.Println("Failed to read from pty master: ", err)
			return
		}

		err = conn.WriteMessage(websocket.BinaryMessage, buf[0:n])

		if err != nil {
			fmt.Println("Failed to send %d bytes on websocket: %s", n, err)
			return
		}
	}
}

func setPtySize(ptym *os.File, size string) {
	sizeArr := strings.Split(size, "x")
	lines, _ := strconv.Atoi(sizeArr[0])
	cols, _ := strconv.Atoi(sizeArr[1])
	if err := win.SetWinsize(ptym.Fd(), &win.Winsize{Height: uint16(lines), Width: uint16(cols)}); err != nil {
		panic(err)
	}
}

func ptyHandler(w http.ResponseWriter, r *http.Request, sizeFlag string) {
	var upgrader = websocket.Upgrader{
		ReadBufferSize:  1,
		WriteBufferSize: 1,
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		fmt.Println("Websocket upgrade failed: ", err)
	}

	ptym, cmd := start()
	setPtySize(ptym, sizeFlag)

	go func() {
		handleOutput(ptym, conn)
	}()

	go func() {
		handleInput(ptym, conn)
	}()

	// Listen for a new winsize on stdin.
	for {
		var newSize string
		_, scanErr := fmt.Scanln(&newSize)
		if scanErr != nil {
			fmt.Println("scan failed: ", scanErr)
		}

		setPtySize(ptym, newSize)
	}

	stop(ptym, cmd, conn)
}

func main() {
	addrFlag := flag.String("addr", ":12061", "IP:PORT or :PORT address to listen on")
	sizeFlag := flag.String("size", "24x80", "initial size for the tty")

	flag.Parse()

	http.HandleFunc("/pty", func(w http.ResponseWriter, r *http.Request) {
		ptyHandler(w, r, *sizeFlag)
	})

	err := http.ListenAndServe(*addrFlag, nil)
	if err != nil {
		fmt.Println("net.http could not listen on address '%s': %s", addrFlag, err)
	}
}
<commit_msg>Added debug prints<commit_after>package main

import "io"
import "fmt"
import "net/http"
import "os"
import "os/exec"
import "flag"
import "strings"
import "strconv"

import "github.com/gorilla/websocket"
import "github.com/kr/pty"
import "github.com/creack/goterm/win"

func start() (*os.File, *exec.Cmd) {
	var err error

	cmdString := "/bin/bash"
	cmd := exec.Command(cmdString)
	ptym, err := pty.Start(cmd)
	if err != nil {
		fmt.Println("Failed to start command: ", err)
	}

	return ptym, cmd
}

func stop(ptym *os.File, cmd *exec.Cmd, conn *websocket.Conn) {
	ptym.Close()
	conn.Close()
	cmd.Wait()
}

// Read from the websocket, copying to the pty master.
func handleInput(ptym *os.File, conn *websocket.Conn) {
	for {
		mt, payload, err := conn.ReadMessage()
		if err != nil {
			if err != io.EOF {
				fmt.Println("conn.ReadMessage failed: ", err)
				return
			}
		}

		if mt == -1 {
			// The client has likely disconnected.
			return
		}

		switch mt {
		case websocket.BinaryMessage:
			ptym.Write(payload)
		default:
			fmt.Println("Invalid message type: ", mt)
			return
		}
	}
}

// Copy everything from the pty master to the websocket.
func handleOutput(ptym *os.File, conn *websocket.Conn) {
	buf := make([]byte, 512)
	// TODO: more graceful exit on socket close / process exit
	for {
		n, err := ptym.Read(buf)
		if err != nil {
			fmt.Println("Failed to read from pty master: ", err)
			return
		}

		err = conn.WriteMessage(websocket.BinaryMessage, buf[0:n])

		if err != nil {
			fmt.Println("Failed to send %d bytes on websocket: %s", n, err)
			return
		}
	}
}

func setPtySize(ptym *os.File, size string) {
	sizeArr := strings.Split(size, "x")
	lines, _ := strconv.Atoi(sizeArr[0])
	cols, _ := strconv.Atoi(sizeArr[1])
	if err := win.SetWinsize(ptym.Fd(), &win.Winsize{Height: uint16(lines), Width: uint16(cols)}); err != nil {
		panic(err)
	}
}

func ptyHandler(w http.ResponseWriter, r *http.Request, sizeFlag string) {
	var upgrader = websocket.Upgrader{
		ReadBufferSize:  1,
		WriteBufferSize: 1,
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		fmt.Println("Websocket upgrade failed: ", err)
	}

	ptym, cmd := start()
	setPtySize(ptym, sizeFlag)

	go func() {
		handleOutput(ptym, conn)
	}()

	go func() {
		handleInput(ptym, conn)
	}()

	// Listen for a new winsize on stdin.
	for {
		var newSize string
		_, scanErr := fmt.Scanln(&newSize)
		if scanErr != nil {
			fmt.Println("scan failed: ", scanErr)
		}

		setPtySize(ptym, newSize)
		fmt.Println("new size: ", newSize)
	}

	stop(ptym, cmd, conn)
}

func main() {
	addrFlag := flag.String("addr", ":12061", "IP:PORT or :PORT address to listen on")
	sizeFlag := flag.String("size", "24x80", "initial size for the tty")

	flag.Parse()

	http.HandleFunc("/pty", func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("client connected.")
		ptyHandler(w, r, *sizeFlag)
	})

	err := http.ListenAndServe(*addrFlag, nil)
	if err != nil {
		fmt.Println("net.http could not listen on address '%s': %s", addrFlag, err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/hashicorp/terraform/plugin"
	"github.com/martinivanov/terraform-provider-kong/kong"
)

func main() {
	plugin.Serve(&plugin.ServeOpts{
		ProviderFunc: kong.Provider,
	})
}
<commit_msg>Fix wrong plugin repo<commit_after>package main

import (
	"github.com/hashicorp/terraform/plugin"
	"github.com/WeKnowSports/terraform-provider-kong/kong"
)

func main() {
	plugin.Serve(&plugin.ServeOpts{
		ProviderFunc: kong.Provider,
	})
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"

	"github.com/drunkenfall/drunkenfall/towerfall"
	"github.com/drunkenfall/drunkenfall/towerfall/migrations"
)

func main() {
	Kekkonen() // Kekkonen

	// Instantiate the database
	db, err := towerfall.NewDatabase(os.Getenv("DF_DB_PATH"))
	if err != nil {
		log.Fatal(err)
	}

	// Apply any applicable migrations
	err = migrations.Migrate(db.DB)
	if err != nil {
		log.Fatal(err)
	}

	// Create the server instance
	s := towerfall.NewServer(db)

	// Load tournaments from the database
	err = db.LoadTournaments()
	if err != nil {
		log.Fatal(err)
	}

	// Set up the paths and the websocket listeners
	s.RegisterHandlersAndListeners()

	// Actually start serving
	if err := s.Serve(); err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Catch termination and close database properly<commit_after>package main

import (
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/drunkenfall/drunkenfall/towerfall"
	"github.com/drunkenfall/drunkenfall/towerfall/migrations"
)

func main() {
	Kekkonen() // Kekkonen

	// Instantiate the database
	db, err := towerfall.NewDatabase(os.Getenv("DF_DB_PATH"))
	if err != nil {
		log.Fatal(err)
	}

	// Apply any applicable migrations
	err = migrations.Migrate(db.DB)
	if err != nil {
		log.Fatal(err)
	}

	// Create the server instance
	s := towerfall.NewServer(db)

	// Load tournaments from the database
	err = db.LoadTournaments()
	if err != nil {
		log.Fatal(err)
	}

	// Set up the paths and the websocket listeners
	s.RegisterHandlersAndListeners()

	// Catch termination signals so we can close the databas properly
	c := make(chan os.Signal, 2)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-c
		log.Print("Catching SIGTERM, closing database...")
		db.DB.Close()
		log.Print("Done. Exiting uncleanly.")
		os.Exit(1)
	}()

	// Actually start serving
	if err := s.Serve(); err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>// git-remote-helper implements a git-remote helper that uses the ipfs transport
//
// ie: git clone ipfs://$some/path/to/.git
//
// see https://git-scm.com/docs/gitremote-helpers for more
//
// progress: https://github.com/cryptix/git-remote-ipfs/issues/1

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"log"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/cryptix/go/debug"
	"github.com/whyrusleeping/ipfs-shell"
)

const usageMsg = `usage git-remote-ipfs <repository> [<URL>]
supports ipfs://$hash/path..

TODO:
- urls like ipfs::/path/
`

func usage() {
	fmt.Fprint(os.Stderr, usageMsg)
	os.Exit(2)
}

var (
	tmpBareRepo string
)

func main() {
	log.SetFlags(0)
	log.SetOutput(os.Stderr)
	log.SetPrefix("git-remote-ipfs:")

	//log.Println("Hello", os.Environ())

	thisGitRepo := os.Getenv("GIT_DIR")
	if thisGitRepo == "" {
		log.Fatal("could not get GIT_DIR env var")
	}
	log.Println("GIT_DIR=", thisGitRepo)

	var u string // repo url
	v := len(os.Args[1:])
	switch v {
	case 2:
		log.Println("repo:", os.Args[1])
		log.Println("url:", os.Args[2])
		u = os.Args[2]

	default:
		log.Fatalf("usage: unknown # of args: %d\n%v", v, os.Args[1:])
	}

	// since we get a proper URL, we can parse it make sure its valid
	repoUrl, err := url.Parse(u)
	if err != nil {
		log.Fatalf("url.Parse() failed: %s", err)
	}
	log.Printf("dbg: repo url %#v", repoUrl)

	if repoUrl.Scheme != "ipfs" { // ipns will have a seperate helper
		log.Fatal("only ipfs schema is supported")
	}

	// get root hash of the passed repo path
	path := fmt.Sprintf("/ipfs/%s/%s", repoUrl.Host, repoUrl.Path)
	var b bytes.Buffer
	if err := Execute(&b,
		exec.Command("ipfs", "object", "get", path),
		exec.Command("ipfs", "object", "put", "--inputenc=json"),
	); err != nil {
		log.Fatalln("root hash pipe failed", err)
	}

	hash := b.String()
	const expAdded = "added "
	if !strings.HasPrefix(hash, expAdded) {
		log.Fatal("invalid output of root-hash-pipe, expected: %s got: %s", expAdded, hash)
	}
	hash = hash[len(expAdded):]
	log.Println("DEBUG: root hash: ", hash)

	tmpBareRepo = fetchFullBareRepo(hash)

	go speakGit(os.Stdin)

	select {} // block indefinetly - until stdin closes most likly
}

func fetchFullBareRepo(root string) string {
	// TODO: document host format
	shell := shell.NewShell("localhost:5001")

	tmpPath := filepath.Join("/", os.TempDir(), root)
	s, err := os.Stat(tmpPath)
	if err != nil {
		if os.IsNotExist(err) {
			if err := shell.Get(root, tmpPath); err != nil {
				log.Fatalf("shell.Get(%s, %s) failed: %s", root, tmpPath, err)
			}
			log.Println("DEBUG: shell got:", root)
			return tmpPath
		}
		log.Fatalf("stat err: %s", err)
	}
	if !s.IsDir() {
		log.Fatalf("please delete %s")
	}
	return tmpPath
}

// speakGit acts like a git-remote-helper
// see this for more: https://www.kernel.org/pub/software/scm/git/docs/gitremote-helpers.html
func speakGit(r io.Reader) {
	r = debug.NewReadLogger("git>>", r)
	w := debug.NewWriteLogger("git<<", os.Stdout)

	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		text := scanner.Text()
		switch {

		case text == "capabilities":
			log.Println("DEBUG: got caps line")
			fmt.Fprintf(w, "fetch\n\n")

		case text == "list":
			log.Println("DEBUG: got list line")

			var b bytes.Buffer
			log.Println("DEBUG: tmp repo:", tmpBareRepo)
			cmd := exec.Command("git", "ls-remote", tmpBareRepo)
			cmd.Stdout = &b
			cmd.Stderr = &b

			if err := cmd.Run(); err != nil {
				log.Fatalf("git ls-remote Run error: %s", err)
			}

			log.Println("DEBUG: ran git ls-remote")
			// convert tabs to spaces
			tabToSpace := strings.NewReplacer("\t", " ")
			_, err := tabToSpace.WriteString(w, b.String())
			if err != nil {
				log.Fatalf("git ls-remote tab conversion error: %s", err)
			}
			fmt.Fprintln(w, "")

		case strings.HasPrefix(text, "fetch "):
			fetchSplit := strings.Split(text, " ")
			if len(fetchSplit) < 2 {
				log.Printf("malformed 'fetch' command. %q", text)
			}
			log.Printf("DEBUG: fetch sha1<%s> name<%s>", fetchSplit[1], fetchSplit[2])

		default:
			log.Printf("DEBUG: default git speak: %q\n", text)
			os.Exit(1)
		}
	}

	if err := scanner.Err(); err != nil {
		log.Fatalf("stdin scanner error: %s", err)
	}
}
<commit_msg>'git clone ipfs://' can work<commit_after>// git-remote-helper implements a git-remote helper that uses the ipfs transport
//
// ie: git clone ipfs://$some/path/to/.git
//
// see https://git-scm.com/docs/gitremote-helpers for more
//
// progress: https://github.com/cryptix/git-remote-ipfs/issues/1

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"log"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/cryptix/go/debug"
	"github.com/whyrusleeping/ipfs-shell"
	"gopkg.in/errgo.v1"
)

const usageMsg = `usage git-remote-ipfs <repository> [<URL>]
supports ipfs://$hash/path..

TODO:
- urls like ipfs::/path/
`

func usage() {
	fmt.Fprint(os.Stderr, usageMsg)
	os.Exit(2)
}

var (
	tmpBareRepo string
	thisGitRepo string
)

func main() {
	log.SetFlags(0)
	log.SetOutput(os.Stderr)
	log.SetPrefix("git-remote-ipfs:")

	//log.Println("Hello", os.Environ())

	thisGitRepo := os.Getenv("GIT_DIR")
	if thisGitRepo == "" {
		log.Fatal("could not get GIT_DIR env var")
	}
	log.Println("GIT_DIR=", thisGitRepo)

	var u string // repo url
	v := len(os.Args[1:])
	switch v {
	case 2:
		log.Println("repo:", os.Args[1])
		log.Println("url:", os.Args[2])
		u = os.Args[2]

	default:
		log.Fatalf("usage: unknown # of args: %d\n%v", v, os.Args[1:])
	}

	// since we get a proper URL, we can parse it make sure its valid
	repoUrl, err := url.Parse(u)
	if err != nil {
		log.Fatalf("url.Parse() failed: %s", err)
	}
	log.Printf("dbg: repo url %#v", repoUrl)

	if repoUrl.Scheme != "ipfs" { // ipns will have a seperate helper
		log.Fatal("only ipfs schema is supported")
	}

	// get root hash of the passed repo path
	path := fmt.Sprintf("/ipfs/%s/%s", repoUrl.Host, repoUrl.Path)
	var b bytes.Buffer
	if err := Execute(&b,
		exec.Command("ipfs", "object", "get", path),
		exec.Command("ipfs", "object", "put", "--inputenc=json"),
	); err != nil {
		log.Fatalln("root hash pipe failed", err)
	}

	hash := b.String()
	const expAdded = "added "
	if !strings.HasPrefix(hash, expAdded) {
		log.Fatal("invalid output of root-hash-pipe, expected: %s got: %s", expAdded, hash)
	}
	hash = hash[len(expAdded):]
	log.Println("DEBUG: root hash: ", hash)

	tmpBareRepo = fetchFullBareRepo(hash)

	go speakGit(os.Stdin)

	select {} // block indefinetly - until stdin closes most likly
}

func fetchFullBareRepo(root string) string {
	// TODO: document host format
	shell := shell.NewShell("localhost:5001")

	tmpPath := filepath.Join("/", os.TempDir(), root)
	s, err := os.Stat(tmpPath)
	if err != nil {
		if os.IsNotExist(err) {
			if err := shell.Get(root, tmpPath); err != nil {
				log.Fatalf("shell.Get(%s, %s) failed: %s", root, tmpPath, err)
			}
			log.Println("DEBUG: shell got:", root)
			return tmpPath
		}
		log.Fatalf("stat err: %s", err)
	}
	if !s.IsDir() {
		log.Fatalf("please delete %s")
	}
	return tmpPath
}

// speakGit acts like a git-remote-helper
// see this for more: https://www.kernel.org/pub/software/scm/git/docs/gitremote-helpers.html
func speakGit(r io.Reader) {
	r = debug.NewReadLogger("git>>", r)
	w := debug.NewWriteLogger("git<<", os.Stdout)

	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		text := scanner.Text()
		switch {

		case text == "capabilities":
			log.Println("DEBUG: got caps line")
			fmt.Fprintf(w, "fetch\n\n")

		case text == "list":
			log.Println("DEBUG: got list line")

			var b bytes.Buffer
			log.Println("DEBUG: tmp repo:", tmpBareRepo)
			cmd := exec.Command("git", "ls-remote", tmpBareRepo)
			cmd.Stdout = &b
			cmd.Stderr = &b

			if err := cmd.Run(); err != nil {
				log.Fatalf("git ls-remote Run error: %s", err)
			}

			log.Println("DEBUG: ran git ls-remote")
			// convert tabs to spaces
			tabToSpace := strings.NewReplacer("\t", " ")
			_, err := tabToSpace.WriteString(w, b.String())
			if err != nil {
				log.Fatalf("git ls-remote tab conversion error: %s", err)
			}
			fmt.Fprintln(w, "")

		case strings.HasPrefix(text, "fetch "):
			fetchSplit := strings.Split(text, " ")
			if len(fetchSplit) < 2 {
				log.Printf("malformed 'fetch' command. %q", text)
			}
			log.Printf("DEBUG: fetch sha1<%s> name<%s>", fetchSplit[1], fetchSplit[2])
			err := fetchObject(fetchSplit[1])
			if err == nil {
				log.Println("fetchObject() worked")
				//fmt.Fprintln(w, "")
				continue
			}
			log.Println("method1 failed:", err)

			err = fetchPackedObject(fetchSplit[1])
			if err == nil {
				log.Println("fetchPackedObject() worked")
				continue
			}
			log.Println("method2 failed:", err)
			os.Exit(1)

		case text == "":
			log.Println("DEBUG: got empty line (end of fetch batch?)")
			fmt.Fprintln(w, "")

		default:
			log.Printf("DEBUG: default git speak: %q\n", text)
		}
	}

	if err := scanner.Err(); err != nil {
		log.Fatalf("stdin scanner error: %s", err)
	}

	log.Println("speakGit: exited read loop")
	os.Exit(0)
}

// "fetch $sha1 $ref" method 1
//   - look for it in ".git/objects/substr($sha1, 0, 2)/substr($sha, 2)"
//   - if found, download it and put it in place. (there may be a command for this)
//   - done \o/
func fetchObject(sha1 string) error {
	p := filepath.Join(tmpBareRepo, "objects", sha1[:2], sha1[2:])
	packF, err := os.Open(p)
	if err != nil {
		if os.IsNotExist(err) {
			return err
		}
		return errgo.Notef(err, "fetchObject: sha1<%s> open() failed", sha1)
	}

	// TODO: unpack/move into GIT_DIR

	if err := packF.Close(); err != nil {
		return err
	}
	return errgo.New("fetchObject: found but more TODO")
}

// "fetch $sha1 $ref" method 2
//   - look for it in packfiles by fetching ".git/objects/pack/*.idx"
//     and looking at each idx with cat <idx> | git show-index  (alternatively can learn to read the format in go)
//   - if found in an <idx>, download the relevant .pack file,
//     and feed it into `git index-pack --stdin --fix-thin` which will put it into place.
//   - done \o/
func fetchPackedObject(sha1 string) error {
	// search for all index files
	p := filepath.Join(tmpBareRepo, "objects", "pack", "*.idx")
	indexes, err := filepath.Glob(p)
	if err != nil {
		return errgo.Notef(err, "fetchPackedObject: glob(%q) failed", p)
	}

	if len(indexes) == 0 {
		return errgo.New("fetchPackedObject: no idx files found")
	}

	for _, idx := range indexes {
		idxF, err := os.Open(idx)
		if err != nil {
			return errgo.Notef(err, "fetchPackedObject: idx<%s> open() failed", sha1)
		}
		defer idxF.Close()

		// using external git show-index < idxF for now
		// TODO: parse index file in go to make this portable
		var b bytes.Buffer
		showIdx := exec.Command("git", "show-index")
		showIdx.Stdin = idxF
		showIdx.Stdout = &b

		if err := showIdx.Run(); err != nil {
			return errgo.Notef(err, "fetchPackedObject: idx<%s> show-index start failed", sha1)
		}

		if !strings.Contains(b.String(), sha1) {
			// sha1 not in index, next idx file
			continue
		}

		if err := idxF.Close(); err != nil {
			return errgo.Notef(err, "fetchPackedObject: idx<%s> idxF.close() failed", sha1)
		}

		// we found an index with our hash inside
		pack := strings.Replace(idx, ".idx", ".pack", 1)
		packF, err := os.Open(pack)
		if err != nil {
			return errgo.Notef(err, "fetchPackedObject: pack<%s> open() failed", sha1)
		}

		b.Reset()
		unpackIdx := exec.Command("git", "unpack-objects")
		unpackIdx.Dir = thisGitRepo // GIT_DIR
		unpackIdx.Stdin = packF
		unpackIdx.Stdout = &b

		if err := unpackIdx.Run(); err != nil {
			return errgo.Notef(err, "fetchPackedObject: pack<%s> 'git unpack-objects' failed\nOutput: %s", sha1, b.String())
		}

		if err := packF.Close(); err != nil {
			return errgo.Notef(err, "fetchPackedObject: pack<%s> packF.close() failed", sha1)
		}
		// found and unpacked - done
		return nil
	}

	return errgo.Newf("did not find sha1<%s> in %d index files", sha1, len(indexes))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/minamijoyo/myaws/cmd"
)

func main() {
	if err := cmd.RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}
<commit_msg>Print stack trace on error exit<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/minamijoyo/myaws/cmd"
)

func main() {
	if err := cmd.RootCmd.Execute(); err != nil {
		fmt.Printf("%+v\n", err)
		os.Exit(-1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/wmbest2/android/adb"
	"os"
	"sync"
)

func runOnDevice(wg *sync.WaitGroup, d *adb.Device, params *[]string) {
	defer wg.Done()
	v, _ := d.ExecSync(*params...)
	fmt.Printf("%s\n", string(v))
}

func runOnAll(params []string) []byte {
	var wg sync.WaitGroup
	devices := adb.ListDevices(nil)

	if len(devices) == 0 {
		return []byte("No devices found\n")
	}

	for _, d := range devices {
		wg.Add(1)
		fmt.Printf("%s\n", d)
		go runOnDevice(&wg, d, &params)
	}
	wg.Wait()
	return []byte("")
}

func flagFromBool(f bool, s string) *string {
	result := fmt.Sprintf("-%s", s)
	if !f {
		result = ""
	}
	return &result
}

func runAndPrint(args ...string) {
    output := adb.Exec(args...)
    out_ok := true
    for {
        var v interface{}
        if !out_ok {
            break
        }
        switch v, out_ok = <-output; v.(type) {
        case []byte:
            fmt.Print(string(v.([]byte)))
        }
    }
}

func main() {

	s := flag.String("s", "", "directs command to the device or emulator with the given\nserial number or qualifier. Overrides ANDROID_SERIAL\n environment variable.")
	p := flag.String("p", "", "directs command to the device or emulator with the given\nserial number or qualifier. Overrides ANDROID_SERIAL\n environment variable.")
	a := flag.Bool("a", false, "directs adb to listen on all interfaces for a connection")
	d := flag.Bool("d", false, "directs command to the only connected USB device\nreturns an error if more than one USB device is present.")
	e := flag.Bool("e", false, "directs command to the device or emulator with the given\nserial number or qualifier. Overrides ANDROID_SERIAL\n environment variable.")
	H := flag.String("H", "", "directs command to the device or emulator with the given\nserial number or qualifier. Overrides ANDROID_SERIAL\n environment variable.")
	P := flag.String("P", "", "directs command to the device or emulator with the given\nserial number or qualifier. Overrides ANDROID_SERIAL\n environment variable.")

	flag.Parse()

	aFlag := flagFromBool(*a, "a")
	dFlag := flagFromBool(*d, "d")
	eFlag := flagFromBool(*e, "e")

	allParams := []*string{aFlag, dFlag, eFlag, p, H, P}
	params := make([]string, 0, 7)
	for _, param := range allParams {
		if *param != "" {
			params = append(params, []string{*param}...)
		}
	}

	l := len(params) + len(flag.Args())
	args := make([]string, 0, l)
	args = append(args, params...)
	args = append(args, flag.Args()...)

	var out []byte
	if *s != "" {
        runAndPrint(os.Args[1:]...)
	} else {
		switch flag.Arg(0) {
        case "install":
			out = runOnAll(args)
        case "uninstall":
			out = runOnAll(args)
        case "devices":
            fmt.Println("List of devices attached")
            devices := adb.ListDevices(nil)

            if len(devices) == 0 {
                out = []byte("No devices found\n")
            } else {
                for _, d := range devices {
                    out = append(out, []byte(fmt.Sprintln(d.String()))...)
                }
                out = append(out, []byte(fmt.Sprintln("\n"))...)
            }
        default:
            runAndPrint(flag.Args()...)
		}
	}
	fmt.Print(string(out))
}
<commit_msg>Fully native now [wip only devices properly functional]<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/wmbest2/android/adb"
	"os"
	"sync"
)

func runOnDevice(wg *sync.WaitGroup, d *adb.Device, params *[]string) {
	defer wg.Done()
	v, _ := d.Host.ShellSync(d, *params...)
	fmt.Printf("%s\n", string(v))
}

func runOnAll(params []string) []byte {
	var wg sync.WaitGroup
	devices := adb.ListDevices(nil)

	if len(devices) == 0 {
		return []byte("No devices found\n")
	}

	for _, d := range devices {
		wg.Add(1)
		fmt.Printf("%s\n", d)
		go runOnDevice(&wg, d, &params)
	}
	wg.Wait()
	return []byte("")
}

func flagFromBool(f bool, s string) *string {
	result := fmt.Sprintf("-%s", s)
	if !f {
		result = ""
	}
	return &result
}

func runAndPrint(args ...string) {
	adb := adb.Default
	output := adb.Shell(adb, args...)
	out_ok := true
	for {
		var v interface{}
		if !out_ok {
			break
		}
		switch v, out_ok = <-output; v.(type) {
		case []byte:
			fmt.Printf("%s\n", v.([]byte))
		}
	}
}

func main() {

	s := flag.String("s", "", "directs command to the device or emulator with the given\nserial number or qualifier. Overrides ANDROID_SERIAL\n environment variable.")
	p := flag.String("p", "", "directs command to the device or emulator with the given\nserial number or qualifier. Overrides ANDROID_SERIAL\n environment variable.")
	a := flag.Bool("a", false, "directs adb to listen on all interfaces for a connection")
	d := flag.Bool("d", false, "directs command to the only connected USB device\nreturns an error if more than one USB device is present.")
	e := flag.Bool("e", false, "directs command to the device or emulator with the given\nserial number or qualifier. Overrides ANDROID_SERIAL\n environment variable.")
	H := flag.String("H", "", "directs command to the device or emulator with the given\nserial number or qualifier. Overrides ANDROID_SERIAL\n environment variable.")
	P := flag.String("P", "", "directs command to the device or emulator with the given\nserial number or qualifier. Overrides ANDROID_SERIAL\n environment variable.")

	flag.Parse()

	aFlag := flagFromBool(*a, "a")
	dFlag := flagFromBool(*d, "d")
	eFlag := flagFromBool(*e, "e")

	allParams := []*string{aFlag, dFlag, eFlag, p, H, P}
	params := make([]string, 0, 7)
	for _, param := range allParams {
		if *param != "" {
			params = append(params, []string{*param}...)
		}
	}

	l := len(params) + len(flag.Args())
	args := make([]string, 0, l)
	args = append(args, params...)
	args = append(args, flag.Args()...)

	var out []byte
	if *s != "" {
		runAndPrint(os.Args[1:]...)
	} else {
		switch flag.Arg(0) {
		case "install":
			out = runOnAll(args)
		case "uninstall":
			out = runOnAll(args)
		case "devices":
			fmt.Println("List of devices attached")
			devices := adb.ListDevices(nil)

			if len(devices) == 0 {
				out = []byte("No devices found\n")
			} else {
				for _, d := range devices {
					out = append(out, []byte(fmt.Sprintln(d.String()))...)
				}
				out = append(out, []byte(fmt.Sprintln("\n"))...)
			}
		default:
			runAndPrint(flag.Args()...)
		}
	}
	fmt.Print(string(out))
}
<|endoftext|>


<commit_before>package whitegate

func main() {
	whitegate.Start()
}
<commit_msg>Restructure<commit_after>package whitegate

func main() {
	Start()
}
<|endoftext|>


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

package main

import (
	"github.com/globocom/tsuru/cmd"
	"github.com/globocom/tsuru/cmd/tsuru-base"
	"os"
)

const (
	version = "0.8.4"
	header  = "Supported-Tsuru"
)

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header)
	m.Register(&tsuru.AppRun{})
	m.Register(&tsuru.AppInfo{})
	m.Register(AppCreate{})
	m.Register(&AppRemove{})
	m.Register(&UnitAdd{})
	m.Register(&UnitRemove{})
	m.Register(tsuru.AppList{})
	m.Register(&tsuru.AppLog{})
	m.Register(&tsuru.AppGrant{})
	m.Register(&tsuru.AppRevoke{})
	m.Register(&tsuru.AppRestart{})
	m.Register(&tsuru.SetCName{})
	m.Register(&tsuru.UnsetCName{})
	m.Register(&tsuru.EnvGet{})
	m.Register(&tsuru.EnvSet{})
	m.Register(&tsuru.EnvUnset{})
	m.Register(&KeyAdd{})
	m.Register(&KeyRemove{})
	m.Register(tsuru.ServiceList{})
	m.Register(tsuru.ServiceAdd{})
	m.Register(tsuru.ServiceRemove{})
	m.Register(tsuru.ServiceDoc{})
	m.Register(tsuru.ServiceInfo{})
	m.Register(tsuru.ServiceInstanceStatus{})
	m.Register(&tsuru.ServiceBind{})
	m.Register(&tsuru.ServiceUnbind{})
	m.Register(platformList{})
	m.Register(swap{})
	return m
}

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

package main

import (
	"github.com/globocom/tsuru/cmd"
	"github.com/globocom/tsuru/cmd/tsuru-base"
	"os"
)

const (
	version = "0.8.5"
	header  = "Supported-Tsuru"
)

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header)
	m.Register(&tsuru.AppRun{})
	m.Register(&tsuru.AppInfo{})
	m.Register(AppCreate{})
	m.Register(&AppRemove{})
	m.Register(&UnitAdd{})
	m.Register(&UnitRemove{})
	m.Register(tsuru.AppList{})
	m.Register(&tsuru.AppLog{})
	m.Register(&tsuru.AppGrant{})
	m.Register(&tsuru.AppRevoke{})
	m.Register(&tsuru.AppRestart{})
	m.Register(&tsuru.SetCName{})
	m.Register(&tsuru.UnsetCName{})
	m.Register(&tsuru.EnvGet{})
	m.Register(&tsuru.EnvSet{})
	m.Register(&tsuru.EnvUnset{})
	m.Register(&KeyAdd{})
	m.Register(&KeyRemove{})
	m.Register(tsuru.ServiceList{})
	m.Register(tsuru.ServiceAdd{})
	m.Register(tsuru.ServiceRemove{})
	m.Register(tsuru.ServiceDoc{})
	m.Register(tsuru.ServiceInfo{})
	m.Register(tsuru.ServiceInstanceStatus{})
	m.Register(&tsuru.ServiceBind{})
	m.Register(&tsuru.ServiceUnbind{})
	m.Register(platformList{})
	m.Register(swap{})
	return m
}

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


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/codemodus/sigmon"
)

var (
	// slow enables a slowing of the digest function and may help users to
	// better understand the implementation of concurrency
	slow = false

	// width controls the amount of goroutines running the digest function
	width = 8
)

func main() {
	sm := sigmon.New(nil)
	sm.Run()

	// define and parse flags
	flag.BoolVar(&slow, "slow", slow, `slow processing to clarify behavior`)
	flag.IntVar(&width, "width", width, `set concurrency width`)
	flag.Parse()

	// get fileInfoGroup
	fig, err := newFileInfoGroup("./testfiles")
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	// get new conch and setup cleanup
	c := newConch(fig)

	sm.Set(func(s *sigmon.SignalMonitor) {
		close(c.doneChan())
	})

	// get fileOutput and error channels
	fos, errc := c.run()

	// print file contents or error
	for fo := range fos {
		fmt.Println(fo.path, fo.data, fo.err)
	}

	select {
	case err := <-errc:
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	default:
	}

	sm.Stop()
}
<commit_msg>Fix print comments.<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/codemodus/sigmon"
)

var (
	// slow enables a slowing of the digest function and may help users to
	// better understand the implementation of concurrency
	slow = false

	// width controls the amount of goroutines running the digest function
	width = 8
)

func main() {
	sm := sigmon.New(nil)
	sm.Run()

	// define and parse flags
	flag.BoolVar(&slow, "slow", slow, `slow processing to clarify behavior`)
	flag.IntVar(&width, "width", width, `set concurrency width`)
	flag.Parse()

	// get fileInfoGroup
	fig, err := newFileInfoGroup("./testfiles")
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	// get new conch and setup cleanup
	c := newConch(fig)

	sm.Set(func(s *sigmon.SignalMonitor) {
		close(c.doneChan())
	})

	// get fileOutput and error channels
	fos, errc := c.run()

	// print file contents
	for fo := range fos {
		fmt.Println(fo.path, fo.data, fo.err)
	}

	// print error, if any
	select {
	case err := <-errc:
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	default:
	}

	sm.Stop()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/gorilla/mux"
	"github.com/memgo/api/meetup"
	"github.com/pmylund/go-cache"
)

var c *cache.Cache

func main() {
	port := "8080"
	ip := "0.0.0.0"

	if len(os.Getenv("PORT")) > 0 {
		port = os.Getenv("PORT")
	}
	if len(os.Getenv("IP")) > 0 {
		ip = os.Getenv("IP")
	}
	c = cache.New(5*time.Minute, 30*time.Second)

	r := mux.NewRouter()
	r.Handle("/", http.RedirectHandler("/calendar.json?keyword=memphis+ruby", 302))
	r.Handle("/favicon.ico", http.NotFoundHandler())
	r.HandleFunc("/slack/meetup", slackMeetup)
	r.HandleFunc("/calendar.json", calendarJson)
	r.HandleFunc("/{meetup}", meetupRedir)
	http.Handle("/", r)

	log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%s", ip, port), nil))
}

// Handler for Slack's outgoing webhook for meetups: !meetup
func slackMeetup(w http.ResponseWriter, r *http.Request) {
	text := r.FormValue("text")
	trigger := r.FormValue("trigger_word")

	text = strings.Replace(text, trigger, "", -1)

	events := filterEventsByKeyword(text)
	var response string

	if len(events) > 0 {
		e := events[0]
		t := time.Unix(0, e.Time*int64(time.Millisecond)).In(time.Local)
		layout := "Jan 2, 2006 at 3:04pm (MST)"
		response = fmt.Sprint(e.Name, " | ", t.Format(layout), " @ ", e.Venue.Name, " | ", e.EventUrl)
	} else {
		response = "No matching meetup found."
	}

	data := struct {
		Text string `json:"text"`
	}{response}

	output, _ := json.Marshal(data)
	log.Println(string(output))
	w.Write(output)
}

// Handle redirecting to the event page for a meetup
func meetupRedir(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	keyword := string(vars["meetup"])

	events := filterEventsByKeyword(keyword)

	url := "http://www.meetup.com/memphis-technology-user-groups/"
	if len(events) > 0 {
		url = events[0].EventUrl
	}

	http.Redirect(w, r, url, 302)
}

// Return a JSON blob of matching upcoming meetups
func calendarJson(w http.ResponseWriter, r *http.Request) {
	keyword := string(r.FormValue("keyword"))

	events := filterEventsByKeyword(keyword)

	type CalendarJsonResponse struct {
		PR      string         `json:"_pull_requests_appreciated"`
		Meetups []meetup.Event `json:"meetups"`
	}

	data := CalendarJsonResponse{"https://github.com/memgo/api", events}
	marsh, _ := json.Marshal(data)
	w.Write(marsh)
}

func filterEventsByKeyword(keyword string) (results []meetup.Event) {
	keyword = strings.TrimSpace(strings.ToLower(keyword))
	r, found := c.Get(keyword)
	if !found {
		log.Println("Cache miss for [", keyword, "]")
		latest, err := getLatestEvents()
		if err != nil {
			log.Println(err)
			return results
		}

		if err != nil {
			log.Println(err)
		}

		for _, element := range latest.Results {
			if strings.Index(strings.ToLower(element.Name), keyword) > -1 {
				results = append(results, element)
			}
		}

		c.Set(keyword, results, cache.DefaultExpiration)
	} else {
		results = r.([]meetup.Event)
	}

	return results
}

func getLatestEvents() (meetup.Events, error) {
	group_id := os.Getenv("MEETUP_GROUP_ID")
	api_key := os.Getenv("MEETUP_API_KEY")
	url := fmt.Sprintf("https://api.meetup.com/2/events?group_id=%s&key=%s", group_id, api_key)
	resp, err := http.Get(url)

	events := new(meetup.Events)
	decoder := json.NewDecoder(resp.Body)
	decoder.Decode(events)

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

	return *events, nil
}
<commit_msg>adding use of envconfig<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/gorilla/mux"
	"github.com/kelseyhightower/envconfig"
	"github.com/memgo/api/meetup"
	"github.com/pmylund/go-cache"
)

type Config struct {
	Host string `default:"0.0.0.0"`
	Port string `default:"8080"`
}

var (
	c      *cache.Cache
	config Config
)

func main() {
	err := envconfig.Process("API", &config)
	if err != nil {
		log.Printf("Error processing config: %v\n", err.Error())
	}

	c = cache.New(5*time.Minute, 30*time.Second)

	r := mux.NewRouter()
	r.Handle("/", http.RedirectHandler("/calendar.json?keyword=memphis+ruby", 302))
	r.Handle("/favicon.ico", http.NotFoundHandler())
	r.HandleFunc("/slack/meetup", slackMeetup)
	r.HandleFunc("/calendar.json", calendarJson)
	r.HandleFunc("/{meetup}", meetupRedir)
	http.Handle("/", r)

	log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%s", config.Host, config.Port), nil))
}

// Handler for Slack's outgoing webhook for meetups: !meetup
func slackMeetup(w http.ResponseWriter, r *http.Request) {
	text := r.FormValue("text")
	trigger := r.FormValue("trigger_word")

	text = strings.Replace(text, trigger, "", -1)

	events := filterEventsByKeyword(text)
	var response string

	if len(events) > 0 {
		e := events[0]
		t := time.Unix(0, e.Time*int64(time.Millisecond)).In(time.Local)
		layout := "Jan 2, 2006 at 3:04pm (MST)"
		response = fmt.Sprint(e.Name, " | ", t.Format(layout), " @ ", e.Venue.Name, " | ", e.EventUrl)
	} else {
		response = "No matching meetup found."
	}

	data := struct {
		Text string `json:"text"`
	}{response}

	output, _ := json.Marshal(data)
	log.Println(string(output))
	w.Write(output)
}

// Handle redirecting to the event page for a meetup
func meetupRedir(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	keyword := string(vars["meetup"])

	events := filterEventsByKeyword(keyword)

	url := "http://www.meetup.com/memphis-technology-user-groups/"
	if len(events) > 0 {
		url = events[0].EventUrl
	}

	http.Redirect(w, r, url, 302)
}

// Return a JSON blob of matching upcoming meetups
func calendarJson(w http.ResponseWriter, r *http.Request) {
	keyword := string(r.FormValue("keyword"))

	events := filterEventsByKeyword(keyword)

	type CalendarJsonResponse struct {
		PR      string         `json:"_pull_requests_appreciated"`
		Meetups []meetup.Event `json:"meetups"`
	}

	data := CalendarJsonResponse{"https://github.com/memgo/api", events}
	marsh, _ := json.Marshal(data)
	w.Write(marsh)
}

func filterEventsByKeyword(keyword string) (results []meetup.Event) {
	keyword = strings.TrimSpace(strings.ToLower(keyword))
	r, found := c.Get(keyword)
	if !found {
		log.Println("Cache miss for [", keyword, "]")
		latest, err := getLatestEvents()
		if err != nil {
			log.Println(err)
			return results
		}

		if err != nil {
			log.Println(err)
		}

		for _, element := range latest.Results {
			if strings.Index(strings.ToLower(element.Name), keyword) > -1 {
				results = append(results, element)
			}
		}

		c.Set(keyword, results, cache.DefaultExpiration)
	} else {
		results = r.([]meetup.Event)
	}

	return results
}

func getLatestEvents() (meetup.Events, error) {
	group_id := os.Getenv("MEETUP_GROUP_ID")
	api_key := os.Getenv("MEETUP_API_KEY")
	url := fmt.Sprintf("https://api.meetup.com/2/events?group_id=%s&key=%s", group_id, api_key)
	resp, err := http.Get(url)

	events := new(meetup.Events)
	decoder := json.NewDecoder(resp.Body)
	decoder.Decode(events)

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

	return *events, nil
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"os/exec"
	"strings"

	"github.com/codegangsta/cli"
	"github.com/codegangsta/negroni"
	"github.com/davecgh/go-spew/spew"
	"github.com/gorilla/mux"
	logging "github.com/op/go-logging"
	"github.com/unrolled/render"
)

type GithubPushEventPayload struct {
	Hook struct {
		Config struct {
			Secret string `json:"secret"`
		} `json:"config"`
	} `json:"hook"`
	Repository struct {
		FullName string `json:"full_name"`
		HtmlUrl  string `json:"html_url"`
	} `json:"repository"`
}

var (
	log         = logging.MustGetLogger("streamLog")
	format      = "%{color}%{time:15:04:05} => %{color:reset} %{message}"
	buildStatus = map[string]string{}
)

func loadBuildStatus() error {
	return nil
}

func streamCommand(name string, args ...string) error {
	cmd := exec.Command(name, args...)
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}
	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			log.Notice(scanner.Text())
		}
	}()
	err = cmd.Start()
	if err != nil {
		return err
	}
	err = cmd.Wait()
	if err != nil {
		return err
	}
	return nil
}

func BuildHookReceiver(c *cli.Context, r *render.Render, dockerBinary string) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, req *http.Request) {
		var (
			payload GithubPushEventPayload
		)
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(&payload)
		if err != nil {
			fmt.Fprintln(os.Stderr, "Error decoding Github push payload:", err)
		}
		spew.Dump(payload)
		if c.String("secret") == "" || payload.Hook.Config.Secret == c.String("secret") {
			githubFullName := payload.Repository.FullName
			repoPath := fmt.Sprintf("./repos/%s", githubFullName)
			repoUrl := payload.Repository.HtmlUrl
			if _, err := os.Stat(repoPath); err != nil {
				if os.IsNotExist(err) {
					fmt.Println("Executing command", "git clone --recursive", repoUrl, repoPath)
					if err := exec.Command("git", "clone", "--recursive", repoUrl, repoPath).Run(); err != nil {
						fmt.Fprintln(os.Stderr, "Error cloning git repository:", err)
					}
				} else {
					fmt.Fprintln(os.Stderr, "Error stat-ing directory", repoPath, ":", err)
				}
				os.Chdir(repoPath)
			} else {
				os.Chdir(repoPath)
				fmt.Println("Pulling existing repository")
				if err := exec.Command("git", "pull").Run(); err != nil {
					fmt.Fprintln(os.Stderr, "Error pulling git repository:", err)
					r.JSON(w, http.StatusInternalServerError, "")
				}
			}

			namespacedImage := ""
			splitImage := strings.Split(githubFullName, "/")
			imageBase := splitImage[len(splitImage)-1]
			if c.String("hub-name") == "" {
				if c.String("alt-registry") == "" {
					namespacedImage = githubFullName
				} else {
					namespacedImage = fmt.Sprintf("%s/%s", c.String("alt-registry"), imageBase)
				}
			} else {
				namespacedImage = fmt.Sprintf("%s/%s", c.String("hub-name"), imageBase)
			}

			fmt.Println("Building docker image")
			err := streamCommand(dockerBinary, "build", "-t", namespacedImage, ".")
			if err != nil {
				fmt.Fprintln(os.Stderr, "Error building docker image for", namespacedImage, ":", err)
				r.JSON(w, http.StatusInternalServerError, map[string]interface{}{
					"Error": err,
				})
			}

			registryName := ""
			if c.String("alt-registry") != "" {
				registryName = c.String("alt-registry")
			} else {
				registryName = "Docker Hub"
			}

			fmt.Println(fmt.Sprintf("Pushing image back to specified registry (%s)...", registryName))
			err = streamCommand(dockerBinary, "push", namespacedImage)
			if err != nil {
				fmt.Fprintln(os.Stderr, "Error pushing docker image for", namespacedImage, ":", err)
				r.JSON(w, http.StatusInternalServerError, map[string]interface{}{
					"Error": err,
				})
			}
		} else {
			r.JSON(w, http.StatusInternalServerError, map[string]interface{}{
				"Error": "Secret from payload was invalid",
			})
		}
		r.JSON(w, http.StatusOK, "")
	}
}

func MakeBuildListHandler(r *render.Render) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, req *http.Request) {

	}
}

func main() {
	logBackend := logging.NewLogBackend(os.Stderr, "", 0)
	logging.SetBackend(logBackend)
	logging.SetFormatter(logging.MustStringFormatter(format))
	logging.SetLevel(logging.NOTICE, "streamLog")
	homeDir := os.Getenv("HOME")

	app := cli.NewApp()
	app.Name = "tarzan"
	app.Usage = "naive cached automated build implementation"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "p,port",
			Value: "3000",
			Usage: "port to serve tarzan on",
		},
		cli.StringFlag{
			Name:  "alt-registry",
			Value: "",
			Usage: "alternative registry to push images to instead of Docker Hub",
		},
		cli.StringFlag{
			Name:  "secret",
			Value: "",
			Usage: "secret to use when receiving webhook payload",
		},
		cli.StringFlag{
			Name:  "hub-name",
			Value: "",
			Usage: "specify a username on Docker Hub which is different than your Github handle",
		},
		cli.StringFlag{
			Name:  "docker-binary-name",
			Value: "docker",
			Usage: "specify the docker binary name (if it is not docker in $PATH)",
		},
	}

	app.Action = func(c *cli.Context) {
		dockerBinary := c.String("docker-binary-name")
		if err := loadBuildStatus(); err != nil {
			fmt.Fprintln(os.Stderr, "Error loading build status (did your repos/ dir get corrupted?):", err)
			os.Exit(1)
		}
		if _, err := os.Stat(fmt.Sprintf("%s/.dockercfg", homeDir)); err != nil {
			if os.IsNotExist(err) {
				log.Warning("Detected no Docker Hub login.  Please log in now.")
				cmd := exec.Command(dockerBinary, "login")
				cmd.Stdin = os.Stdin
				cmd.Stdout = os.Stdout
				cmd.Stderr = os.Stderr
				if err := cmd.Run(); err != nil {
					fmt.Fprintln(os.Stderr, "Error running docker login")
					os.Exit(1)
				}
			}
		}
		r := render.New(render.Options{})
		router := mux.NewRouter()
		router.HandleFunc("/build", BuildHookReceiver(c, r, dockerBinary)).Methods("POST")
		router.HandleFunc("/buildList", MakeBuildListHandler(r)).Methods("GET")

		n := negroni.Classic()
		n.Use(negroni.NewStatic(http.Dir("frontend/")))
		n.UseHandler(router)
		n.Run(fmt.Sprintf(":%s", c.String("port")))
	}

	app.Run(os.Args)
}
<commit_msg>Start to build outline of buildList response<commit_after>package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"os/exec"
	"strings"

	"github.com/codegangsta/cli"
	"github.com/codegangsta/negroni"
	"github.com/davecgh/go-spew/spew"
	"github.com/gorilla/mux"
	logging "github.com/op/go-logging"
	"github.com/unrolled/render"
)

type GithubPushEventPayload struct {
	Hook struct {
		Config struct {
			Secret string `json:"secret"`
		} `json:"config"`
	} `json:"hook"`
	Repository struct {
		FullName string `json:"full_name"`
		HtmlUrl  string `json:"html_url"`
	} `json:"repository"`
}

type Layer struct {
	Id      string
	Command string
	Size    int64
}

type AutomatedBuild struct {
	FromImage     string
	RepoName      string
	DockerfileUrl string
	Status        string
	Layers        []Layer
}

var (
	log           = logging.MustGetLogger("streamLog")
	format        = "%{color}%{time:15:04:05} => %{color:reset} %{message}"
	buildStatuses = map[string]string{}
)

func loadBuildStatus() error {
	return nil
}

func streamCommand(name string, args ...string) error {
	cmd := exec.Command(name, args...)
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}
	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			log.Notice(scanner.Text())
		}
	}()
	err = cmd.Start()
	if err != nil {
		return err
	}
	err = cmd.Wait()
	if err != nil {
		return err
	}
	return nil
}

func BuildHookReceiver(c *cli.Context, r *render.Render, dockerBinary string) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, req *http.Request) {
		var (
			payload GithubPushEventPayload
		)
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(&payload)
		if err != nil {
			fmt.Fprintln(os.Stderr, "Error decoding Github push payload:", err)
		}
		spew.Dump(payload)
		if c.String("secret") == "" || payload.Hook.Config.Secret == c.String("secret") {
			githubFullName := payload.Repository.FullName
			repoPath := fmt.Sprintf("./repos/%s", githubFullName)
			repoUrl := payload.Repository.HtmlUrl
			if _, err := os.Stat(repoPath); err != nil {
				if os.IsNotExist(err) {
					fmt.Println("Executing command", "git clone --recursive", repoUrl, repoPath)
					if err := exec.Command("git", "clone", "--recursive", repoUrl, repoPath).Run(); err != nil {
						fmt.Fprintln(os.Stderr, "Error cloning git repository:", err)
					}
				} else {
					fmt.Fprintln(os.Stderr, "Error stat-ing directory", repoPath, ":", err)
				}
				os.Chdir(repoPath)
			} else {
				os.Chdir(repoPath)
				fmt.Println("Pulling existing repository")
				if err := exec.Command("git", "pull").Run(); err != nil {
					fmt.Fprintln(os.Stderr, "Error pulling git repository:", err)
					r.JSON(w, http.StatusInternalServerError, "")
				}
			}

			namespacedImage := ""
			splitImage := strings.Split(githubFullName, "/")
			imageBase := splitImage[len(splitImage)-1]
			if c.String("hub-name") == "" {
				if c.String("alt-registry") == "" {
					namespacedImage = githubFullName
				} else {
					namespacedImage = fmt.Sprintf("%s/%s", c.String("alt-registry"), imageBase)
				}
			} else {
				namespacedImage = fmt.Sprintf("%s/%s", c.String("hub-name"), imageBase)
			}

			fmt.Println("Building docker image")
			err := streamCommand(dockerBinary, "build", "-t", namespacedImage, ".")
			if err != nil {
				fmt.Fprintln(os.Stderr, "Error building docker image for", namespacedImage, ":", err)
				r.JSON(w, http.StatusInternalServerError, map[string]interface{}{
					"Error": err,
				})
			}

			registryName := ""
			if c.String("alt-registry") != "" {
				registryName = c.String("alt-registry")
			} else {
				registryName = "Docker Hub"
			}

			fmt.Println(fmt.Sprintf("Pushing image back to specified registry (%s)...", registryName))
			err = streamCommand(dockerBinary, "push", namespacedImage)
			if err != nil {
				fmt.Fprintln(os.Stderr, "Error pushing docker image for", namespacedImage, ":", err)
				r.JSON(w, http.StatusInternalServerError, map[string]interface{}{
					"Error": err,
				})
			}
		} else {
			r.JSON(w, http.StatusInternalServerError, map[string]interface{}{
				"Error": "Secret from payload was invalid",
			})
		}
		r.JSON(w, http.StatusOK, "")
	}
}

func MakeBuildListHandler(r *render.Render) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, req *http.Request) {
		var (
			buildList = []AutomatedBuild{}
		)

		r.JSON(w, http.StatusOK, buildList)
	}
}

func main() {
	logBackend := logging.NewLogBackend(os.Stderr, "", 0)
	logging.SetBackend(logBackend)
	logging.SetFormatter(logging.MustStringFormatter(format))
	logging.SetLevel(logging.NOTICE, "streamLog")
	homeDir := os.Getenv("HOME")

	app := cli.NewApp()
	app.Name = "tarzan"
	app.Usage = "naive cached automated build implementation"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "p,port",
			Value: "3000",
			Usage: "port to serve tarzan on",
		},
		cli.StringFlag{
			Name:  "alt-registry",
			Value: "",
			Usage: "alternative registry to push images to instead of Docker Hub",
		},
		cli.StringFlag{
			Name:  "secret",
			Value: "",
			Usage: "secret to use when receiving webhook payload",
		},
		cli.StringFlag{
			Name:  "hub-name",
			Value: "",
			Usage: "specify a username on Docker Hub which is different than your Github handle",
		},
		cli.StringFlag{
			Name:  "docker-binary-name",
			Value: "docker",
			Usage: "specify the docker binary name (if it is not docker in $PATH)",
		},
	}

	app.Action = func(c *cli.Context) {
		dockerBinary := c.String("docker-binary-name")
		if err := loadBuildStatus(); err != nil {
			fmt.Fprintln(os.Stderr, "Error loading build status (did your repos/ dir get corrupted?):", err)
			os.Exit(1)
		}
		if _, err := os.Stat(fmt.Sprintf("%s/.dockercfg", homeDir)); err != nil {
			if os.IsNotExist(err) {
				log.Warning("Detected no Docker Hub login.  Please log in now.")
				cmd := exec.Command(dockerBinary, "login")
				cmd.Stdin = os.Stdin
				cmd.Stdout = os.Stdout
				cmd.Stderr = os.Stderr
				if err := cmd.Run(); err != nil {
					fmt.Fprintln(os.Stderr, "Error running docker login")
					os.Exit(1)
				}
			}
		}
		r := render.New(render.Options{})
		router := mux.NewRouter()
		router.HandleFunc("/build", BuildHookReceiver(c, r, dockerBinary)).Methods("POST")
		router.HandleFunc("/buildList", MakeBuildListHandler(r)).Methods("GET")

		n := negroni.Classic()
		n.Use(negroni.NewStatic(http.Dir("frontend/")))
		n.UseHandler(router)
		n.Run(fmt.Sprintf(":%s", c.String("port")))
	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>/*

SmartProxy is a companion for Web API developers by mocking, filtering, replaying, "diff'ing" HTTP req/responses
It may also help Web API hosting via diff'ing between API versions and taking actions when errors.

SmartProxy acts as a reverse proxy that

- maintains an history of request
- allows to inspect them
- allows to modify them : YOU take action

 *  Inspired by eBay/fabio, mitmproxy, WireMock, mashape/kong
 */
package smartproxy

import (
	"log"
	"fmt"

	"flag"
	"os"
	"os/signal"
	"strconv"
	"strings"

	"net/url"
	"net/http"

    // _ "expvar" // adds a memstats endpoint handler at /debug/vars
)

// version contains the version number
// It is set by build/release.sh for tagged releases
// so that 'go get' just works.
//
// It is also set by the linker when fabio
// is built via the Makefile or the build/docker.sh
// script to ensure the correct version nubmer
var version = "v0.2"

func main() {
	var showVersion, dumpRequest bool
	var name, port, serve, route, healthcheck string
	flag.BoolVar(&showVersion, "v", false, "show version")
	flag.BoolVar(&dumpRequest, "dump", true, "dumps ingoing and outgoing proxied traffic")
	flag.StringVar(&serve, "serve", "127.0.0.1:8080", "host or host:port of the proxied service, defaults to 127.0.0.1:8080")
	// WORKAROUND do not use absolute path (starting with /), because go runtime expands as a directory
	flag.StringVar(&route, "route", "", "relative path to the proxied service, defaults to /, on WINDOWS : do not prefix with /")
	flag.StringVar(&port, "port", "9090", "ip port of reverse proxy, defaults to 9090")
	flag.StringVar(&name, "name", "SmartProxy", "name of the service, defaults to SmartProxy")
	flag.StringVar(&healthcheck, "healthcheck", "/ping", "healthcheck path, defaults to /alive, on WINDOWS : do not prefix with /")
	flag.Parse()

	if showVersion {
		fmt.Printf("SmartProxy version %s, build undefined", version)
		return
	}

	if _, err := strconv.Atoi(port); err != nil {
		log.Fatalf("[FATAL] Invalid port: %s (%s)\n", port, err)
	}

	log.Printf("[INFO] Starting %s, version: %s", name, version)

	// start http server
	go func() {
		// register reverse proxy and specified middlewares
		endpoint := &url.URL{Scheme:"http", Host:serve}
		pattern := computeProxyPath(route)
		proxy := CreateReverseProxy(endpoint, &pattern) // *ReverseProxy
		proxyHandler := RegisterMiddleware(proxy, dumpRequest) // wrap proxy if necessary
		http.Handle(pattern, proxyHandler)

		// register health check
		ping := computeHealthcheckPath(healthcheck)
		http.HandleFunc(ping, func(w http.ResponseWriter, r *http.Request) {
			log.Printf("[INFO] Health check")
			w.Header().Set("Content-Type", "application/json; charset=utf-8")
			fmt.Fprintf(w, `{ "version":"%s", "state":"active", "name":"%s", "port":"%s", "serving":"http://%s", "via":"%s", "healthcheck":"%s"}`, version, name, port, serve, pattern, healthcheck)
		})

		// add a default route if the proxy is not registered on /
		if pattern != "/" {
			http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
				log.Printf("[INFO] No route registered for %s", r.RequestURI)
				w.Header().Set("Content-Type", "application/json; charset=utf-8")
				w.WriteHeader(http.StatusNotFound)
				fmt.Fprint(w, `{ "state":"error", "description":"nothing here" }`)
			})
		}

		log.Printf("[INFO] Listening on http://localhost:%s\n", port)
		log.Printf("[INFO] Serving http://%s via path %s\n", serve, pattern)
		if err := http.ListenAndServe(":" + port, nil); err != nil {
			log.Fatal("[FATAL] ",err)
		}
	}()

	// run until we get a signal
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, os.Interrupt, os.Kill)
	<-quit
}

func computeProxyPath(route string) string {
	// Ensure a leading and ending / to the route
	//    - leading / is due to an issue on windows with Args, which requires to pass the route arg as relative (no leading /)
	//           see https://golang.org/src/os/proc.go, line 19
	//           see https://golang.org/src/syscall/exec_windows.go, line 156
	//    - ending / is required to serve all traffic to the proxy /route, /route/ and /route/*, and not only the /route URL
	pattern := route
	if !(strings.HasPrefix(pattern, "/")) {
		pattern = "/" + pattern
	}
	if !(strings.HasSuffix(pattern, "/")) {
		pattern = pattern + "/"
	}
	return pattern
}

func computeHealthcheckPath(route string) string {
	// Ensure a leading / to the route
	pattern := route
	if !(strings.HasPrefix(pattern, "/")) {
		pattern = "/" + pattern
	}
	return pattern
}

<commit_msg>fixed dump flag<commit_after>/*

SmartProxy is a companion for Web API developers by mocking, filtering, replaying, "diff'ing" HTTP req/responses
It may also help Web API hosting via diff'ing between API versions and taking actions when errors.

SmartProxy acts as a reverse proxy that

- maintains an history of request
- allows to inspect them
- allows to modify them : YOU take action

 *  Inspired by eBay/fabio, mitmproxy, WireMock, mashape/kong
 */
package main

import (
	"log"
	"fmt"

	"flag"
	"os"
	"os/signal"
	"strconv"
	"strings"

	"net/url"
	"net/http"

    // _ "expvar" // adds a memstats endpoint handler at /debug/vars
)

// version contains the version number
// It is set by build/release.sh for tagged releases
// so that 'go get' just works.
//
// It is also set by the linker when fabio
// is built via the Makefile or the build/docker.sh
// script to ensure the correct version nubmer
var version = "v0.2"

func main() {
	var showVersion, dumpRequest bool
	var name, port, serve, route, healthcheck string
	flag.BoolVar(&showVersion, "v", false, "show version")
	flag.BoolVar(&dumpRequest, "dump", false, "dumps ingoing and outgoing proxied traffic")
	flag.StringVar(&serve, "serve", "127.0.0.1:8080", "host or host:port of the proxied service, defaults to 127.0.0.1:8080")
	// WORKAROUND do not use absolute path (starting with /), because go runtime expands as a directory
	flag.StringVar(&route, "route", "", "relative path to the proxied service, defaults to /, on WINDOWS : do not prefix with /")
	flag.StringVar(&port, "port", "9090", "ip port of reverse proxy, defaults to 9090")
	flag.StringVar(&name, "name", "SmartProxy", "name of the service, defaults to SmartProxy")
	flag.StringVar(&healthcheck, "healthcheck", "/ping", "healthcheck path, defaults to /alive, on WINDOWS : do not prefix with /")
	flag.Parse()

	if showVersion {
		fmt.Printf("SmartProxy version %s", version)
		return
	}

	if _, err := strconv.Atoi(port); err != nil {
		log.Fatalf("[FATAL] Invalid port: %s (%s)\n", port, err)
	}

	log.Printf("[INFO] Starting %s, version: %s", name, version)

	// start http server
	go func() {
		// register reverse proxy and specified middlewares
		endpoint := &url.URL{Scheme:"http", Host:serve}
		pattern := computeProxyPath(route)
		proxy := CreateReverseProxy(endpoint, &pattern) // *ReverseProxy
		proxyHandler := RegisterMiddleware(proxy, dumpRequest) // wrap proxy if necessary
		http.Handle(pattern, proxyHandler)

		// register health check
		ping := computeHealthcheckPath(healthcheck)
		http.HandleFunc(ping, func(w http.ResponseWriter, r *http.Request) {
			log.Printf("[INFO] Health check")
			w.Header().Set("Content-Type", "application/json; charset=utf-8")
			fmt.Fprintf(w, `{ "version":"%s", "state":"active", "name":"%s", "port":"%s", "serving":"http://%s", "via":"%s", "healthcheck":"%s"}`, version, name, port, serve, pattern, healthcheck)
		})

		// add a default route if the proxy is not registered on /
		if pattern != "/" {
			http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
				log.Printf("[INFO] No route registered for %s", r.RequestURI)
				w.Header().Set("Content-Type", "application/json; charset=utf-8")
				w.WriteHeader(http.StatusNotFound)
				fmt.Fprint(w, `{ "state":"error", "description":"nothing here" }`)
			})
		}

		log.Printf("[INFO] Listening on http://localhost:%s\n", port)
		log.Printf("[INFO] Serving http://%s via path %s\n", serve, pattern)
		if err := http.ListenAndServe(":" + port, nil); err != nil {
			log.Fatal("[FATAL] ",err)
		}
	}()

	// run until we get a signal
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, os.Interrupt, os.Kill)
	<-quit
}

func computeProxyPath(route string) string {
	// Ensure a leading and ending / to the route
	//    - leading / is due to an issue on windows with Args, which requires to pass the route arg as relative (no leading /)
	//           see https://golang.org/src/os/proc.go, line 19
	//           see https://golang.org/src/syscall/exec_windows.go, line 156
	//    - ending / is required to serve all traffic to the proxy /route, /route/ and /route/*, and not only the /route URL
	pattern := route
	if !(strings.HasPrefix(pattern, "/")) {
		pattern = "/" + pattern
	}
	if !(strings.HasSuffix(pattern, "/")) {
		pattern = pattern + "/"
	}
	return pattern
}

func computeHealthcheckPath(route string) string {
	// Ensure a leading / to the route
	pattern := route
	if !(strings.HasPrefix(pattern, "/")) {
		pattern = "/" + pattern
	}
	return pattern
}

<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"strconv"

	"github.com/BurntSushi/toml"
	htr "github.com/julienschmidt/httprouter"
	"github.com/mailgun/mailgun-go"
)

var (
	config = flag.String("config", "config.toml", "The config to use")

	domain   = flag.String("domain", "", "The domain to send from")
	mgAPIKey = flag.String("api-key", "", "The API key to use")
	pbAPIKey = flag.String("pub-key", "", "The public API key to use")
	sendTo   = flag.String("send-to", "", "The email address to send to")
	sender   = flag.String("sender", "", "The email address to send from")
	subject  = flag.String("subject", "Registration", "Subject")

	port = flag.Int("port", 24000, "The port to listen on")
)

type Config struct {
	Domain  string `toml:"domain"`
	APIKey  string `toml:"api-key"`
	PubKey  string `toml:"pub-key"`
	SendTo  string `toml:"send-to"`
	Sender  string `toml:"sender"`
	Subject string `toml:"subject"`
	Port    int    `toml:"port"`
}

func main() {
	flag.Parse()

	conf, err := getConfig(*config)
	if err != nil {
		panic(err)
	}

	m := mailer(
		conf.Domain,
		conf.APIKey,
		conf.PubKey,
		conf.Subject,
		conf.SendTo,
		conf.Sender,
	)
	r := htr.New()
	r.POST("/register/:email", wrap(m, "email"))

	log.Printf("Simple Reg listening on port :%d\n", conf.Port)
	panic(http.ListenAndServe(":"+strconv.Itoa(conf.Port), r))
}

func wrap(f func(string) error, key string) htr.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps htr.Params) {
		if err := f(ps.ByName(key)); err != nil {
			http.Error(w, err.Error(), 500)
		} else {
			w.WriteHeader(http.StatusOK)
		}
	}
}

func getConfig(which string) (*Config, error) {
	var conf Config
	if which != "" {
		if _, err := toml.DecodeFile(which, &conf); err != nil {
			return nil, fmt.Errorf("failed to parse config %s: %v", which, err)
		}
	}
	for k, v := range map[string]struct {
		f  string
		cf *string
	}{
		"domain":  {f: *domain, cf: &(conf.Domain)},
		"api-key": {f: *mgAPIKey, cf: &(conf.APIKey)},
		"pub-key": {f: *pbAPIKey, cf: &(conf.PubKey)},
		"send-to": {f: *sendTo, cf: &(conf.SendTo)},
		"sender":  {f: *sender, cf: &(conf.Sender)},
	} {
		switch {
		case v.f == "" && *(v.cf) == "":
			return nil, fmt.Errorf("must define a value for flag %s", k)
		case *v.cf == "":
			*v.cf = v.f
		}
	}
	if *port != 0 {
		conf.Port = *port
	}

	return &conf, nil
}

func mailer(domain, apiKey, pubKey, sub, to, from string) func(string) error {
	mg := mailgun.NewMailgun(
		domain,
		apiKey,
		pubKey,
	)

	return func(email string) error {
		m := mg.NewMessage(
			// From
			"Registration <"+from+">",
			// Subject
			sub,
			// Plain-text body
			email,
		)

		if err := m.AddRecipient(to); err != nil {
			log.Printf("failed to add recipient %q: %v", to, err)
			return err
		}

		if _, _, err := mg.Send(m); err != nil {
			log.Printf("failed to send to recipient %q: %v", to, err)
			return err
		}

		log.Printf("registered user %q OK", email)

		return nil
	}
}
<commit_msg>Add CORS with options<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"strconv"

	"github.com/BurntSushi/toml"
	htr "github.com/julienschmidt/httprouter"
	"github.com/mailgun/mailgun-go"
	"github.com/rs/cors"
)

var (
	config = flag.String("config", "config.toml", "The config to use")

	domain   = flag.String("domain", "", "The domain to send from")
	mgAPIKey = flag.String("api-key", "", "The API key to use")
	pbAPIKey = flag.String("pub-key", "", "The public API key to use")
	sendTo   = flag.String("send-to", "", "The email address to send to")
	sender   = flag.String("sender", "", "The email address to send from")
	subject  = flag.String("subject", "Registration", "Subject")
	origin   = flag.String("origin", "", "Allow CORS origin")

	port = flag.Int("port", 24000, "The port to listen on")
)

type Config struct {
	Domain  string   `toml:"domain"`
	APIKey  string   `toml:"api-key"`
	PubKey  string   `toml:"pub-key"`
	SendTo  string   `toml:"send-to"`
	Sender  string   `toml:"sender"`
	Subject string   `toml:"subject"`
	Origins []string `toml:"origins"`
	Port    int      `toml:"port"`
}

func main() {
	flag.Parse()

	conf, err := getConfig(*config)
	if err != nil {
		panic(err)
	}

	m := mailer(
		conf.Domain,
		conf.APIKey,
		conf.PubKey,
		conf.Subject,
		conf.SendTo,
		conf.Sender,
	)
	r := htr.New()
	r.POST("/register/:email", wrap(m, "email"))
	rCORS := cors.New(cors.Options{
		AllowedOrigins:   conf.Origins,
		AllowedMethods:   []string{"POST"},
		AllowCredentials: true,
	}).Handler(r)

	log.Printf("Simple Reg listening on port :%d\n", conf.Port)
	panic(http.ListenAndServe(":"+strconv.Itoa(conf.Port), rCORS))
}

func wrap(f func(string) error, key string) htr.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps htr.Params) {
		if err := f(ps.ByName(key)); err != nil {
			http.Error(w, err.Error(), 500)
		} else {
			w.WriteHeader(http.StatusOK)
		}
	}
}

func getConfig(which string) (*Config, error) {
	var conf Config
	if which != "" {
		if _, err := toml.DecodeFile(which, &conf); err != nil {
			return nil, fmt.Errorf("failed to parse config %s: %v", which, err)
		}
	}
	for k, v := range map[string]struct {
		f  string
		cf *string
	}{
		"domain":  {f: *domain, cf: &(conf.Domain)},
		"api-key": {f: *mgAPIKey, cf: &(conf.APIKey)},
		"pub-key": {f: *pbAPIKey, cf: &(conf.PubKey)},
		"send-to": {f: *sendTo, cf: &(conf.SendTo)},
		"sender":  {f: *sender, cf: &(conf.Sender)},
	} {
		switch {
		case v.f == "" && *(v.cf) == "":
			return nil, fmt.Errorf("must define a value for flag %s", k)
		case *v.cf == "":
			*v.cf = v.f
		}
	}
	if *port != 0 {
		conf.Port = *port
	}
	switch {
	case *origin == "" && conf.Origins == nil:
		conf.Origins = []string{"*"}
	case *origin != "":
		conf.Origins = []string{*origin}
	}

	return &conf, nil
}

func mailer(domain, apiKey, pubKey, sub, to, from string) func(string) error {
	mg := mailgun.NewMailgun(
		domain,
		apiKey,
		pubKey,
	)

	return func(email string) error {
		m := mg.NewMessage(
			// From
			"Registration <"+from+">",
			// Subject
			sub,
			// Plain-text body
			email,
		)

		if err := m.AddRecipient(to); err != nil {
			log.Printf("failed to add recipient %q: %v", to, err)
			return err
		}

		if _, _, err := mg.Send(m); err != nil {
			log.Printf("failed to send to recipient %q: %v", to, err)
			return err
		}

		log.Printf("registered user %q OK", email)

		return nil
	}
}
<|endoftext|>


<commit_before>package main

import (
    "log"
    "math/rand"
    "time"
)

func main() {
    log.Print("started.")

    // チャネル
    sleep1_finished := make(chan bool)

    go func() {
        // 0.2秒かかるコマンド
        log.Print("sleep1 started.")
        time.Sleep(200 * 1000 * 1000 * time.Nanosecond)
        log.Print("sleep1 finished.")
        sleep1_finished <- true
    }()

    // 終わるまで待つ
    <- sleep1_finished

    dice()
}

func dice() {
    log.Printf("%v", random())
}

// http://qiita.com/cubicdaiya/items/819886c57e9d17e4b019
// 34枚の内からランダムに1枚返す
func random()(string) {
    a := 126976 // ton
    rand.Seed(time.Now().UnixNano())
    return string(a + rand.Intn(34))
}
<commit_msg>Update<commit_after>package main

import (
    "log"
    "math/rand"
    "time"
)

func main() {
    log.Print("started.")

    // チャネル
    sleep1_finished := make(chan bool)

    go func() {
        // 0.2秒かかるコマンド
        log.Print("sleep1 started.")
        time.Sleep(200 * 1000 * 1000 * time.Nanosecond)
        log.Print("sleep1 finished.")
        sleep1_finished <- true
    }()

    // 終わるまで待つ
    <- sleep1_finished

    dice()
}

func dice() {
    log.Printf("%v", string(random()))
}

// http://qiita.com/cubicdaiya/items/819886c57e9d17e4b019
// 34枚の内からランダムに1枚返す
func random()(int) {
    a := 126976 // ton https://codepoints.net/U+1F000
    rand.Seed(time.Now().UnixNano())
    return a + rand.Intn(34)
}
<|endoftext|>


<commit_before>package main

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

import (
	"github.com/alfredxing/calc/compute"
)

import (
	"golang.org/x/crypto/ssh/terminal"
)

// Stores the state of the terminal before making it raw
var regularState *terminal.State

func main() {
	if len(os.Args) > 1 {
		input := strings.Replace(strings.Join(os.Args[1:], ""), " ", "", -1)
		res, err := compute.Evaluate(input)
		if err != nil {
			fmt.Println("Error: " + err.Error())
			return
		}
		fmt.Printf("%s\n", strconv.FormatFloat(res, 'G', -1, 64))
		return
	}

	var err error
	regularState, err = terminal.MakeRaw(0)
	if err != nil {
		panic(err)
	}
	defer terminal.Restore(0, regularState)

	term := terminal.NewTerminal(os.Stdin, "> ")
	term.AutoCompleteCallback = handleKey
	for {
		text, err := term.ReadLine()
		if err != nil {
			if err == io.EOF {
				// Quit without error on Ctrl^D
				fmt.Println()
				break
			}
			panic(err)
		}

		text = strings.Replace(text, " ", "", -1)
		if text == "exit" || text == "quit" {
			break
		}

		res, err := compute.Evaluate(text)
		if err != nil {
			fmt.Println("Error: " + err.Error())
			continue
		}
		fmt.Printf("%s\n", strconv.FormatFloat(res, 'G', -1, 64))
	}
}

func handleKey(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
	if key == '\x03' {
		fmt.Println()
		terminal.Restore(0, regularState)
		os.Exit(0)
	}
	return "", 0, false
}
<commit_msg>Use term.Write() to write to console<commit_after>package main

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

import (
	"github.com/alfredxing/calc/compute"
)

import (
	"golang.org/x/crypto/ssh/terminal"
)

// Stores the state of the terminal before making it raw
var regularState *terminal.State

func main() {
	if len(os.Args) > 1 {
		input := strings.Replace(strings.Join(os.Args[1:], ""), " ", "", -1)
		res, err := compute.Evaluate(input)
		if err != nil {
			fmt.Println("Error: " + err.Error())
			return
		}
		fmt.Printf("%s\n", strconv.FormatFloat(res, 'G', -1, 64))
		return
	}

	var err error
	regularState, err = terminal.MakeRaw(0)
	if err != nil {
		panic(err)
	}
	defer terminal.Restore(0, regularState)

	term := terminal.NewTerminal(os.Stdin, "> ")
	term.AutoCompleteCallback = handleKey
	for {
		text, err := term.ReadLine()
		if err != nil {
			if err == io.EOF {
				// Quit without error on Ctrl^D
				fmt.Println()
				break
			}
			panic(err)
		}

		text = strings.Replace(text, " ", "", -1)
		if text == "exit" || text == "quit" {
			break
		}

		res, err := compute.Evaluate(text)
		if err != nil {
			fmt.Println("Error: " + err.Error())
			continue
		}
		term.Write([]byte(fmt.Sprintf("%s\n", strconv.FormatFloat(res, 'G', -1, 64))))
	}
}

func handleKey(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
	if key == '\x03' {
		fmt.Println()
		terminal.Restore(0, regularState)
		os.Exit(0)
	}
	return "", 0, false
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"

	"gopkg.in/urfave/cli.v1"
	"github.com/codegangsta/envy/lib"
	"github.com/codegangsta/gin/lib"

	"log"
	"os"
	"os/signal"
	"path/filepath"
	"strconv"
	"syscall"
	"time"
)

var (
	startTime  = time.Now()
	logger     = log.New(os.Stdout, "[gin] ", 0)
	immediate  = false
	buildError error
)

func main() {
	app := cli.NewApp()
	app.Name = "gin"
	app.Usage = "A live reload utility for Go web applications."
	app.Action = MainAction
	app.Flags = []cli.Flag{
		cli.IntFlag{
			Name:  "port,p",
			Value: 3000,
			Usage: "port for the proxy server",
		},
		cli.IntFlag{
			Name:  "appPort,a",
			Value: 3001,
			Usage: "port for the Go web server",
		},
		cli.StringFlag{
			Name:  "bin,b",
			Value: "gin-bin",
			Usage: "name of generated binary file",
		},
		cli.StringFlag{
			Name:  "path,t",
			Value: ".",
			Usage: "Path to watch files from",
		},
		cli.BoolFlag{
			Name:  "immediate,i",
			Usage: "run the server immediately after it's built",
		},
		cli.BoolFlag{
			Name:  "godep,g",
			Usage: "use godep when building",
		},
	}
	app.Commands = []cli.Command{
		{
			Name:      "run",
			ShortName: "r",
			Usage:     "Run the gin proxy in the current working directory",
			Action:    MainAction,
		},
		{
			Name:      "env",
			ShortName: "e",
			Usage:     "Display environment variables set by the .env file",
			Action:    EnvAction,
		},
	}

	app.Run(os.Args)
}

func MainAction(c *cli.Context) {
	port := c.GlobalInt("port")
	appPort := strconv.Itoa(c.GlobalInt("appPort"))
	immediate = c.GlobalBool("immediate")

	// Bootstrap the environment
	envy.Bootstrap()

	// Set the PORT env
	os.Setenv("PORT", appPort)

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

	builder := gin.NewBuilder(c.GlobalString("path"), c.GlobalString("bin"), c.GlobalBool("godep"))
	runner := gin.NewRunner(filepath.Join(wd, builder.Binary()), c.Args()...)
	runner.SetWriter(os.Stdout)
	proxy := gin.NewProxy(builder, runner)

	config := &gin.Config{
		Port:    port,
		ProxyTo: "http://localhost:" + appPort,
	}

	err = proxy.Run(config)
	if err != nil {
		logger.Fatal(err)
	}

	logger.Printf("listening on port %d\n", port)

	shutdown(runner)

	// build right now
	build(builder, runner, logger)

	// scan for changes
	scanChanges(c.GlobalString("path"), func(path string) {
		runner.Kill()
		build(builder, runner, logger)
	})
}

func EnvAction(c *cli.Context) {
	// Bootstrap the environment
	env, err := envy.Bootstrap()
	if err != nil {
		logger.Fatalln(err)
	}

	for k, v := range env {
		fmt.Printf("%s: %s\n", k, v)
	}

}

func build(builder gin.Builder, runner gin.Runner, logger *log.Logger) {
	err := builder.Build()
	if err != nil {
		buildError = err
		logger.Println("ERROR! Build failed.")
		fmt.Println(builder.Errors())
	} else {
		// print success only if there were errors before
		if buildError != nil {
			logger.Println("Build Successful")
		}
		buildError = nil
		if immediate {
			runner.Run()
		}
	}

	time.Sleep(100 * time.Millisecond)
}

type scanCallback func(path string)

func scanChanges(watchPath string, cb scanCallback) {
	for {
		filepath.Walk(watchPath, func(path string, info os.FileInfo, err error) error {
			if path == ".git" {
				return filepath.SkipDir
			}

			// ignore hidden files
			if filepath.Base(path)[0] == '.' {
				return nil
			}

			if filepath.Ext(path) == ".go" && info.ModTime().After(startTime) {
				cb(path)
				startTime = time.Now()
				return errors.New("done")
			}

			return nil
		})
		time.Sleep(500 * time.Millisecond)
	}
}

func shutdown(runner gin.Runner) {
	c := make(chan os.Signal, 2)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		s := <-c
		log.Println("Got signal: ", s)
		err := runner.Kill()
		if err != nil {
			log.Print("Error killing: ", err)
		}
		os.Exit(1)
	}()
}
<commit_msg>Added colors for build messages<commit_after>package main

import (
	"errors"
	"fmt"

	"gopkg.in/urfave/cli.v1"
	"github.com/codegangsta/envy/lib"
	"github.com/codegangsta/gin/lib"

	"log"
	"os"
	"os/signal"
	"path/filepath"
	"strconv"
	"syscall"
	"time"
)

var (
	startTime  = time.Now()
	logger     = log.New(os.Stdout, "[gin] ", 0)
	immediate  = false
	buildError error
	colorGreen = string([]byte{27, 91, 57, 55, 59, 51, 50, 59, 49, 109})
	colorRed   = string([]byte{27, 91, 57, 55, 59, 51, 49, 59, 49, 109})
	colorReset = string([]byte{27, 91, 48, 109})
)

func main() {
	app := cli.NewApp()
	app.Name = "gin"
	app.Usage = "A live reload utility for Go web applications."
	app.Action = MainAction
	app.Flags = []cli.Flag{
		cli.IntFlag{
			Name:  "port,p",
			Value: 3000,
			Usage: "port for the proxy server",
		},
		cli.IntFlag{
			Name:  "appPort,a",
			Value: 3001,
			Usage: "port for the Go web server",
		},
		cli.StringFlag{
			Name:  "bin,b",
			Value: "gin-bin",
			Usage: "name of generated binary file",
		},
		cli.StringFlag{
			Name:  "path,t",
			Value: ".",
			Usage: "Path to watch files from",
		},
		cli.BoolFlag{
			Name:  "immediate,i",
			Usage: "run the server immediately after it's built",
		},
		cli.BoolFlag{
			Name:  "godep,g",
			Usage: "use godep when building",
		},
	}
	app.Commands = []cli.Command{
		{
			Name:      "run",
			ShortName: "r",
			Usage:     "Run the gin proxy in the current working directory",
			Action:    MainAction,
		},
		{
			Name:      "env",
			ShortName: "e",
			Usage:     "Display environment variables set by the .env file",
			Action:    EnvAction,
		},
	}

	app.Run(os.Args)
}

func MainAction(c *cli.Context) {
	port := c.GlobalInt("port")
	appPort := strconv.Itoa(c.GlobalInt("appPort"))
	immediate = c.GlobalBool("immediate")

	// Bootstrap the environment
	envy.Bootstrap()

	// Set the PORT env
	os.Setenv("PORT", appPort)

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

	builder := gin.NewBuilder(c.GlobalString("path"), c.GlobalString("bin"), c.GlobalBool("godep"))
	runner := gin.NewRunner(filepath.Join(wd, builder.Binary()), c.Args()...)
	runner.SetWriter(os.Stdout)
	proxy := gin.NewProxy(builder, runner)

	config := &gin.Config{
		Port:    port,
		ProxyTo: "http://localhost:" + appPort,
	}

	err = proxy.Run(config)
	if err != nil {
		logger.Fatal(err)
	}

	logger.Printf("listening on port %d\n", port)

	shutdown(runner)

	// build right now
	build(builder, runner, logger)

	// scan for changes
	scanChanges(c.GlobalString("path"), func(path string) {
		runner.Kill()
		build(builder, runner, logger)
	})
}

func EnvAction(c *cli.Context) {
	// Bootstrap the environment
	env, err := envy.Bootstrap()
	if err != nil {
		logger.Fatalln(err)
	}

	for k, v := range env {
		fmt.Printf("%s: %s\n", k, v)
	}

}

func build(builder gin.Builder, runner gin.Runner, logger *log.Logger) {
	err := builder.Build()
	if err != nil {
		buildError = err
		logger.Printf("%sERROR! Build failed.%s\n", colorRed, colorReset)
		fmt.Println(builder.Errors())
	} else {
		// print success only if there were errors before
		if buildError != nil {
			logger.Printf("%sBuild Successful%s\n", colorGreen, colorReset)
		}
		buildError = nil
		if immediate {
			runner.Run()
		}
	}

	time.Sleep(100 * time.Millisecond)
}

type scanCallback func(path string)

func scanChanges(watchPath string, cb scanCallback) {
	for {
		filepath.Walk(watchPath, func(path string, info os.FileInfo, err error) error {
			if path == ".git" {
				return filepath.SkipDir
			}

			// ignore hidden files
			if filepath.Base(path)[0] == '.' {
				return nil
			}

			if filepath.Ext(path) == ".go" && info.ModTime().After(startTime) {
				cb(path)
				startTime = time.Now()
				return errors.New("done")
			}

			return nil
		})
		time.Sleep(500 * time.Millisecond)
	}
}

func shutdown(runner gin.Runner) {
	c := make(chan os.Signal, 2)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		s := <-c
		log.Println("Got signal: ", s)
		err := runner.Kill()
		if err != nil {
			log.Print("Error killing: ", err)
		}
		os.Exit(1)
	}()
}
<|endoftext|>