<commit_before>package main

import (
	"fmt"
	"golang.org/x/net/html"
	"log"
	"net/http"
	"net/url"
	"os"
	"os/signal"
)

type Page struct {
	Url   *url.URL
	Next  *Page
}

func (page *Page) IsMatch(opage *Page) bool {
	return page.Url.String() == opage.Url.String()
}

// Gets the first link of a wikipedia page.
func (page *Page) FollowLink(acceptFunc func(ur *url.URL) bool) (*Page, error) {
	resp, err := http.Get(page.Url.String())
	if err != nil {
		return page, err
	}

	body := resp.Body
	defer body.Close()

	z := html.NewTokenizer(body)
	inBody := false
	inP := false
	depth := 0
	for {
		tt := z.Next()
		switch tt {
		case html.ErrorToken:
			return page, z.Err()
		case html.StartTagToken, html.EndTagToken:
			tn, _ := z.TagName()
			if string(tn) == "div" {
				if tt == html.StartTagToken {
					if inBody {
						// Descend into an inner div
						depth++
					} else {
						// This is a div tag
						// Wikipedia puts the main section of the article
						// within a div tag with the id "mw-content-text"
						// Loop through attributes for an id
						more := true
						for more {
							key, val, m := z.TagAttr()
							more = m
							if string(key) == "id" && string(val) == "mw-content-text" {
								inBody = true
							}
						}
					}
				} else {
					if depth == 0 {
						inBody = false
					}
				}
			} else if inBody && string(tn) == "p" {
				if tt == html.StartTagToken {
					inP = true
				} else {
					inP = false
				}
			} else if inP && tt == html.StartTagToken && string(tn) == "a" {
				// This is an anchor tag
				// This is an anchor tag in a div
				// Check if it has an href attribute
				more := true
				for more {
					key, val, m := z.TagAttr()
					more = m
					if string(key) == "href" {
						// Parse URL
						ur, err := page.Url.Parse(string(val))
						if err != nil {
							// If this url is not parseable,
							// skip to the second url
							break
						}

						if acceptFunc(ur) {
							p := &Page{Url: ur}
							page.Next = p
							return p, nil
						}
					}
				}
			}
		}
	}
}

func main() {
	haveVisited := make(map[url.URL]Page)
	visits := 0

	prefix := "http://en.wikipedia.org/wiki/"

	var targetPage *Page
	var startPage *Page

	if len(os.Args) == 3 {
		ur, err := url.Parse(prefix+os.Args[1])
		if err != nil {
			log.Fatal(err)
		}

		targetPage = &Page{Url: ur}

		ur, err = url.Parse(prefix+os.Args[2])
		if err != nil {
			log.Fatal(err)
		}

		// Initial page to start crawler
		startPage = &Page{Url: ur}
	} else {
		fmt.Println("Needs url to start crawler")
		return
	}

	done := make(chan bool)
	go func () {
		page := startPage
		for {
			pg, err := page.FollowLink(func(ur *url.URL) bool {
				// Don't Revisit pages
				p := haveVisited[*ur]
				if p.Url != nil {
					return false
				}

				// Don't leave the world of Wikipedia
				if len(ur.String()) < len(prefix) || ur.String()[:len(prefix)] != prefix {
					return false
				}
				return true
			})
			if err != nil {
				if err.Error() == "EOF" {
					// Could not find a link on this file,
					// Go back up one page
					lp := startPage
					p := startPage
					for p.Next != nil {
						lp = p
						p = p.Next
					}
					if (lp == startPage) {
						log.Fatal("Cannot find links on provided page")
					}
					page = lp
					visits--
					continue
				}
				log.Fatal(err)
			}
			page = pg

			fmt.Printf("Have Followed %d links\r", visits)

			haveVisited[*page.Url] = *page
			visits++

			if page.IsMatch(targetPage) {
				fmt.Printf("Found match, took %d follows\n", visits)
				break
			}
		}
		done <- true
	}()

	sig := make(chan os.Signal)
	signal.Notify(sig, os.Interrupt)

	// Wait for successful path or sigint
	select {
	case <-done:
	case <-sig:
	}

	// Print path
	page := startPage
	i := 0
	for page != nil {
		fmt.Printf("%d: %s\n", i, page.Url)
		page = page.Next
		i++
	}
}
<commit_msg>configability<commit_after>package main

import (
	"fmt"
	"golang.org/x/net/html"
	"log"
	"net/http"
	"net/url"
	"os"
	"os/signal"
	"strings"
)

// Wikipedia puts the main section of the article
// within a div tag with the id "mw-content-text"
// Loop through attributes for an id
var divId string = "mw-content-text"

type Page struct {
	Url   *url.URL
	Next  *Page
}

func (page *Page) IsMatch(opage *Page) bool {
	return page.Url.String() == opage.Url.String()
}

// Gets the first link of a wikipedia page.
func (page *Page) FollowLink(acceptFunc func(ur *url.URL) bool) (*Page, error) {
	resp, err := http.Get(page.Url.String())
	if err != nil {
		return page, err
	}

	body := resp.Body
	defer body.Close()

	z := html.NewTokenizer(body)
	inBody := false
	inP := 0
	depth := 0
	for {
		tt := z.Next()
		switch tt {
		case html.ErrorToken:
			return page, z.Err()
		case html.StartTagToken, html.EndTagToken:
			tn, _ := z.TagName()
			if string(tn) == "div" {
				if tt == html.StartTagToken {
					if inBody {
						// Descend into an inner div
						depth++
					} else {
						// This is a div tag
						more := true
						for more {
							key, val, m := z.TagAttr()
							more = m
							if string(key) == "id" && string(val) == divId {
								inBody = true
							}
						}
					}
				} else {
					if depth == 0 {
						inBody = false
					}
				}
			} else if inBody && string(tn) == "p" {
				if tt == html.StartTagToken {
					inP++
				} else {
					inP--
				}
			} else if inP > 0 && tt == html.StartTagToken && string(tn) == "a" {
				// This is an anchor tag
				// This is an anchor tag in a div
				// Check if it has an href attribute
				more := true
				for more {
					key, val, m := z.TagAttr()
					more = m
					if string(key) == "href" {
						// Parse URL
						ur, err := page.Url.Parse(string(val))
						if err != nil {
							// If this url is not parseable,
							// skip to the second url
							break
						}

						if acceptFunc(ur) {
							p := &Page{Url: ur}
							page.Next = p
							return p, nil
						}
					}
				}
			}
		}
	}
}

func main() {
	haveVisited := make(map[url.URL]Page)
	visits := 0

	prefix := "http://en.wikipedia.org/wiki/"

	var targetPage *Page
	var startPage *Page

	if len(os.Args) == 3 {
		ur, err := url.Parse(prefix+os.Args[1])
		if err != nil {
			log.Fatal(err)
		}

		targetPage = &Page{Url: ur}

		ur, err = url.Parse(prefix+os.Args[2])
		if err != nil {
			log.Fatal(err)
		}

		// Initial page to start crawler
		startPage = &Page{Url: ur}
	} else {
		fmt.Println("Needs url to start crawler")
		return
	}

	done := make(chan bool)
	go func () {
		page := startPage
		for {
			pg, err := page.FollowLink(func(ur *url.URL) bool {
				// Don't Revisit pages
				p := haveVisited[*ur]
				if p.Url != nil {
					return false
				}

				// Don't leave the world of Wikipedia
				if !strings.HasPrefix(ur.String(), prefix) {
					return false
				}

				// check after prefix url
				str := strings.TrimPrefix(ur.String(), prefix)

				// Cannot be a file, e.g. a resource page
				// Cannot be a non top-level Wikipedia page
				// Cannot be a sup page hash link
				if strings.Contains(str, ":") || strings.Contains(str, "/") || strings.Contains(str, "#") {
					return false
				}

				return true
			})
			if err != nil {
				if err.Error() == "EOF" {
					// Could not find a link on this file,
					// Go back up one page
					lp := startPage
					p := startPage
					for p.Next != nil {
						lp = p
						p = p.Next
					}
					if (lp == startPage) {
						log.Fatal("Cannot find links on provided page")
					}
					page = lp
					visits--
					continue
				}
				log.Fatal(err)
			}
			page = pg

			fmt.Printf("Have Followed %d links\r", visits)

			haveVisited[*page.Url] = *page
			visits++

			if page.IsMatch(targetPage) {
				fmt.Printf("Found match, took %d follows\n", visits)
				break
			}
		}
		done <- true
	}()

	sig := make(chan os.Signal)
	signal.Notify(sig, os.Interrupt)

	// Wait for successful path or sigint
	select {
	case <-done:
	case <-sig:
	}

	// Print path
	page := startPage
	i := 0
	for page != nil {
		fmt.Printf("%d: %s\n", i, page.Url)
		page = page.Next
		i++
	}
}
<|endoftext|>


<commit_before>// Accept requests to combine PDF documents located on Amazon S3 into
// a single document, upload back to S3, and notify a callback URL.
// TODO fail fast if S3 connection is not usable.
// TODO include timing information in response
// TODO need a way to enable auth in responses
package main

import (
	"launchpad.net/goamz/aws"
	"net/http"
	"pdfcombiner/server"
)

// Verify AWS credentials are set in the environment:
// - AWS_ACCESS_KEY_ID
// - AWS_SECRET_ACCESS_KEY
func init() {
	_, err := aws.EnvAuth()
	if err != nil {
		panic(err)
	}
}

func main() {
	server := new(server.CombinerServer)
	http.HandleFunc("/health_check", server.Ping)
	http.HandleFunc("/", server.ProcessJob)
	http.ListenAndServe(":8080", nil)
}
<commit_msg>Only start server if specified<commit_after>// Accept requests to combine PDF documents located on Amazon S3 into
// a single document, upload back to S3, and notify a callback URL.
// TODO fail fast if S3 connection is not usable.
// TODO include timing information in response
// TODO need a way to enable auth in responses
package main

import (
	"flag"
	"launchpad.net/goamz/aws"
	"net/http"
	"pdfcombiner/server"
)

var (
	port       string
	serverMode bool
)

func init() {
	flag.BoolVar(&serverMode, "server", false, "run in server mode")
	flag.StringVar(&port, "port", "8080", "port to listen on")
}

func main() {
	flag.Parse()
	verifyAws()
	if serverMode {
		serve()
	}
}

// Verify AWS credentials are set in the environment:
// - AWS_ACCESS_KEY_ID
// - AWS_SECRET_ACCESS_KEY
func verifyAws() {
	_, err := aws.EnvAuth()
	if err != nil {
		panic(err)
	}
}

// Start a HTTP server listening on `port` to respond
// to JSON-formatted combination requests.
func serve() {
	server := new(server.CombinerServer)
	http.HandleFunc("/health_check", server.Ping)
	http.HandleFunc("/", server.ProcessJob)
	println("Accepting connections on " + port)
	http.ListenAndServe(":"+port, nil)
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"
)

var (
	version = "unknown"
)

func main() {
	app := cli.NewApp()
	app.Name = "downstream plugin"
	app.Usage = "downstream plugin"
	app.Action = run
	app.Version = version
	app.Flags = []cli.Flag{
		cli.StringSliceFlag{
			Name:   "repositories",
			Usage:  "List of repositories to trigger",
			EnvVar: "PLUGIN_REPOSITORIES",
		},
		cli.StringFlag{
			Name:   "server",
			Usage:  "Trigger a drone build on a custom server",
			EnvVar: "DOWNSTREAM_SERVER,PLUGIN_SERVER",
		},
		cli.StringFlag{
			Name:   "host",
			Usage:  "Host for default value of server flag",
			EnvVar: "DRONE_SYSTEM_HOST,PLUGIN_HOST",
		},
		cli.StringFlag{
			Name:   "proto",
			Usage:  "Protocol for default value of server flag",
			EnvVar: "DRONE_SYSTEM_PROTO,PLUGIN_PROTO",
		},
		cli.StringFlag{
			Name:   "token",
			Usage:  "Drone API token from your user settings",
			EnvVar: "DRONE_TOKEN,DOWNSTREAM_TOKEN,PLUGIN_TOKEN",
		},
		cli.BoolFlag{
			Name:   "wait",
			Usage:  "Wait for any currently running builds to finish",
			EnvVar: "PLUGIN_WAIT",
		},
		cli.DurationFlag{
			Name:   "timeout",
			Value:  time.Duration(60) * time.Second,
			Usage:  "How long to wait on any currently running builds",
			EnvVar: "PLUGIN_WAIT_TIMEOUT",
		},
		cli.BoolFlag{
			Name:   "last-successful",
			Usage:  "Trigger last successful build",
			EnvVar: "PLUGIN_LAST_SUCCESSFUL",
		},
		cli.StringSliceFlag{
			Name:   "params",
			Usage:  "List of params (key=value or file paths of params) to pass to triggered builds",
			EnvVar: "PLUGIN_PARAMS",
		},
		cli.StringSliceFlag{
			Name:   "params-from-env",
			Usage:  "List of environment variables to pass to triggered builds",
			EnvVar: "PLUGIN_PARAMS_FROM_ENV",
		},
		cli.StringFlag{
			Name:   "deploy",
			Usage:  "Environment to trigger deploy for the respective build",
			EnvVar: "PLUGIN_DEPLOY",
		},
	}

	if err := app.Run(os.Args); err != nil {
		logrus.Fatal(err)
	}
}

func run(c *cli.Context) error {
	plugin := Plugin{
		Repos:          c.StringSlice("repositories"),
		Server:         c.String("server"),
		Token:          c.String("token"),
		Wait:           c.Bool("wait"),
		Timeout:        c.Duration("timeout"),
		LastSuccessful: c.Bool("last-successful"),
		Params:         c.StringSlice("params"),
		ParamsEnv:      c.StringSlice("params-from-env"),
		Deploy:         c.String("deploy"),
	}

	return plugin.Exec()
}
<commit_msg>prefix flags with `system.`, also init plugin with flag values<commit_after>package main

import (
	"os"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"
)

var (
	version = "unknown"
)

func main() {
	app := cli.NewApp()
	app.Name = "downstream plugin"
	app.Usage = "downstream plugin"
	app.Action = run
	app.Version = version
	app.Flags = []cli.Flag{
		cli.StringSliceFlag{
			Name:   "repositories",
			Usage:  "List of repositories to trigger",
			EnvVar: "PLUGIN_REPOSITORIES",
		},
		cli.StringFlag{
			Name:   "server",
			Usage:  "Trigger a drone build on a custom server",
			EnvVar: "DOWNSTREAM_SERVER,PLUGIN_SERVER",
		},
		cli.StringFlag{
			Name:   "system.host",
			Usage:  "Host for default value of server flag",
			EnvVar: "DRONE_SYSTEM_HOST,PLUGIN_HOST",
		},
		cli.StringFlag{
			Name:   "system.proto",
			Usage:  "Protocol for default value of server flag",
			EnvVar: "DRONE_SYSTEM_PROTO,PLUGIN_PROTO",
		},
		cli.StringFlag{
			Name:   "token",
			Usage:  "Drone API token from your user settings",
			EnvVar: "DRONE_TOKEN,DOWNSTREAM_TOKEN,PLUGIN_TOKEN",
		},
		cli.BoolFlag{
			Name:   "wait",
			Usage:  "Wait for any currently running builds to finish",
			EnvVar: "PLUGIN_WAIT",
		},
		cli.DurationFlag{
			Name:   "timeout",
			Value:  time.Duration(60) * time.Second,
			Usage:  "How long to wait on any currently running builds",
			EnvVar: "PLUGIN_WAIT_TIMEOUT",
		},
		cli.BoolFlag{
			Name:   "last-successful",
			Usage:  "Trigger last successful build",
			EnvVar: "PLUGIN_LAST_SUCCESSFUL",
		},
		cli.StringSliceFlag{
			Name:   "params",
			Usage:  "List of params (key=value or file paths of params) to pass to triggered builds",
			EnvVar: "PLUGIN_PARAMS",
		},
		cli.StringSliceFlag{
			Name:   "params-from-env",
			Usage:  "List of environment variables to pass to triggered builds",
			EnvVar: "PLUGIN_PARAMS_FROM_ENV",
		},
		cli.StringFlag{
			Name:   "deploy",
			Usage:  "Environment to trigger deploy for the respective build",
			EnvVar: "PLUGIN_DEPLOY",
		},
	}

	if err := app.Run(os.Args); err != nil {
		logrus.Fatal(err)
	}
}

func run(c *cli.Context) error {
	plugin := Plugin{
		Repos:          c.StringSlice("repositories"),
		Server:         c.String("server"),
		Host:           c.String("system.host"),
		Proto:          c.String("system.proto"),
		Token:          c.String("token"),
		Wait:           c.Bool("wait"),
		Timeout:        c.Duration("timeout"),
		LastSuccessful: c.Bool("last-successful"),
		Params:         c.StringSlice("params"),
		ParamsEnv:      c.StringSlice("params-from-env"),
		Deploy:         c.String("deploy"),
	}

	return plugin.Exec()
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strings"
	"time"
)

var replace = map[string]func(){
	"nnf":       nnf,
	"nnl":       nnl,
	"openFile":  openFile,
	"readFile":  readFile,
	"getURL":    getURL,
	"reqStdin":  reqStdin,
	"goMain":    goMain,
	"tempFile":  tempFile,
	"serveHTTP": serveHTTP,
	"pymain":    pyMain,
	"html5":     html5,
	"now":       now,
	"ubb":       bash,
	"ubp":       python,
	"gomain":    goMain,
	"flagsh":    flagsh,
	"dummyType": dummyType,
}

var update = map[string]func(string){
	"fpl(":  fpl,
	"lpf(":  lpf,
	"lpl(":  lpl,
	"fpf(":  fpf,
	"hfunc": hfunc,
	"ow:":   pyOpenWrite,
	"ul":    ul,
}

var dom = []string{"div", "form", "section", "article", "body", "header"}

func main() {
	if os.Getenv("shortcuts") == "off" {
		return
	}

	stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}

	s := bufio.NewScanner(os.Stdin)

	for s.Scan() {
		line := s.Text()
		trim := strings.TrimSpace(line)

		if f, found := replace[trim]; found {
			f()
			continue
		}

		var replaced bool
		for pre := range update {
			if strings.HasPrefix(trim, pre) {
				update[pre](line)
				replaced = true
				break
			}

		}
		for _, pre := range dom {
			if strings.HasPrefix(trim, pre) {
				element(line, pre)
				replaced = true
				break
			}

		}
		if !replaced {
			fmt.Println(line)
		}
	}

}

func nnf() {
	fmt.Println(`if err != nil{
	log.Fatalf("Failed to do something: %s\n", err)
	}`)
}

func nnl() {
	fmt.Println(`if err != nil{
	log.Printf("Failed to do something: %s\n", err)
	}`)
}

func lpf(line string) {
	fmt.Println(strings.Replace(line, "lpf(", "log.Printf(", 1))
}

func fpf(line string) {
	fmt.Println(strings.Replace(line, "fpf(", "fmt.Printf(", 1))
}

func lpl(line string) {
	fmt.Println(strings.Replace(line, "lpl(", "log.Println(", 1))
}

func fpl(line string) {
	fmt.Println(strings.Replace(line, "fpl(", "fmt.Println(", 1))
}

func goMain() {
	fmt.Println(`package main

import (
    "fmt"
)

func main() {
    fmt.Println("gopher")
}
`)
}

func serveHTTP() {
	fmt.Println(`package main

import (
    "fmt"
	"net/http"
)

func main() {
    http.HandleFunc("/", index)
	http.ListenAndServe(":8080", nil)
}

func index(w http.ResponseWriter, r *http.Request){
	fmt.Fprintf(w, "hello")
}
`)
}

func pyMain() {
	fmt.Println(`#!/usr/bin/env python
"""
You should probably write something here.
"""

from __future__ import unicode_literals

def main():
    """
    Do the thing.
    """
    print "python"

if __name__ == '__main__':
    main()
`)
}

func html5() {
	fmt.Println(`<!DOCTYPE html>

		<meta charset="UTF-8">
		<title>title</title>
        <link rel="stylesheet" href="https://aoeus.com/milligram.min.css" type="text/css">
		<meta name="viewport" content="width-device-width, initial-scale=1">

topic

content

`)
}

func hfunc(line string) {
	parts := strings.Split(line, " ")
	name := "index"
	if len(parts) > 1 {
		name = parts[1]
	}
	fmt.Printf(`func %s(w http.ResponseWriter, r *http.Request){
	}`, name)
}

func pyOpenWrite(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	lines := []string{
		`with open("out.txt", "wb") as raw:`,
		`    raw.write("{0}\n".format(msg))`,
	}

	for _, line = range lines {
		fmt.Printf("%s%s\n", pad, line)
	}

}

func ul(line string) {
	trim := strings.TrimSpace(line)
	margin := len(line) - len(strings.TrimLeft(trim, " \t"))
	padding := strings.Repeat(" ", margin)
	fmt.Printf(padding)
	fmt.Println("
")
	for i := 0; i < 3; i++ {
		fmt.Printf(padding)
		fmt.Println("\t
")
		fmt.Printf(padding)
		fmt.Println("\t\tthing")
		fmt.Printf(padding)
		fmt.Println("\t
")
	}
	fmt.Printf(padding)
	fmt.Println("
")

}

func element(line , el string) {
	margin := len(line) - len(strings.TrimLeft(line, " \t"))
	padding := line[0:margin]
	fmt.Printf(padding)
	fmt.Println("<" + el + ">")
	fmt.Printf(padding)
	fmt.Println("</" + el + ">")
}

func form(line string) {
	margin := len(line) - len(strings.TrimLeft(line, " \t"))
	padding := line[0:margin]
	fmt.Printf(padding)
	fmt.Println("<form>")
	fmt.Printf(padding)
	fmt.Println("</form>")
}

func openFile() {
	fmt.Println(`f, err := os.Open(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}
	defer f.Close()`)
}

func readFile() {
	fmt.Println(`b, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}`)
}

func getURL() {
	fmt.Println(`resp, err := http.Get(link)
	if err != nil {
		log.Printf("Unable to fetch %q: %s\n", link, err)
		return
	}
	defer resp.Body.Close()
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Printf("Unable to read response from  %q: %s\n", link, err)
		return
	}
	`)
}

func reqStdin() {
	fmt.Println(`stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}`)
}

func tempFile() {
	fmt.Println(`t, err := ioutil.TempFile("", "temp")
if err != nil{
	log.Fatalf("Unable to create temp file: %s\n", err)
}
fmt.Printf("Created temp file %q\n", t.Name())
defer t.Close()
`)
}

func now() {
	fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}

func bash() {
	fmt.Println("#!/usr/bin/env bash")
}

func python() {
	fmt.Println("#!/usr/bin/env python")
}

func flagsh() {

	fmt.Println(`#!/usr/bin/env bash

flag=$(mktemp)
touch $flag

while true; do
sleep 5
    find . -mmin -1 -name '*.go' 2>>/dev/null | while read file; do
        if [[ "$file" -nt $flag ]]; then
            if [[ "$file" == "$flag" ]]; then
                continue
            fi
            echo "$file was updated"
            touch $flag
        fi
    done
done
`)
}

func dummyType() {
	fmt.Println(`type dummy struct {
    thing string
    size int
    color string
}
`)
}
<commit_msg>Add some stuff, remove DOM stuff<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strings"
	"time"
)

var replace = map[string]func(){
	"nnf":       nnf,
	"nnl":       nnl,
	"openFile":  openFile,
	"readFile":  readFile,
	"getURL":    getURL,
	"reqStdin":  reqStdin,
	"goMain":    goMain,
	"tempFile":  tempFile,
	"serveHTTP": serveHTTP,
	"pymain":    pyMain,
	"html5":     html5,
	"now":       now,
	"ubb":       bash,
	"ubp":       python,
	"gomain":    goMain,
	"flagsh":    flagsh,
	"dummyType": dummyType,
	"jm":        jsonMarshal,
	"ju":        jsonUnmarshal,
	"rb":        readBody,
	"watcher":   watcher,
}

var update = map[string]func(string){
	"fpl(":  fpl,
	"lpf(":  lpf,
	"lpl(":  lpl,
	"fpf(":  fpf,
	"hfunc": hfunc,
	"ow:":   pyOpenWrite,
	"ul":    ul,
}

func main() {
	if os.Getenv("shortcuts") == "off" {
		return
	}

	stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}

	s := bufio.NewScanner(os.Stdin)

	for s.Scan() {
		line := s.Text()
		trim := strings.TrimSpace(line)

		if f, found := replace[trim]; found {
			f()
			continue
		}

		var replaced bool
		for pre := range update {
			if strings.HasPrefix(trim, pre) {
				update[pre](line)
				replaced = true
				break
			}

		}
		if !replaced {
			fmt.Println(line)
		}
	}

}

func nnf() {
	fmt.Println(`if err != nil{
	log.Fatalf("Failed to do something: %s\n", err)
	}`)
}

func nnl() {
	fmt.Println(`if err != nil{
	log.Printf("Failed to do something: %s\n", err)
	}`)
}

func lpf(line string) {
	fmt.Println(strings.Replace(line, "lpf(", "log.Printf(", 1))
}

func fpf(line string) {
	fmt.Println(strings.Replace(line, "fpf(", "fmt.Printf(", 1))
}

func lpl(line string) {
	fmt.Println(strings.Replace(line, "lpl(", "log.Println(", 1))
}

func fpl(line string) {
	fmt.Println(strings.Replace(line, "fpl(", "fmt.Println(", 1))
}

func goMain() {
	fmt.Println(`package main

import (
    "fmt"
)

func main() {
    fmt.Println("gopher")
}
`)
}

func serveHTTP() {
	fmt.Println(`package main

import (
    "fmt"
	"net/http"
)

func main() {
    http.HandleFunc("/", index)
	http.ListenAndServe(":8080", nil)
}

func index(w http.ResponseWriter, r *http.Request){
	fmt.Fprintf(w, "hello")
}
`)
}

func pyMain() {
	fmt.Println(`#!/usr/bin/env python
"""
You should probably write something here.
"""

from __future__ import unicode_literals

def main():
    """
    Do the thing.
    """
    print "python"

if __name__ == '__main__':
    main()
`)
}

func html5() {
	fmt.Println(`<!DOCTYPE html>

		<meta charset="UTF-8">
		<title>title</title>
        <link rel="stylesheet" href="https://aoeus.com/milligram.min.css" type="text/css">
		<meta name="viewport" content="width-device-width, initial-scale=1">

topic

content

`)
}

func hfunc(line string) {
	parts := strings.Split(line, " ")
	name := "index"
	if len(parts) > 1 {
		name = parts[1]
	}
	fmt.Printf(`func %s(w http.ResponseWriter, r *http.Request){
	}`, name)
}

func pyOpenWrite(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	lines := []string{
		`with open("out.txt", "wb") as raw:`,
		`    raw.write("{0}\n".format(msg))`,
	}

	for _, line = range lines {
		fmt.Printf("%s%s\n", pad, line)
	}

}

func ul(line string) {
	trim := strings.TrimSpace(line)
	margin := len(line) - len(strings.TrimLeft(trim, " \t"))
	padding := strings.Repeat(" ", margin)
	fmt.Printf(padding)
	fmt.Println("
")
	for i := 0; i < 3; i++ {
		fmt.Printf(padding)
		fmt.Println("\t
")
		fmt.Printf(padding)
		fmt.Println("\t\tthing")
		fmt.Printf(padding)
		fmt.Println("\t
")
	}
	fmt.Printf(padding)
	fmt.Println("
")

}

func element(line, el string) {
	margin := len(line) - len(strings.TrimLeft(line, " \t"))
	padding := line[0:margin]
	fmt.Printf(padding)
	fmt.Println("<" + el + ">")
	fmt.Printf(padding)
	fmt.Println("</" + el + ">")
}

func form(line string) {
	margin := len(line) - len(strings.TrimLeft(line, " \t"))
	padding := line[0:margin]
	fmt.Printf(padding)
	fmt.Println("<form>")
	fmt.Printf(padding)
	fmt.Println("</form>")
}

func openFile() {
	fmt.Println(`f, err := os.Open(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}
	defer f.Close()`)
}

func readFile() {
	fmt.Println(`b, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}`)
}

func getURL() {
	fmt.Println(`resp, err := http.Get(link)
	if err != nil {
		log.Printf("Unable to fetch %q: %s\n", link, err)
		return
	}
	defer resp.Body.Close()
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Printf("Unable to read response from  %q: %s\n", link, err)
		return
	}
	`)
}

func reqStdin() {
	fmt.Println(`stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}`)
}

func tempFile() {
	fmt.Println(`t, err := ioutil.TempFile("", "temp")
if err != nil{
	log.Fatalf("Unable to create temp file: %s\n", err)
}
fmt.Printf("Created temp file %q\n", t.Name())
defer t.Close()
`)
}

func now() {
	fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}

func bash() {
	fmt.Println("#!/usr/bin/env bash")
}

func python() {
	fmt.Println("#!/usr/bin/env python")
}

func flagsh() {

	fmt.Println(`#!/usr/bin/env bash

flag=$(mktemp)
touch $flag

while true; do
sleep 5
    find . -mmin -1 -name '*.go' 2>>/dev/null | while read file; do
        if [[ "$file" -nt $flag ]]; then
            if [[ "$file" == "$flag" ]]; then
                continue
            fi
            echo "$file was updated"
            touch $flag
        fi
    done
done
`)
}

func dummyType() {
	fmt.Println(`type dummy struct {
    thing string
    size int
    color string
}
`)
}
func jsonMarshal() {
	fmt.Println(`b, err := json.Marshal(x)
    if err != nil{
        log.Fatalf("Failed to do something: %s\n", err)
	} `)
}

func jsonUnmarshal() {
	fmt.Println(`var x thing
err = json.Unmarshal(b, &x)
return x, err
`)
}

func readBody() {
	fmt.Println(`b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}
	defer r.Body.Close()`)
}

func watcher() {
	fmt.Println(`#!/usr/bin/env bash

bin=monkey
flag=$(mktemp)
code=main.go

function cleanup() {
    pkill $bin
    rm -f $bin
    rm -f $flag
    exit
}

trap cleanup SIGINT SIGTERM

while true
do
    if [ ! "$code" -nt $flag ]; then
        sleep 5
        continue
    fi
    go build -o $bin $code || { touch $flag; continue; }
    pkill $bin
    ./$bin &
    sleep 1
    ./tests.sh
    touch $flag
    sleep 15
done`)
}
<|endoftext|>


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

package main

import (
	"os"
	"strings"

	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/cloudfoundry/cli/cf/trace"
	"github.com/cloudfoundry/cli/plugin"
	"github.com/ecsteam/cloudfoundry-top-plugin/top"
	"github.com/ecsteam/cloudfoundry-top-plugin/util"
	"github.com/simonleung8/flags"
)

type TopCmd struct {
	ui terminal.UI
}

func (c *TopCmd) GetMetadata() plugin.PluginMetadata {
	return plugin.PluginMetadata{
		Name: "top",
		Version: plugin.VersionType{
			Major: 0,
			Minor: 7,
			Build: 3,
		},
		MinCliVersion: plugin.VersionType{
			Major: 6,
			Minor: 17,
			Build: 0,
		},
		Commands: []plugin.Command{
			{
				Name:     "top",
				HelpText: "Displays top stats - by Kurt Kellner of ECS Team",
				UsageDetails: plugin.Usage{
					Usage: "cf top",
					Options: map[string]string{
						"no-top-check": "-ntc, do not check if there are other instances of top running on this OS",
						"cygwin":       "-c, force run under cygwin (Use this to run: 'cmd /c start cf top -cygwin' )",
						"nozzles":      "-n, specify the number of nozzle instances (default: 2)",
						"debug":        "-d, enable debugging",
					},
				},
			},
		},
	}
}

func main() {
	plugin.Start(new(TopCmd))
}

func (c *TopCmd) Run(cliConnection plugin.CliConnection, args []string) {
	var options *top.ClientOptions

	traceLogger := trace.NewLogger(os.Stdout, true, os.Getenv("CF_TRACE"), "")
	c.ui = terminal.NewUI(os.Stdin, os.Stdout, terminal.NewTeePrinter(os.Stdout), traceLogger)

	switch args[0] {
	case "top":
		options = c.buildClientOptions(args)
	case "example-alternate-command":
	default:
		return
	}

	if options == nil {
		return
	}

	if options.Nozzles > 10 {
		c.ui.Failed("Can not specify more then 10 nozzle instances")
		return
	}
	if options.Nozzles < 1 {
		c.ui.Failed("Can not specify less then 1 nozzle instance")
		return
	}

	// TODO: THis is for testing only
	/*
		for i := 0; i < 10; i++ {
			token, err := cliConnection.AccessToken()
			if err != nil {
				c.ui.Failed(err.Error())
				break
			}
			fmt.Printf("Token: %v\n\n", token)
		}
		if true {
			return
		}
	*/

	cfTrace := os.Getenv("CF_TRACE")
	if strings.ToLower(cfTrace) == "true" {
		c.ui.Failed("The cf top plugin will not run with CF_TRACE environment variable set to true")
		return
	}

	if !options.Cygwin && util.IsCygwin() {
		c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top -cygwin'")
		return
	}

	/***********************************************************
	Trying to find a way to detect cygwin but not detect cygwin if cmd.exe is spawned from cygwin

	values := os.Environ()
	for _, v := range values  {
		fmt.Printf("value: [%v]\n", v)
	}

	fmt.Printf("Separator: [%v]\n", os.PathSeparator)
	fmt.Printf("PathListSeparator: [%v]\n", os.PathListSeparator)
	fmt.Printf("Geteuid: %v\n", os.Geteuid())
	fmt.Printf("Getppid: %v\n", os.Getppid())
	p, e := os.FindProcess(os.Getppid())
	fmt.Printf("Getppid: %+v [Err:%v]\n", p, e)

	if strings.Contains(strings.ToLower(os.Getenv("OS")), "windows") {
		shell := os.Getenv("SHELL")
		if len(shell) > 0 {
			c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top'")
			return
		}
	}
	fmt.Printf("runtime.GOOS: [%v]\n", runtime.GOOS)
	*/

	/*
		if strings.ToLower(osType) == "cygwin" {
			c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top'")
			return
		}
	*/

	client := top.NewClient(cliConnection, options, c.ui)
	client.Start()
}

func (c *TopCmd) buildClientOptions(args []string) *top.ClientOptions {
	var debug bool
	var noTopCheck bool
	var cygwin bool
	var nozzles int

	fc := flags.New()
	fc.NewBoolFlag("debug", "d", "used for debugging")
	fc.NewBoolFlag("no-top-check", "ntc", "Do not check if there are other instances of top running")
	fc.NewBoolFlag("cygwin", "c", "force run under cygwin (Use this to run: 'cmd /c start cf top -cygwin' )")
	fc.NewIntFlagWithDefault("nozzles", "n", "number of nozzles", 2)
	//fc.NewStringFlag("filter", "f", "specify message filter such as LogMessage, ValueMetric, CounterEvent, HttpStartStop")
	err := fc.Parse(args[1:]...)

	if err != nil {
		c.ui.Failed(err.Error())
		return nil
	}
	if fc.IsSet("debug") {
		debug = fc.Bool("debug")
	}
	if fc.IsSet("no-top-check") {
		noTopCheck = fc.Bool("no-top-check")
	}
	if fc.IsSet("cygwin") {
		cygwin = fc.Bool("cygwin")
	}

	nozzles = fc.Int("nozzles")

	/*
		if fc.IsSet("filter") {
			filter = fc.String("filter")
		}
	*/
	return &top.ClientOptions{
		Debug:      debug,
		NoTopCheck: noTopCheck,
		Cygwin:     cygwin,
		Nozzles:    nozzles,
	}
}
<commit_msg>Build version v0.7.4<commit_after>// Copyright (c) 2016 ECS Team, Inc. - All Rights Reserved
// https://github.com/ECSTeam/cloudfoundry-top-plugin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"os"
	"strings"

	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/cloudfoundry/cli/cf/trace"
	"github.com/cloudfoundry/cli/plugin"
	"github.com/ecsteam/cloudfoundry-top-plugin/top"
	"github.com/ecsteam/cloudfoundry-top-plugin/util"
	"github.com/simonleung8/flags"
)

type TopCmd struct {
	ui terminal.UI
}

func (c *TopCmd) GetMetadata() plugin.PluginMetadata {
	return plugin.PluginMetadata{
		Name: "top",
		Version: plugin.VersionType{
			Major: 0,
			Minor: 7,
			Build: 4,
		},
		MinCliVersion: plugin.VersionType{
			Major: 6,
			Minor: 17,
			Build: 0,
		},
		Commands: []plugin.Command{
			{
				Name:     "top",
				HelpText: "Displays top stats - by Kurt Kellner of ECS Team",
				UsageDetails: plugin.Usage{
					Usage: "cf top",
					Options: map[string]string{
						"no-top-check": "-ntc, do not check if there are other instances of top running on this OS",
						"cygwin":       "-c, force run under cygwin (Use this to run: 'cmd /c start cf top -cygwin' )",
						"nozzles":      "-n, specify the number of nozzle instances (default: 2)",
						"debug":        "-d, enable debugging",
					},
				},
			},
		},
	}
}

func main() {
	plugin.Start(new(TopCmd))
}

func (c *TopCmd) Run(cliConnection plugin.CliConnection, args []string) {
	var options *top.ClientOptions

	traceLogger := trace.NewLogger(os.Stdout, true, os.Getenv("CF_TRACE"), "")
	c.ui = terminal.NewUI(os.Stdin, os.Stdout, terminal.NewTeePrinter(os.Stdout), traceLogger)

	switch args[0] {
	case "top":
		options = c.buildClientOptions(args)
	case "example-alternate-command":
	default:
		return
	}

	if options == nil {
		return
	}

	if options.Nozzles > 10 {
		c.ui.Failed("Can not specify more then 10 nozzle instances")
		return
	}
	if options.Nozzles < 1 {
		c.ui.Failed("Can not specify less then 1 nozzle instance")
		return
	}

	// TODO: THis is for testing only
	/*
		for i := 0; i < 10; i++ {
			token, err := cliConnection.AccessToken()
			if err != nil {
				c.ui.Failed(err.Error())
				break
			}
			fmt.Printf("Token: %v\n\n", token)
		}
		if true {
			return
		}
	*/

	cfTrace := os.Getenv("CF_TRACE")
	if strings.ToLower(cfTrace) == "true" {
		c.ui.Failed("The cf top plugin will not run with CF_TRACE environment variable set to true")
		return
	}

	if !options.Cygwin && util.IsCygwin() {
		c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top -cygwin'")
		return
	}

	/***********************************************************
	Trying to find a way to detect cygwin but not detect cygwin if cmd.exe is spawned from cygwin

	values := os.Environ()
	for _, v := range values  {
		fmt.Printf("value: [%v]\n", v)
	}

	fmt.Printf("Separator: [%v]\n", os.PathSeparator)
	fmt.Printf("PathListSeparator: [%v]\n", os.PathListSeparator)
	fmt.Printf("Geteuid: %v\n", os.Geteuid())
	fmt.Printf("Getppid: %v\n", os.Getppid())
	p, e := os.FindProcess(os.Getppid())
	fmt.Printf("Getppid: %+v [Err:%v]\n", p, e)

	if strings.Contains(strings.ToLower(os.Getenv("OS")), "windows") {
		shell := os.Getenv("SHELL")
		if len(shell) > 0 {
			c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top'")
			return
		}
	}
	fmt.Printf("runtime.GOOS: [%v]\n", runtime.GOOS)
	*/

	/*
		if strings.ToLower(osType) == "cygwin" {
			c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top'")
			return
		}
	*/

	client := top.NewClient(cliConnection, options, c.ui)
	client.Start()
}

func (c *TopCmd) buildClientOptions(args []string) *top.ClientOptions {
	var debug bool
	var noTopCheck bool
	var cygwin bool
	var nozzles int

	fc := flags.New()
	fc.NewBoolFlag("debug", "d", "used for debugging")
	fc.NewBoolFlag("no-top-check", "ntc", "Do not check if there are other instances of top running")
	fc.NewBoolFlag("cygwin", "c", "force run under cygwin (Use this to run: 'cmd /c start cf top -cygwin' )")
	fc.NewIntFlagWithDefault("nozzles", "n", "number of nozzles", 2)
	//fc.NewStringFlag("filter", "f", "specify message filter such as LogMessage, ValueMetric, CounterEvent, HttpStartStop")
	err := fc.Parse(args[1:]...)

	if err != nil {
		c.ui.Failed(err.Error())
		return nil
	}
	if fc.IsSet("debug") {
		debug = fc.Bool("debug")
	}
	if fc.IsSet("no-top-check") {
		noTopCheck = fc.Bool("no-top-check")
	}
	if fc.IsSet("cygwin") {
		cygwin = fc.Bool("cygwin")
	}

	nozzles = fc.Int("nozzles")

	/*
		if fc.IsSet("filter") {
			filter = fc.String("filter")
		}
	*/
	return &top.ClientOptions{
		Debug:      debug,
		NoTopCheck: noTopCheck,
		Cygwin:     cygwin,
		Nozzles:    nozzles,
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/christophwitzko/github-release-download/release"
	"github.com/julienschmidt/httprouter"
	"log"
	"net/http"
	"os"
	"os/signal"
	"time"
)

var bindAddress string = ":5000"
var client *release.GithubClient

func init() {
	if ba := os.Getenv("BIND_ADDRESS"); ba != "" {
		bindAddress = ba
	}
	client = release.NewClient(os.Getenv("GITHUB_TOKEN"))
}

func logger(router http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("%s - %s %s", r.RemoteAddr, r.Method, r.URL.EscapedPath())
		router.ServeHTTP(w, r)
	})
}

func doRedirect(w http.ResponseWriter, r *http.Request, url string, err error) {
	if err != nil {
		log.Println(err)
		http.Error(w, "server error", http.StatusInternalServerError)
		return
	}
	if url == "" {
		http.NotFound(w, r)
		return
	}
	http.Redirect(w, r, url, 302)
}

func getLatestDownload(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
	defer cancel()
	url, err := client.GetLatestDownloadUrl(ctx, ps[0].Value, ps[1].Value, ps[2].Value, ps[3].Value)
	doRedirect(w, r, url, err)
}

func getMatchingDownload(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
	defer cancel()
	url, err := client.GetMatchingDownloadUrl(ctx, ps[0].Value, ps[1].Value, ps[2].Value, ps[3].Value, ps[4].Value)
	doRedirect(w, r, url, err)
}

func getVersions(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
	defer cancel()
	if ps[0].Value == "_" && ps[1].Value == "go" {
		versions, err := client.GetGoVersions(ctx)
		if err != nil {
			log.Println(err)
			http.Error(w, "server error", http.StatusInternalServerError)
			return
		}
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		json.NewEncoder(w).Encode(versions)
		return
	}
	http.NotFound(w, r)
}

func index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprintln(w, "https://get-release.xyz/:owner/:repo/:os/:arch{/:constraint}")
}

func main() {
	router := httprouter.New()
	router.GET("/", index)
	router.GET("/:owner/:repo", getVersions)
	router.GET("/:owner/:repo/:os/:arch", getLatestDownload)
	router.GET("/:owner/:repo/:os/:arch/:constraint", getMatchingDownload)
	server := http.Server{
		Addr:    bindAddress,
		Handler: logger(router),
	}
	go func() {
		log.Printf("starting server on port %s...", bindAddress)
		if err := server.ListenAndServe(); err != nil {
			log.Fatal(err)
		}
	}()
	defer server.Shutdown(nil)
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	<-c
	log.Println("server stopped")
}
<commit_msg>feat: add usage route<commit_after>package main

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/christophwitzko/github-release-download/release"
	"github.com/julienschmidt/httprouter"
	"log"
	"net/http"
	"os"
	"os/signal"
	"time"
)

var bindAddress string = ":5000"
var client *release.GithubClient

func init() {
	if ba := os.Getenv("BIND_ADDRESS"); ba != "" {
		bindAddress = ba
	}
	client = release.NewClient(os.Getenv("GITHUB_TOKEN"))
}

func logger(router http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("%s - %s %s", r.RemoteAddr, r.Method, r.URL.EscapedPath())
		router.ServeHTTP(w, r)
	})
}

func doRedirect(w http.ResponseWriter, r *http.Request, url string, err error) {
	if err != nil {
		log.Println(err)
		http.Error(w, "server error", http.StatusInternalServerError)
		return
	}
	if url == "" {
		http.NotFound(w, r)
		return
	}
	http.Redirect(w, r, url, 302)
}

func getLatestDownload(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
	defer cancel()
	url, err := client.GetLatestDownloadUrl(ctx, ps[0].Value, ps[1].Value, ps[2].Value, ps[3].Value)
	doRedirect(w, r, url, err)
}

func getMatchingDownload(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
	defer cancel()
	url, err := client.GetMatchingDownloadUrl(ctx, ps[0].Value, ps[1].Value, ps[2].Value, ps[3].Value, ps[4].Value)
	doRedirect(w, r, url, err)
}

func getVersions(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
	defer cancel()
	if ps[0].Value == "_" && ps[1].Value == "go" {
		versions, err := client.GetGoVersions(ctx)
		if err != nil {
			log.Println(err)
			http.Error(w, "server error", http.StatusInternalServerError)
			return
		}
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		json.NewEncoder(w).Encode(versions)
		return
	}
	http.NotFound(w, r)
}

func usage(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	if ps[0].Value != "_usage" {
		http.NotFound(w, r)
		return
	}
	rl, _, err := client.Client.RateLimits(r.Context())
	if err != nil {
		log.Println(err)
		http.Error(w, "server error", http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	json.NewEncoder(w).Encode(rl.Core)
}

func index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprintln(w, "https://get-release.xyz/:owner/:repo/:os/:arch{/:constraint}")
}

func main() {
	router := httprouter.New()
	router.GET("/", index)
	router.GET("/:owner", usage)
	router.GET("/:owner/:repo", getVersions)
	router.GET("/:owner/:repo/:os/:arch", getLatestDownload)
	router.GET("/:owner/:repo/:os/:arch/:constraint", getMatchingDownload)
	server := http.Server{
		Addr:    bindAddress,
		Handler: logger(router),
	}
	go func() {
		log.Printf("starting server on port %s...", bindAddress)
		if err := server.ListenAndServe(); err != nil {
			log.Fatal(err)
		}
	}()
	defer server.Shutdown(nil)
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	<-c
	log.Println("server stopped")
}
<|endoftext|>


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

// Go-import-redirector is an HTTP server for a custom Go import domain.
// It responds to requests in a given import path root with a meta tag
// specifying the source repository for the ``go get'' command and an
// HTML redirect to the godoc.org documentation page for that package.
//
// Usage:
//
//	go-import-redirector [-addr address] [-tls] [-vcs sys] <import> <repo>
//
// Go-import-redirector listens on address (default ``:80'')
// and responds to requests for URLs in the given import path root
// with one meta tag specifying the given source repository for ``go get''
// and another meta tag causing a redirect to the corresponding
// godoc.org documentation page.
//
// For example, if invoked as:
//
//	go-import-redirector 9fans.net/go https://github.com/9fans/go
//
// then the response for 9fans.net/go/acme/editinacme will include these tags:
//
//	<meta name="go-import" content="9fans.net/go git https://github.com/9fans/go">
//	<meta http-equiv="refresh" content="0; url=https://godoc.org/9fans.net/go/acme/editinacme">
//
// If both <import> and <repo> end in /*, the corresponding path element
// is taken from the import path and substituted in repo on each request.
// For example, if invoked as:
//
//	go-import-redirector rsc.io/* https://github.com/rsc/*
//
// then the response for rsc.io/x86/x86asm will include these tags:
//
//	<meta name="go-import" content="rsc.io/x86 git https://github.com/rsc/x86">
//	<meta http-equiv="refresh" content="0; url=https://godoc.org/rsc.io/x86/x86asm">
//
// Note that the wildcard element (x86) has been included in the Git repo path.
//
// The -addr option specifies the HTTP address to serve (default ``:http'').
//
// The -tls option causes go-import-redirector to serve HTTPS on port 443,
// loading an X.509 certificate and key pair from files in the current directory
// named after the host in the import path with .crt and .key appended
// (for example, rsc.io.crt and rsc.io.key).
// Like for http.ListenAndServeTLS, the certificate file should contain the
// concatenation of the server's certificate and the signing certificate authority's certificate.
//
// The -vcs option specifies the version control system, git, hg, or svn (default ``git'').
//
// Deployment on Google Cloud Platform
//
// For the case of a redirector for an entire domain (such as rsc.io above),
// the Makefile in this directory contains recipes to deploy a trivial VM running
// just this program, using a static IP address that can be loaded into the
// DNS configuration for the target domain.
//
package main

import (
	"bytes"
	"flag"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"os"
	"strings"
)

var (
	addr       = flag.String("addr", ":http", "serve http on `address`")
	serveTLS   = flag.Bool("tls", false, "serve https on :443")
	vcs        = flag.String("vcs", "git", "set version control `system`")
	importPath string
	repoPath   string
	wildcard   bool
)

func usage() {
	fmt.Fprintf(os.Stderr, "usage: go-import-redirector <import> <repo>\n")
	fmt.Fprintf(os.Stderr, "options:\n")
	flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, "examples:\n")
	fmt.Fprintf(os.Stderr, "\tgo-import-redirector rsc.io/* https://github.com/rsc/*\n")
	fmt.Fprintf(os.Stderr, "\tgo-import-redirector 9fans.net/go https://github.com/9fans/go\n")
	os.Exit(2)
}

func main() {
	log.SetFlags(0)
	log.SetPrefix("go-import-redirector: ")
	flag.Usage = usage
	flag.Parse()
	if flag.NArg() != 2 {
		flag.Usage()
	}
	importPath = flag.Arg(0)
	repoPath = flag.Arg(1)
	if !strings.Contains(repoPath, "://") {
		log.Fatal("repo path must be full URL")
	}
	if strings.HasSuffix(importPath, "/*") != strings.HasSuffix(repoPath, "/*") {
		log.Fatal("either both import and repo must have /* or neither")
	}
	if strings.HasSuffix(importPath, "/*") {
		wildcard = true
		importPath = strings.TrimSuffix(importPath, "/*")
		repoPath = strings.TrimSuffix(repoPath, "/*")
	}
	http.HandleFunc(strings.TrimSuffix(importPath, "/")+"/", redirect)
	if *serveTLS {
		host := importPath
		if i := strings.Index(host, "/"); i >= 0 {
			host = host[:i]
		}
		go func() {
			log.Fatal(http.ListenAndServeTLS(":https", host+".crt", host+".key", nil))
		}()
	}
	log.Fatal(http.ListenAndServe(*addr, nil))
}

var tmpl = template.Must(template.New("main").Parse(`<!DOCTYPE html>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="go-import" content="{{.ImportRoot}} {{.VCS}} {{.VCSRoot}}">
<meta http-equiv="refresh" content="0; url=https://godoc.org/{{.ImportRoot}}{{.Suffix}}">

Nothing to see here; move along.

`))

type data struct {
	ImportRoot string
	VCS        string
	VCSRoot    string
	Suffix     string
}

func redirect(w http.ResponseWriter, req *http.Request) {
	path := strings.TrimSuffix(req.Host+req.URL.Path, "/")
	var importRoot, repoRoot, suffix string
	if wildcard {
		if path == importPath {
			http.Redirect(w, req, "https://godoc.org/"+importPath, 302)
			return
		}
		if !strings.HasPrefix(path, importPath+"/") {
			http.NotFound(w, req)
			return
		}
		elem := path[len(importPath)+1:]
		if i := strings.Index(elem, "/"); i >= 0 {
			elem, suffix = elem[:i], elem[i:]
		}
		importRoot = importPath + "/" + elem
		repoRoot = repoPath + "/" + elem
	} else {
		if path != importPath && !strings.HasPrefix(path, importPath+"/") {
			http.NotFound(w, req)
			return
		}
		importRoot = importPath
		repoRoot = repoPath
		suffix = path[len(importPath):]
	}
	d := &data{
		ImportRoot: importRoot,
		VCS:        *vcs,
		VCSRoot:    repoRoot,
		Suffix:     suffix,
	}
	var buf bytes.Buffer
	err := tmpl.Execute(&buf, d)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	w.Write(buf.Bytes())
}
<commit_msg>Allow for custom GoDoc URLs<commit_after>// Copyright 2015 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Go-import-redirector is an HTTP server for a custom Go import domain.
// It responds to requests in a given import path root with a meta tag
// specifying the source repository for the ``go get'' command and an
// HTML redirect to the godoc.org documentation page for that package.
//
// Usage:
//
//	go-import-redirector [-addr address] [-tls] [-vcs sys] <import> <repo>
//
// Go-import-redirector listens on address (default ``:80'')
// and responds to requests for URLs in the given import path root
// with one meta tag specifying the given source repository for ``go get''
// and another meta tag causing a redirect to the corresponding
// godoc.org documentation page.
//
// For example, if invoked as:
//
//	go-import-redirector 9fans.net/go https://github.com/9fans/go
//
// then the response for 9fans.net/go/acme/editinacme will include these tags:
//
//	<meta name="go-import" content="9fans.net/go git https://github.com/9fans/go">
//	<meta http-equiv="refresh" content="0; url=https://godoc.org/9fans.net/go/acme/editinacme">
//
// If both <import> and <repo> end in /*, the corresponding path element
// is taken from the import path and substituted in repo on each request.
// For example, if invoked as:
//
//	go-import-redirector rsc.io/* https://github.com/rsc/*
//
// then the response for rsc.io/x86/x86asm will include these tags:
//
//	<meta name="go-import" content="rsc.io/x86 git https://github.com/rsc/x86">
//	<meta http-equiv="refresh" content="0; url=https://godoc.org/rsc.io/x86/x86asm">
//
// Note that the wildcard element (x86) has been included in the Git repo path.
//
// The -addr option specifies the HTTP address to serve (default ``:http'').
//
// The -tls option causes go-import-redirector to serve HTTPS on port 443,
// loading an X.509 certificate and key pair from files in the current directory
// named after the host in the import path with .crt and .key appended
// (for example, rsc.io.crt and rsc.io.key).
// Like for http.ListenAndServeTLS, the certificate file should contain the
// concatenation of the server's certificate and the signing certificate authority's certificate.
//
// The -vcs option specifies the version control system, git, hg, or svn (default ``git'').
//
// Deployment on Google Cloud Platform
//
// For the case of a redirector for an entire domain (such as rsc.io above),
// the Makefile in this directory contains recipes to deploy a trivial VM running
// just this program, using a static IP address that can be loaded into the
// DNS configuration for the target domain.
//
package main

import (
	"bytes"
	"flag"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"os"
	"strings"
)

var (
	addr       = flag.String("addr", ":http", "serve http on `address`")
	serveTLS   = flag.Bool("tls", false, "serve https on :443")
	vcs        = flag.String("vcs", "git", "set version control `system`")
	godoc      = flag.String("godoc", "https://godoc.org/", "godoc redirect address")
	importPath string
	repoPath   string
	wildcard   bool
)

func usage() {
	fmt.Fprintf(os.Stderr, "usage: go-import-redirector <import> <repo>\n")
	fmt.Fprintf(os.Stderr, "options:\n")
	flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, "examples:\n")
	fmt.Fprintf(os.Stderr, "\tgo-import-redirector rsc.io/* https://github.com/rsc/*\n")
	fmt.Fprintf(os.Stderr, "\tgo-import-redirector 9fans.net/go https://github.com/9fans/go\n")
	os.Exit(2)
}

func main() {
	log.SetFlags(0)
	log.SetPrefix("go-import-redirector: ")
	flag.Usage = usage
	flag.Parse()
	if flag.NArg() != 2 {
		flag.Usage()
	}
	importPath = flag.Arg(0)
	repoPath = flag.Arg(1)
	if !strings.Contains(repoPath, "://") {
		log.Fatal("repo path must be full URL")
	}
	if strings.HasSuffix(importPath, "/*") != strings.HasSuffix(repoPath, "/*") {
		log.Fatal("either both import and repo must have /* or neither")
	}
	if strings.HasSuffix(importPath, "/*") {
		wildcard = true
		importPath = strings.TrimSuffix(importPath, "/*")
		repoPath = strings.TrimSuffix(repoPath, "/*")
	}
	http.HandleFunc(strings.TrimSuffix(importPath, "/")+"/", redirect)
	if *serveTLS {
		host := importPath
		if i := strings.Index(host, "/"); i >= 0 {
			host = host[:i]
		}
		go func() {
			log.Fatal(http.ListenAndServeTLS(":https", host+".crt", host+".key", nil))
		}()
	}
	log.Fatal(http.ListenAndServe(*addr, nil))
}

var tmpl = template.Must(template.New("main").Parse(`<!DOCTYPE html>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="go-import" content="{{.ImportRoot}} {{.VCS}} {{.VCSRoot}}">
<meta http-equiv="refresh" content="0; url={{.GoDoc}}">

Nothing to see here; move along.

`))

type data struct {
	ImportRoot string
	VCS        string
	VCSRoot    string
	GoDoc      template.URL
}

func redirect(w http.ResponseWriter, req *http.Request) {
	path := strings.TrimSuffix(req.Host+req.URL.Path, "/")
	var importRoot, repoRoot, suffix string
	if wildcard {
		if path == importPath {
			http.Redirect(w, req, "https://godoc.org/"+importPath, 302)
			return
		}
		if !strings.HasPrefix(path, importPath+"/") {
			http.NotFound(w, req)
			return
		}
		elem := path[len(importPath)+1:]
		if i := strings.Index(elem, "/"); i >= 0 {
			elem, suffix = elem[:i], elem[i:]
		}
		importRoot = importPath + "/" + elem
		repoRoot = repoPath + "/" + elem
	} else {
		if path != importPath && !strings.HasPrefix(path, importPath+"/") {
			http.NotFound(w, req)
			return
		}
		importRoot = importPath
		repoRoot = repoPath
		suffix = path[len(importPath):]
	}
	goDocURL := template.URL(*godoc + importRoot + suffix)
	d := &data{
		ImportRoot: importRoot,
		VCS:        *vcs,
		VCSRoot:    repoRoot,
		GoDoc:      goDocURL,
	}
	var buf bytes.Buffer
	err := tmpl.Execute(&buf, d)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	w.Write(buf.Bytes())
}
<|endoftext|>


<commit_before>package main

import (
	"html/template"
	"log"
	"net/http"
	"google.golang.org/appengine"
)

//Type template from Package Template
var tpl *template.Template

//pageData type with underlying type struct
//Title and title are different. title would be unexported and could not be used in a template
//Title is exported due to capalization of the first letter.

type pageData struct {
	Title string
	FirstName string
}

func init() {
	//needs relative reference
	tpl = template.Must(template.ParseGlob("gohtml-templates/*.gohtml"))
	http.HandleFunc("/", idx)
	//http.HandleFunc("/index", idx)
	http.HandleFunc("/about", about)
	http.HandleFunc("/contact", contact)
	http.HandleFunc("/apply", apply)
	http.HandleFunc("/redirect", redirect)
	http.HandleFunc("/favicon.ico", favicon)
	http.Handle("/public", http.FileServer(http.Dir("./go-pub")))
}

func main() {
	appengine.Main()
}

func idx(w http.ResponseWriter, req *http.Request) {

	pd := pageData{
		Title: "Index Page",
	}

	//Denies any other requests except GET
	if req.Method != "GET" {
		http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
		return
	}

	err := tpl.ExecuteTemplate(w, "index.gohtml", pd)
	if err != nil {
		//Println is Printline
		log.Println(err)
		http.Error(w, "Internal Server error", http.StatusInternalServerError)
		return
	}
}

func about(w http.ResponseWriter, req *http.Request) {

	pd := pageData{
		Title: "About Page",
	}

	err := tpl.ExecuteTemplate(w, "about.gohtml", pd)
	if err != nil {
		log.Println(err)
		http.Error(w, "Internal Server error", http.StatusInternalServerError)
		return
	}
}

func contact(w http.ResponseWriter, req *http.Request) {

	pd := pageData{
		Title: "Contact Page",
	}

	err := tpl.ExecuteTemplate(w, "contact.gohtml", pd)
	if err != nil {
		log.Println(err)
		http.Error(w, "Internal Server error", http.StatusInternalServerError)
		return
	}
}

func apply(w http.ResponseWriter, req *http.Request) {
	var first string

	pd := pageData{
		Title: "Apply Page",
	}

	// Wenn die HTTP-Methode POST anstatt GET ist dann führe folgendes aus
	//req.Method ist der http-Request der eine Konstante hat
	if req.Method == http.MethodPost {
		//single equal sign because we are not initializing the variable
		first = req.FormValue("fname")
		pd.FirstName = first
	}

	err := tpl.ExecuteTemplate(w, "apply.gohtml", pd)
	if err != nil {
		log.Println(err)
		http.Error(w, "Internal Server error", http.StatusInternalServerError)
		return
	}
}

func redirect(w http.ResponseWriter, req *http.Request) {
	http.Redirect(w, req, "/contact", http.StatusSeeOther)
}

//func public(w http.ResponseWriter, req *http.Request) {
//	http.FileServer(http.Dir("./go-pub"))
//}

func favicon (w http.ResponseWriter, req *http.Request) {
	http.ServeFile(w, req, "./favicon.ico")
}<commit_msg>fixed serving of public resources<commit_after>package main

import (
	"html/template"
	"log"
	"net/http"
	"google.golang.org/appengine"
)

//Type template from Package Template
var tpl *template.Template

//pageData type with underlying type struct
//Title and title are different. title would be unexported and could not be used in a template
//Title is exported due to capalization of the first letter.

type pageData struct {
	Title string
	FirstName string
}

func init() {
	//needs relative reference
	tpl = template.Must(template.ParseGlob("gohtml-templates/*.gohtml"))
	http.HandleFunc("/", idx)
	//http.HandleFunc("/index", idx)
	http.HandleFunc("/about", about)
	http.HandleFunc("/contact", contact)
	http.HandleFunc("/apply", apply)
	http.HandleFunc("/redirect", redirect)
	http.HandleFunc("/favicon.ico", favicon)
	http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("./go-pub"))))
}

func main() {
	appengine.Main()
}

func idx(w http.ResponseWriter, req *http.Request) {

	pd := pageData{
		Title: "Index Page",
	}

	//Denies any other requests except GET
	if req.Method != "GET" {
		http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
		return
	}

	err := tpl.ExecuteTemplate(w, "index.gohtml", pd)
	if err != nil {
		//Println is Printline
		log.Println(err)
		http.Error(w, "Internal Server error", http.StatusInternalServerError)
		return
	}
}

func about(w http.ResponseWriter, req *http.Request) {

	pd := pageData{
		Title: "About Page",
	}

	err := tpl.ExecuteTemplate(w, "about.gohtml", pd)
	if err != nil {
		log.Println(err)
		http.Error(w, "Internal Server error", http.StatusInternalServerError)
		return
	}
}

func contact(w http.ResponseWriter, req *http.Request) {

	pd := pageData{
		Title: "Contact Page",
	}

	err := tpl.ExecuteTemplate(w, "contact.gohtml", pd)
	if err != nil {
		log.Println(err)
		http.Error(w, "Internal Server error", http.StatusInternalServerError)
		return
	}
}

func apply(w http.ResponseWriter, req *http.Request) {
	var first string

	pd := pageData{
		Title: "Apply Page",
	}

	// Wenn die HTTP-Methode POST anstatt GET ist dann führe folgendes aus
	//req.Method ist der http-Request der eine Konstante hat
	if req.Method == http.MethodPost {
		//single equal sign because we are not initializing the variable
		first = req.FormValue("fname")
		pd.FirstName = first
	}

	err := tpl.ExecuteTemplate(w, "apply.gohtml", pd)
	if err != nil {
		log.Println(err)
		http.Error(w, "Internal Server error", http.StatusInternalServerError)
		return
	}
}

func redirect(w http.ResponseWriter, req *http.Request) {
	http.Redirect(w, req, "/contact", http.StatusSeeOther)
}

func favicon (w http.ResponseWriter, req *http.Request) {
	http.ServeFile(w, req, "./favicon.ico")
}<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"os/exec"
	"syscall"

	"github.com/dotcloud/docker/pkg/user"
)

const VERSION = "1.0"

func main() {
	log.SetFlags(0) // no timestamps on our logs

	if len(os.Args) <= 2 {
		log.Printf("Usage: %s user-spec command [args]", os.Args[0])
		log.Printf("   ie: %s tianon bash", os.Args[0])
		log.Printf("       %s nobody:root bash -c 'whoami && id'", os.Args[0])
		log.Printf("       %s 1000:1 id", os.Args[0])
		log.Printf("%s version: %s", os.Args[0], VERSION)
		os.Exit(1)
	}

	uid, gid, suppGids, err := user.GetUserGroupSupplementary(os.Args[1], syscall.Getuid(), syscall.Getgid())
	if err != nil {
		log.Fatalf("error: failed parsing '%s': %v", os.Args[1], err)
	}

	if err := syscall.Setgroups(suppGids); err != nil {
		log.Fatalf("error: failed to setgroups: %v", err)
	}
	if err := syscall.Setgid(gid); err != nil {
		log.Fatalf("error: failed to setgid: %v", err)
	}
	if err := syscall.Setuid(uid); err != nil {
		log.Fatalf("error: failed to setuid: %v", err)
	}

	name, err := exec.LookPath(os.Args[2])
	if err != nil {
		log.Fatalf("error: %v", err)
	}

	err = syscall.Exec(name, os.Args[2:], os.Environ())
	if err != nil {
		log.Fatalf("error: exec failed: %v", err)
	}
}
<commit_msg>add LockOSThread and explicit GOMAXPROCS to ensure even more explicitly that we're running in the same thread for the duration<commit_after>package main

import (
	"log"
	"os"
	"os/exec"
	"runtime"
	"syscall"

	"github.com/dotcloud/docker/pkg/user"
)

const VERSION = "1.0"

func init() {
	// make sure we only have one process and that it runs on the main thread (so that ideally, when we Exec, we keep our user switches and stuff)
	runtime.GOMAXPROCS(1)
	runtime.LockOSThread()
}

func main() {
	log.SetFlags(0) // no timestamps on our logs

	if len(os.Args) <= 2 {
		log.Printf("Usage: %s user-spec command [args]", os.Args[0])
		log.Printf("   ie: %s tianon bash", os.Args[0])
		log.Printf("       %s nobody:root bash -c 'whoami && id'", os.Args[0])
		log.Printf("       %s 1000:1 id", os.Args[0])
		log.Printf("%s version: %s", os.Args[0], VERSION)
		os.Exit(1)
	}

	uid, gid, suppGids, err := user.GetUserGroupSupplementary(os.Args[1], syscall.Getuid(), syscall.Getgid())
	if err != nil {
		log.Fatalf("error: failed parsing '%s': %v", os.Args[1], err)
	}

	if err := syscall.Setgroups(suppGids); err != nil {
		log.Fatalf("error: failed to setgroups: %v", err)
	}
	if err := syscall.Setgid(gid); err != nil {
		log.Fatalf("error: failed to setgid: %v", err)
	}
	if err := syscall.Setuid(uid); err != nil {
		log.Fatalf("error: failed to setuid: %v", err)
	}

	name, err := exec.LookPath(os.Args[2])
	if err != nil {
		log.Fatalf("error: %v", err)
	}

	err = syscall.Exec(name, os.Args[2:], os.Environ())
	if err != nil {
		log.Fatalf("error: exec failed: %v", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"code.google.com/p/gcfg"
	"compress/gzip"
	"encoding/json"
	"fmt"
	"github.com/boredomist/mixport/exports"
	"github.com/boredomist/mixport/mixpanel"
	flag "github.com/ogier/pflag"
	kinesis "github.com/sendgridlabs/go-kinesis"
	"io"
	"log"
	"os"
	"path"
	"runtime"
	"runtime/pprof"
	"strings"
	"sync"
	"syscall"
	"time"
)

// Mixpanel API credentials, used by the configuration parser.
type mixpanelCredentials struct {
	Key    string
	Secret string
	Token  string
}

// fileExportConfig contains configuration options common to the file export
// streams (CSV and JSON).
type fileExportConfig struct {
	State     bool
	Gzip      bool
	Fifo      bool
	Directory string
}

// columnExportConfig contains configuration options for the CSV with columns
// export type. It is a superset of the more general `fileExportConfig`.
//
// - `Columns` is the path to a JSON file containing the mapping of events to
//   the columns to include in the CSV output.
type columnExportConfig struct {
	fileExportConfig
	Columns string
}

// configFormat is the in-memory representation of the mixport configuration
// file.
//
// - `Product` is Mixpanel API credential information for each product that
//   will be exported.
// - `Kinesis` is access keys and configuration for Amazon Kinesis exporter.
// - `JSON` and `CSV` are the configuration setups for the `JSON` and `CSV`
//   exporters, respectively.
// - `Columns` is the configuration for the `CSV column` export type.
type configFormat struct {
	Product map[string]*mixpanelCredentials
	Kinesis struct {
		State     bool
		Keyid     string
		Secretkey string
		Stream    string
		Region    string
	}

	JSON    fileExportConfig
	CSV     fileExportConfig
	Columns columnExportConfig
}

// exportConfig simply bundles together the variables describing the export of
// a single Mixpanel product to reduce a bit of noise in helper function type
// signatures.
type exportConfig struct {
	Product    string
	Creds      mixpanelCredentials
	Start, End time.Time
}

// Holds parsed configuration file
var cfg = configFormat{}

// Will be set to true when an export goroutine fails (to set exit status).
var exportFailed = false

func main() {

	var (
		configFile  = flag.StringP("config", "c", "./mixport.conf", "path to configuration file")
		dateString  = flag.StringP("date", "d", "", "date of data to pull in YYYY/MM/DD, default is yesterday")
		rangeString = flag.StringP("range", "r", "", "date range to pull in YYYY/MM/DD-YYYY/MM/DD")
		cpuProfile  = flag.String("prof", "", "dump pprof info to a file.")
		productList = flag.String("products", "", "comma separated list of products to export.")
		maxProcs    = flag.IntP("procs", "p", runtime.NumCPU(), "maximum number of OS threads to spawn.")
	)

	flag.Parse()

	runtime.GOMAXPROCS(*maxProcs)

	if *cpuProfile != "" {
		f, err := os.Create(*cpuProfile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if err := gcfg.ReadFileInto(&cfg, *configFile); err != nil {
		log.Fatalf("Failed to load %s: %s", *configFile, err)
	}

	var exportStart, exportEnd time.Time

	// Default to yesterday (should be newest available data)
	if *dateString == "" {
		year, month, day := time.Now().UTC().AddDate(0, 0, -1).Date()

		exportStart = time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
		exportEnd = exportStart
	} else {
		if d, err := time.Parse("2006/01/02", *dateString); err != nil {
			log.Fatalf("Invalid date: %s, should be in YYYY/MM/DD format",
				*dateString)
		} else {
			exportStart = d
			exportEnd = exportStart
		}
	}

	if *rangeString != "" {
		formatError := func() {
			log.Fatalf("Invalid range: %s, should be YYYY/MM/DD-YYYY/MM/DD.", *rangeString)
		}

		parts := strings.Split(*rangeString, "-")

		if len(parts) != 2 {
			formatError()
		}

		var err error

		if exportStart, err = time.Parse("2006/01/02", parts[0]); err != nil {
			formatError()
		}

		if exportEnd, err = time.Parse("2006/01/02", parts[1]); err != nil {
			formatError()
		}

	}

	products := make(map[string]*mixpanelCredentials)

	// If not explicitly specified, export all products in the config
	if *productList == "" {
		products = cfg.Product
	} else {
		for _, name := range strings.Split(*productList, ",") {
			if creds, ok := cfg.Product[name]; ok {
				products[name] = creds
			} else {
				log.Fatalf("Don't have credentials specified for %s", name)
			}
		}
	}

	// WaitGroup will hold the process open until all of the child
	// goroutines have completed execution.
	var wg sync.WaitGroup
	wg.Add(len(products))

	// Run each individual product export in a new goroutine.
	for product, creds := range products {
		go exportProduct(exportConfig{product, *creds, exportStart, exportEnd}, &wg)
	}

	// Wait for all our goroutines to finish up
	wg.Wait()

	if exportFailed {
		log.Fatalf("Export finished with errors.")
	}
}

// createExportFile abstracts the handling of configuration variables common to
// `csv`, `json`, and `columns` into a single function.
//
// The returned tuple contains:
//   - A generic io.Writer which will be passed off to the export function.
//   - A function taking no arguments which should be called after the export
//     function finishes (using defer) to do any necessary cleanup, depending
//     on the specified configuration options.
func createExportFile(export exportConfig, conf fileExportConfig, suffix, ext string) (io.Writer, func()) {
	if conf.Gzip {
		ext += ".gz"
	}

	start, end := export.Start, export.End

	timeFmt := "20060102"
	stamp := start.Format(timeFmt)

	// Append end date to timestamp if we're using a date range.
	if start != end {
		stamp += fmt.Sprintf("-%s", end.Format(timeFmt))
	}

	name := path.Join(conf.Directory, fmt.Sprintf("%s%s-%s.%s", export.Product, suffix, stamp, ext))

	if conf.Fifo {
		if err := syscall.Mkfifo(name, syscall.S_IRWXU); err != nil {
			log.Fatalf("Couldn't create named pipe: %s", err)
		}
	}

	fp, err := os.Create(name)
	if err != nil {
		log.Fatalf("Couldn't create file: %s", err)
	}

	writer := (io.Writer)(fp)
	if conf.Gzip {
		writer = gzip.NewWriter(fp)
	}

	cleanup := func() {
		if conf.Gzip {
			(writer).(*gzip.Writer).Close()
		}

		fp.Close()

		if conf.Fifo {
			os.Remove(name)
		}
	}

	return writer, cleanup
}

// exportProduct is called once for each individual mixpanel product to be
// exported. It starts each export function in its own goroutine and will block
// until all events have been processed.
func exportProduct(export exportConfig, wg *sync.WaitGroup) {
	defer wg.Done()

	client := mixpanel.New(export.Product, export.Creds.Key, export.Creds.Secret)
	eventData := make(chan mixpanel.EventData)

	// We need to mux eventData into multiple channels to ensure all export
	// funcs have a chance to see each event instance.
	var chans []chan mixpanel.EventData

	if cfg.Kinesis.State {
		ch := make(chan mixpanel.EventData)
		chans = append(chans, ch)

		ksis := kinesis.New(cfg.Kinesis.Keyid, cfg.Kinesis.Secretkey)
		if cfg.Kinesis.Region != "" {
			ksis.Region = "us-east-1"
		}

		wg.Add(1)
		go func() {
			defer wg.Done()
			exports.KinesisStreamer(ksis, cfg.Kinesis.Stream, ch)
		}()
	}

	if cfg.JSON.State {
		ch := make(chan mixpanel.EventData)
		chans = append(chans, ch)

		wg.Add(1)
		go func() {
			defer wg.Done()

			writer, cleanup := createExportFile(export, cfg.JSON, "", "json")
			defer cleanup()

			exports.JSONStreamer(writer, ch)
		}()
	}

	if cfg.CSV.State {
		ch := make(chan mixpanel.EventData)
		chans = append(chans, ch)

		wg.Add(1)
		go func() {
			defer wg.Done()

			writer, cleanup := createExportFile(export, cfg.CSV, "", "csv")
			defer cleanup()

			exports.CSVStreamer(writer, ch)
		}()
	}

	if cfg.Columns.State {
		fp, err := os.Open(cfg.Columns.Columns)

		if err != nil {
			log.Fatalf("Couldn't open column defintions: %v", err)
		}

		// We expect a single map in the file of the form:
		//   {"product": {"event": ["columns", ...], ...}, ...}
		columns := make(map[string]map[string][]string)

		if err := json.NewDecoder(fp).Decode(&columns); err != nil {
			log.Fatalf("Failed to read column definitions: %v", err)
		}

		fp.Close()

		// Not much sense in consuming the stream if we have no events
		// to actually capture.
		if prodCols, ok := columns[export.Product]; ok {
			defs := make(map[string]exports.EventColumnDef)
			fileConf := cfg.Columns.fileExportConfig

			for event, cols := range prodCols {
				w, cleanupFunc := createExportFile(export, fileConf, event, "csv")
				defer cleanupFunc()

				defs[event] = exports.NewEventColumnDef(w, cols)
			}

			ch := make(chan mixpanel.EventData)
			chans = append(chans, ch)

			wg.Add(1)
			go func() {
				defer wg.Done()
				exports.CSVColumnStreamer(defs, ch)
			}()
		}
	}

	go func() {
		defer close(eventData)

		// We want it to be start-end inclusive, so add one day to end date.
		end := export.End.AddDate(0, 0, 1)

		for date := export.Start; date.Before(end); date = date.AddDate(0, 0, 1) {
			if err := client.ExportDate(date, eventData, nil); err != nil {
				log.Printf("export failed: %v", err)
				exportFailed = true
				break
			}
		}
	}()

	// Multiplex each received event to each of the active export funcs.
	for data := range eventData {
		for _, ch := range chans {
			ch <- data
		}
	}

	// Closing all the channels will signal the streaming export functions
	// that they've reached the end of the stream and should terminate as
	// soon as the channel is drained.
	for _, ch := range chans {
		close(ch)
	}
}
<commit_msg>Use buffered channels for export functions<commit_after>package main

import (
	"code.google.com/p/gcfg"
	"compress/gzip"
	"encoding/json"
	"fmt"
	"github.com/boredomist/mixport/exports"
	"github.com/boredomist/mixport/mixpanel"
	flag "github.com/ogier/pflag"
	kinesis "github.com/sendgridlabs/go-kinesis"
	"io"
	"log"
	"os"
	"path"
	"runtime"
	"runtime/pprof"
	"strings"
	"sync"
	"syscall"
	"time"
)

// Mixpanel API credentials, used by the configuration parser.
type mixpanelCredentials struct {
	Key    string
	Secret string
	Token  string
}

// fileExportConfig contains configuration options common to the file export
// streams (CSV and JSON).
type fileExportConfig struct {
	State     bool
	Gzip      bool
	Fifo      bool
	Directory string
}

// columnExportConfig contains configuration options for the CSV with columns
// export type. It is a superset of the more general `fileExportConfig`.
//
// - `Columns` is the path to a JSON file containing the mapping of events to
//   the columns to include in the CSV output.
type columnExportConfig struct {
	fileExportConfig
	Columns string
}

// configFormat is the in-memory representation of the mixport configuration
// file.
//
// - `Product` is Mixpanel API credential information for each product that
//   will be exported.
// - `Kinesis` is access keys and configuration for Amazon Kinesis exporter.
// - `JSON` and `CSV` are the configuration setups for the `JSON` and `CSV`
//   exporters, respectively.
// - `Columns` is the configuration for the `CSV column` export type.
type configFormat struct {
	Product map[string]*mixpanelCredentials
	Kinesis struct {
		State     bool
		Keyid     string
		Secretkey string
		Stream    string
		Region    string
	}

	JSON    fileExportConfig
	CSV     fileExportConfig
	Columns columnExportConfig
}

// exportConfig simply bundles together the variables describing the export of
// a single Mixpanel product to reduce a bit of noise in helper function type
// signatures.
type exportConfig struct {
	Product    string
	Creds      mixpanelCredentials
	Start, End time.Time
}

// Holds parsed configuration file
var cfg = configFormat{}

// Will be set to true when an export goroutine fails (to set exit status).
var exportFailed = false

func main() {

	var (
		configFile  = flag.StringP("config", "c", "./mixport.conf", "path to configuration file")
		dateString  = flag.StringP("date", "d", "", "date of data to pull in YYYY/MM/DD, default is yesterday")
		rangeString = flag.StringP("range", "r", "", "date range to pull in YYYY/MM/DD-YYYY/MM/DD")
		cpuProfile  = flag.String("prof", "", "dump pprof info to a file.")
		productList = flag.String("products", "", "comma separated list of products to export.")
		maxProcs    = flag.IntP("procs", "p", runtime.NumCPU(), "maximum number of OS threads to spawn.")
	)

	flag.Parse()

	runtime.GOMAXPROCS(*maxProcs)

	if *cpuProfile != "" {
		f, err := os.Create(*cpuProfile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if err := gcfg.ReadFileInto(&cfg, *configFile); err != nil {
		log.Fatalf("Failed to load %s: %s", *configFile, err)
	}

	var exportStart, exportEnd time.Time

	// Default to yesterday (should be newest available data)
	if *dateString == "" {
		year, month, day := time.Now().UTC().AddDate(0, 0, -1).Date()

		exportStart = time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
		exportEnd = exportStart
	} else {
		if d, err := time.Parse("2006/01/02", *dateString); err != nil {
			log.Fatalf("Invalid date: %s, should be in YYYY/MM/DD format",
				*dateString)
		} else {
			exportStart = d
			exportEnd = exportStart
		}
	}

	if *rangeString != "" {
		formatError := func() {
			log.Fatalf("Invalid range: %s, should be YYYY/MM/DD-YYYY/MM/DD.", *rangeString)
		}

		parts := strings.Split(*rangeString, "-")

		if len(parts) != 2 {
			formatError()
		}

		var err error

		if exportStart, err = time.Parse("2006/01/02", parts[0]); err != nil {
			formatError()
		}

		if exportEnd, err = time.Parse("2006/01/02", parts[1]); err != nil {
			formatError()
		}

	}

	products := make(map[string]*mixpanelCredentials)

	// If not explicitly specified, export all products in the config
	if *productList == "" {
		products = cfg.Product
	} else {
		for _, name := range strings.Split(*productList, ",") {
			if creds, ok := cfg.Product[name]; ok {
				products[name] = creds
			} else {
				log.Fatalf("Don't have credentials specified for %s", name)
			}
		}
	}

	// WaitGroup will hold the process open until all of the child
	// goroutines have completed execution.
	var wg sync.WaitGroup
	wg.Add(len(products))

	// Run each individual product export in a new goroutine.
	for product, creds := range products {
		go exportProduct(exportConfig{product, *creds, exportStart, exportEnd}, &wg)
	}

	// Wait for all our goroutines to finish up
	wg.Wait()

	if exportFailed {
		log.Fatalf("Export finished with errors.")
	}
}

// createExportFile abstracts the handling of configuration variables common to
// `csv`, `json`, and `columns` into a single function.
//
// The returned tuple contains:
//   - A generic io.Writer which will be passed off to the export function.
//   - A function taking no arguments which should be called after the export
//     function finishes (using defer) to do any necessary cleanup, depending
//     on the specified configuration options.
func createExportFile(export exportConfig, conf fileExportConfig, suffix, ext string) (io.Writer, func()) {
	if conf.Gzip {
		ext += ".gz"
	}

	start, end := export.Start, export.End

	timeFmt := "20060102"
	stamp := start.Format(timeFmt)

	// Append end date to timestamp if we're using a date range.
	if start != end {
		stamp += fmt.Sprintf("-%s", end.Format(timeFmt))
	}

	name := path.Join(conf.Directory, fmt.Sprintf("%s%s-%s.%s", export.Product, suffix, stamp, ext))

	if conf.Fifo {
		if err := syscall.Mkfifo(name, syscall.S_IRWXU); err != nil {
			log.Fatalf("Couldn't create named pipe: %s", err)
		}
	}

	fp, err := os.Create(name)
	if err != nil {
		log.Fatalf("Couldn't create file: %s", err)
	}

	writer := (io.Writer)(fp)
	if conf.Gzip {
		writer = gzip.NewWriter(fp)
	}

	cleanup := func() {
		if conf.Gzip {
			(writer).(*gzip.Writer).Close()
		}

		fp.Close()

		if conf.Fifo {
			os.Remove(name)
		}
	}

	return writer, cleanup
}

// exportProduct is called once for each individual mixpanel product to be
// exported. It starts each export function in its own goroutine and will block
// until all events have been processed.
func exportProduct(export exportConfig, wg *sync.WaitGroup) {
	defer wg.Done()

	client := mixpanel.New(export.Product, export.Creds.Key, export.Creds.Secret)
	eventData := make(chan mixpanel.EventData)

	// We need to mux eventData into multiple channels to ensure all export
	// funcs have a chance to see each event instance.
	var chans []chan mixpanel.EventData

	makeChan := func() chan mixpanel.EventData {
		// Using buffered channels so that a slower receiver won't
		// block a quicker one.
		c := make(chan mixpanel.EventData, 100)
		chans = append(chans, c)

		return c
	}

	if cfg.Kinesis.State {
		c := makeChan()

		ksis := kinesis.New(cfg.Kinesis.Keyid, cfg.Kinesis.Secretkey)
		if cfg.Kinesis.Region != "" {
			ksis.Region = "us-east-1"
		}

		wg.Add(1)
		go func() {
			defer wg.Done()
			exports.KinesisStreamer(ksis, cfg.Kinesis.Stream, c)
		}()
	}

	if cfg.JSON.State {
		c := makeChan()

		wg.Add(1)
		go func() {
			defer wg.Done()

			writer, cleanup := createExportFile(export, cfg.JSON, "", "json")
			defer cleanup()

			exports.JSONStreamer(writer, c)
		}()
	}

	if cfg.CSV.State {
		c := makeChan()

		wg.Add(1)
		go func() {
			defer wg.Done()

			writer, cleanup := createExportFile(export, cfg.CSV, "", "csv")
			defer cleanup()

			exports.CSVStreamer(writer, c)
		}()
	}

	if cfg.Columns.State {
		fp, err := os.Open(cfg.Columns.Columns)

		if err != nil {
			log.Fatalf("Couldn't open column defintions: %v", err)
		}

		// We expect a single map in the file of the form:
		//   {"product": {"event": ["columns", ...], ...}, ...}
		columns := make(map[string]map[string][]string)

		if err := json.NewDecoder(fp).Decode(&columns); err != nil {
			log.Fatalf("Failed to read column definitions: %v", err)
		}

		fp.Close()

		// Not much sense in consuming the stream if we have no events
		// to actually capture.
		if prodCols, ok := columns[export.Product]; ok {
			defs := make(map[string]exports.EventColumnDef)
			fileConf := cfg.Columns.fileExportConfig

			for event, cols := range prodCols {
				w, cleanupFunc := createExportFile(export, fileConf, event, "csv")
				defer cleanupFunc()

				defs[event] = exports.NewEventColumnDef(w, cols)
			}

			c := makeChan()

			wg.Add(1)
			go func() {
				defer wg.Done()
				exports.CSVColumnStreamer(defs, c)
			}()
		}
	}

	go func() {
		defer close(eventData)

		// We want it to be start-end inclusive, so add one day to end date.
		end := export.End.AddDate(0, 0, 1)

		for date := export.Start; date.Before(end); date = date.AddDate(0, 0, 1) {
			if err := client.ExportDate(date, eventData, nil); err != nil {
				log.Printf("export failed: %v", err)
				exportFailed = true
				break
			}
		}
	}()

	// Multiplex each received event to each of the active export funcs.
	for data := range eventData {
		for _, ch := range chans {
			ch <- data
		}
	}

	// Closing all the channels will signal the streaming export functions
	// that they've reached the end of the stream and should terminate as
	// soon as the channel is drained.
	for _, ch := range chans {
		close(ch)
	}
}
<|endoftext|>


<commit_before>package main

import (
	config "github.com/poddworks/machine/config"
	mach "github.com/poddworks/machine/lib/machine"

	"github.com/poddworks/machine/driver/aws"
	"github.com/poddworks/machine/driver/swarm"

	"github.com/urfave/cli"

	"fmt"
	"math/rand"
	"os"
	"time"
)

const (
	DEFAULT_CONFIG_DIR = "~/.machine"

	DEFAULT_ORGANIZATION_PLACEMENT_NAME = "podd.org"

	DEFAULT_MACHINE_PORT = "22"
)

func init() {
	rand.Seed(time.Now().Unix())
}

func main() {
	app := cli.NewApp()
	app.Version = "1.0.0"
	app.Name = "machine"
	app.Usage = "Swiss Army knife for DevOps"
	app.EnableBashCompletion = true
	app.Authors = []cli.Author{
		cli.Author{"Yi-Hung Jen", "yihungjen@gmail.com"},
	}
	app.Commands = []cli.Command{
		CreateCommand(),
		InstanceCommand("start", "Start"),
		InstanceCommand("stop", "Stop"),
		InstanceCommand("reboot", "Reboot"),
		InstanceCommand("rm", "Remove And Terminate"),
		ListInstanceCommand(),
		IPCommand(),
		EnvCommand(),
		ExecCommand(),
		SSHCommand(),
		TlsCommand(),
		DnstoolCommand(),
		aws.NewCommand(),
		swarm.NewCommand(),
		RecipeCommand(),
	}
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "user", EnvVar: "MACHINE_USER", Usage: "Run command as user"},
		cli.StringFlag{Name: "cert", EnvVar: "MACHINE_CERT_FILE", Usage: "Private key to use in Authentication"},
		cli.StringFlag{Name: "port", EnvVar: "MACHINE_PORT", Value: DEFAULT_MACHINE_PORT, Usage: "Connected to ssh port"},
		cli.StringFlag{Name: "org", Value: DEFAULT_ORGANIZATION_PLACEMENT_NAME, Usage: "Organization for Self Signed CA"},
		cli.StringFlag{Name: "confdir", Value: DEFAULT_CONFIG_DIR, Usage: "Configuration and Certificate path"},
	}
	app.Before = func(c *cli.Context) error {
		if err := config.Parse(c); err != nil {
			return cli.NewExitError("error/failed-to-parse-config", 1)
		}
		if err := mach.InstList.Load(); err != nil {
			return cli.NewExitError("error/failed-to-load-cache-instance", 1)
		}
		return nil
	}
	app.BashComplete = func(c *cli.Context) {
		// List available commands
		for _, cmd := range app.Commands {
			fmt.Fprint(c.App.Writer, " ", cmd.Name)
		}
	}
	app.Run(os.Args)
}
<commit_msg>Release 1.2.0<commit_after>package main

import (
	config "github.com/poddworks/machine/config"
	mach "github.com/poddworks/machine/lib/machine"

	"github.com/poddworks/machine/driver/aws"
	"github.com/poddworks/machine/driver/swarm"

	"github.com/urfave/cli"

	"fmt"
	"math/rand"
	"os"
	"time"
)

const (
	DEFAULT_CONFIG_DIR = "~/.machine"

	DEFAULT_ORGANIZATION_PLACEMENT_NAME = "podd.org"

	DEFAULT_MACHINE_PORT = "22"
)

func init() {
	rand.Seed(time.Now().Unix())
}

func main() {
	app := cli.NewApp()
	app.Version = "1.2.0"
	app.Name = "machine"
	app.Usage = "Swiss Army knife for DevOps"
	app.EnableBashCompletion = true
	app.Authors = []cli.Author{
		cli.Author{"Yi-Hung Jen", "yihungjen@gmail.com"},
	}
	app.Commands = []cli.Command{
		CreateCommand(),
		InstanceCommand("start", "Start"),
		InstanceCommand("stop", "Stop"),
		InstanceCommand("reboot", "Reboot"),
		InstanceCommand("rm", "Remove And Terminate"),
		ListInstanceCommand(),
		IPCommand(),
		EnvCommand(),
		ExecCommand(),
		SSHCommand(),
		TlsCommand(),
		DnstoolCommand(),
		aws.NewCommand(),
		swarm.NewCommand(),
		RecipeCommand(),
	}
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "user", EnvVar: "MACHINE_USER", Usage: "Run command as user"},
		cli.StringFlag{Name: "cert", EnvVar: "MACHINE_CERT_FILE", Usage: "Private key to use in Authentication"},
		cli.StringFlag{Name: "port", EnvVar: "MACHINE_PORT", Value: DEFAULT_MACHINE_PORT, Usage: "Connected to ssh port"},
		cli.StringFlag{Name: "org", Value: DEFAULT_ORGANIZATION_PLACEMENT_NAME, Usage: "Organization for Self Signed CA"},
		cli.StringFlag{Name: "confdir", Value: DEFAULT_CONFIG_DIR, Usage: "Configuration and Certificate path"},
	}
	app.Before = func(c *cli.Context) error {
		if err := config.Parse(c); err != nil {
			return cli.NewExitError("error/failed-to-parse-config", 1)
		}
		if err := mach.InstList.Load(); err != nil {
			return cli.NewExitError("error/failed-to-load-cache-instance", 1)
		}
		return nil
	}
	app.BashComplete = func(c *cli.Context) {
		// List available commands
		for _, cmd := range app.Commands {
			fmt.Fprint(c.App.Writer, " ", cmd.Name)
		}
	}
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"

	_ "github.com/lib/pq"

	"github.com/emicklei/go-restful"
	"github.com/manifest-destiny/api/apidocs"
	"github.com/manifest-destiny/api/player"
)

const (
	tlsCert = "keys/tls_cert.crt"
	tlsKey  = "keys/tls_key.key"
)

var (
	dbInfo, port, cert, key string
	tls                     bool
)

func init() {

	dbInfo = fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s",
		os.Getenv("DATABASE_USER"),
		os.Getenv("DATABASE_PASSWORD"),
		os.Getenv("DATABASE_HOST"),
		os.Getenv("DATABASE_NAME"),
		os.Getenv("DATABASE_SSL"))

	port = os.Getenv("API_PORT")
	if port == "" {
		port = "80"
	}

	// write TLS cert and key to file
	os.Remove(tlsKey)
	os.Remove(tlsCert)

	if os.Getenv("TLS_KEY_BASE64") == "" || os.Getenv("TLS_CERTIFICATE_BASE64") == "" {
		tls = false
	} else {
		tls = true
		tlsKeyB, err := base64.StdEncoding.DecodeString(os.Getenv("TLS_KEY_BASE64"))
		fatal(err)
		err = ioutil.WriteFile(tlsKey, tlsKeyB, 0400)
		fatal(err)
		tlsCertB, err := base64.StdEncoding.DecodeString(os.Getenv("TLS_CERTIFICATE_BASE64"))
		fatal(err)
		err = ioutil.WriteFile(tlsCert, tlsCertB, 0400)
		fatal(err)
	}
}

func main() {
	// initialize postgres backend
	db, err := sql.Open("postgres", dbInfo)
	fatal(err)

	defer db.Close()

	// Add store to resource
	p := player.PlayerResource{}

	// Register container
	wsContainer := restful.NewContainer()
	p.Register(wsContainer)

	// Setup api docs
	apidocs.Register(wsContainer, port, tls)

	// Start server
	log.Printf("listening on localhost:%s", port)
	server := &http.Server{Addr: fmt.Sprintf(":%s", port), Handler: wsContainer}
	if tls {
		log.Fatal(server.ListenAndServeTLS(tlsCert, tlsKey))
	} else {
		log.Fatal(server.ListenAndServe())
	}
}

func fatal(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>removing ssl from env variables<commit_after>package main

import (
	"database/sql"
	"fmt"
	"log"
	"net/http"
	"os"

	_ "github.com/lib/pq"

	"github.com/emicklei/go-restful"
	"github.com/manifest-destiny/api/apidocs"
	"github.com/manifest-destiny/api/player"
)

const (
	tlsCert = "keys/tls_cert.crt"
	tlsKey  = "keys/tls_key.key"
)

var (
	dbInfo, port string
	tls          bool
)

func init() {

	dbInfo = fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s",
		os.Getenv("DATABASE_USER"),
		os.Getenv("DATABASE_PASSWORD"),
		os.Getenv("DATABASE_HOST"),
		os.Getenv("DATABASE_NAME"),
		os.Getenv("DATABASE_SSL"))

	port = os.Getenv("API_PORT")
	if os.Getenv("TLS_ENABLED") == "1" {
		tls = true
	} else {
		tls = false
	}

	if port == "" {
		port = "80"
	}
}

func main() {
	// initialize postgres backend
	db, err := sql.Open("postgres", dbInfo)
	fatal(err)

	defer db.Close()

	// Add store to resource
	p := player.PlayerResource{}

	// Register container
	wsContainer := restful.NewContainer()
	p.Register(wsContainer)

	// Setup api docs
	apidocs.Register(wsContainer, port, tls)

	// Start server
	log.Printf("listening on localhost:%s", port)
	server := &http.Server{Addr: fmt.Sprintf(":%s", port), Handler: wsContainer}
	if tls {
		log.Fatal(server.ListenAndServeTLS(tlsCert, tlsKey))
	} else {
		log.Fatal(server.ListenAndServe())
	}
}

func fatal(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>