<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/ConSol/sakuli-go-wrapper/execute"
	"github.com/ConSol/sakuli-go-wrapper/input"
	"os"
	"path/filepath"
	"time"
)

func main() {
	var loop int
	var javaHome string
	var javaProperties input.StringSlice
	var preHooks input.StringSlice
	var postHooks input.StringSlice
	var browser string
	var encrypt string
	var inter string
	var run string
	var sahiHome string
	var sakuliHome string

	if os.Getenv("SAKULI_HOME") == "" {
		panic("SAKULI_HOME environment variable is not set")
	}

	sakuliJars := filepath.Join(os.Getenv("SAKULI_HOME"), "libs", "java")
	originalUsage := flag.Usage
	flag.Usage = func() {
		fmt.Println(`Generic Sakuli test starter.
2016 - The Sakuli team / Philip Griesbacher.
`)
		originalUsage()
	}
	flag.IntVar(&loop, "-loop", 0, "loop this suite, wait n seconds between executions, 0 means no loops (default: 0)")
	flag.StringVar(&javaHome, "-javahome", "", "Java bin dir (overrides PATH)")
	flag.Var(&preHooks, "-preHook", "A programm which will be executed before sakuli (Can be added multiple times)")
	flag.Var(&postHooks, "-postHook", "A programm which will be executed after sakuli (Can be added multiple times)")

	flag.Var(&javaProperties, "D", "JVM option to set a property on runtime, overrides the 'sakuli.properties'")
	flag.StringVar(&browser, "-browser", "", "(optional) browser for the test execution (default: Firefox)")
	flag.StringVar(&encrypt, "-encrypt", "", "encrypt a secret")
	flag.StringVar(&inter, "-interface", "", "(optional) network interface used for encryption")
	flag.StringVar(&run, "-run", "", "run a sakuli test suite")
	flag.StringVar(&sahiHome, "-sahi_home", "", "(optional) Sahi installation folder")
	flag.StringVar(&sakuliHome, "-sakuli_home", os.Getenv("SAKULI_HOME"), "(optional) SAKULI_HOME folder, default: environment variable 'SAKULI_HOME'")
	flag.Parse()

	input.TestRun(run)

	javaExecutable := input.TestJavaHome(javaHome)
	javaProperties = javaProperties.AddPrefix("-D")
	sakuliProperties := map[string]string{"sakuli_home": sakuliHome}

	if browser != "" {
		sakuliProperties["browser"] = browser
	}
	if inter != "" {
		sakuliProperties["interface"] = inter
	}
	if encrypt != "" {
		sakuliProperties["encrypt"] = encrypt
	}
	if run != "" {
		sakuliProperties["run"] = run
	}
	if sahiHome != "" {
		sakuliProperties["sahiHome"] = sahiHome
	}
	joinedSakuliProperties := genSakuliPropertiesList(sakuliProperties)

	fmt.Println("=========== Starting Pre-Hooks ===========")
	for _, pre := range preHooks {
		execute.RunHandler(pre)
	}
	fmt.Println("=========== Finished Pre-Hooks ===========")

	sakuliReturnCode := execute.RunSakuli(javaExecutable, sakuliJars, javaProperties, joinedSakuliProperties)
	for loop > 0 {
		fmt.Printf("*** Loop mode - sleeping for %d seconds... ***\n", loop)
		time.Sleep(time.Duration(loop) * time.Second)
		execute.RunSakuli(javaExecutable, sakuliJars, javaProperties, joinedSakuliProperties)
	}

	fmt.Println("=========== Starting Post-Hooks ===========")
	for _, post := range postHooks {
		execute.RunHandler(post)
	}
	fmt.Println("=========== Finished Post-Hooks ===========")

	os.Exit(sakuliReturnCode)
}

func genSakuliPropertiesList(properties map[string]string) input.StringSlice {
	propertiesString := []string{}
	for k, v := range properties {
		propertiesString = append(propertiesString, fmt.Sprintf("--%s", k))
		propertiesString = append(propertiesString, v)
	}
	return propertiesString
}
<commit_msg>#150 modify flags<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/ConSol/sakuli-go-wrapper/execute"
	"github.com/ConSol/sakuli-go-wrapper/input"
	"os"
	"path/filepath"
	"time"
)

func main() {
	var loop int
	var javaHome string
	var javaProperties input.StringSlice
	var preHooks input.StringSlice
	var postHooks input.StringSlice
	var browser string
	var encrypt string
	var inter string
	var run string
	var sahiHome string
	var sakuliHome string

	if os.Getenv("SAKULI_HOME") == "" {
		panic("SAKULI_HOME environment variable is not set")
	}

	sakuliJars := filepath.Join(os.Getenv("SAKULI_HOME"), "libs", "java")
	originalUsage := flag.Usage
	flag.Usage = func() {
		fmt.Println(`Generic Sakuli test starter.
2016 - The Sakuli team / Philip Griesbacher.
`)
		originalUsage()
	}
	flag.IntVar(&loop, "loop", 0, "loop this suite, wait n seconds between executions, 0 means no loops (default: 0)")
	flag.StringVar(&javaHome, "javahome", "", "Java bin dir (overrides PATH)")
	flag.Var(&preHooks, "preHook", "A programm which will be executed before sakuli (Can be added multiple times)")
	flag.Var(&postHooks, "postHook", "A programm which will be executed after sakuli (Can be added multiple times)")

	flag.Var(&javaProperties, "D", "JVM option to set a property on runtime, overrides the 'sakuli.properties'")
	flag.StringVar(&browser, "browser", "", "(optional) browser for the test execution (default: Firefox)")
	flag.StringVar(&encrypt, "encrypt", "", "encrypt a secret")
	flag.StringVar(&inter, "interface", "", "(optional) network interface used for encryption")
	flag.StringVar(&run, "run", "", "run a sakuli test suite")
	flag.StringVar(&sahiHome, "sahi_home", "", "(optional) Sahi installation folder")
	flag.StringVar(&sakuliHome, "sakuli_home", os.Getenv("SAKULI_HOME"), "(optional) SAKULI_HOME folder, default: environment variable 'SAKULI_HOME'")
	flag.Parse()

	input.TestRun(run)

	javaExecutable := input.TestJavaHome(javaHome)
	javaProperties = javaProperties.AddPrefix("-D")
	sakuliProperties := map[string]string{"sakuli_home": sakuliHome}

	if browser != "" {
		sakuliProperties["browser"] = browser
	}
	if inter != "" {
		sakuliProperties["interface"] = inter
	}
	if encrypt != "" {
		sakuliProperties["encrypt"] = encrypt
	}
	if run != "" {
		sakuliProperties["run"] = run
	}
	if sahiHome != "" {
		sakuliProperties["sahiHome"] = sahiHome
	}
	joinedSakuliProperties := genSakuliPropertiesList(sakuliProperties)

	if len(preHooks) > 0 {
		fmt.Println("=========== Starting Pre-Hooks ===========")
		for _, pre := range preHooks {
			execute.RunHandler(pre)
		}
		fmt.Println("=========== Finished Pre-Hooks ===========")
	}

	sakuliReturnCode := execute.RunSakuli(javaExecutable, sakuliJars, javaProperties, joinedSakuliProperties)
	for loop > 0 {
		fmt.Printf("*** Loop mode - sleeping for %d seconds... ***\n", loop)
		time.Sleep(time.Duration(loop) * time.Second)
		execute.RunSakuli(javaExecutable, sakuliJars, javaProperties, joinedSakuliProperties)
	}

	if len(postHooks) > 0 {
		fmt.Println("=========== Starting Post-Hooks ===========")
		for _, post := range postHooks {
			execute.RunHandler(post)
		}
		fmt.Println("=========== Finished Post-Hooks ===========")
	}
	os.Exit(sakuliReturnCode)
}

func genSakuliPropertiesList(properties map[string]string) input.StringSlice {
	propertiesString := []string{}
	for k, v := range properties {
		propertiesString = append(propertiesString, fmt.Sprintf("--%s", k))
		propertiesString = append(propertiesString, v)
	}
	return propertiesString
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
	"time"

	"github.com/kisom/goutils/die"
)

var (
	waitFor time.Duration
	verbose bool
	cmdName = "xscreensaver-command"
)

func scanForXScreenSaver() {
	_, err := exec.LookPath(cmdName)
	if err != nil {
		die.With("xscreensaver-command not found: please install it via your package manager.")
	}
}

func heartbeat() {
	for {
		<-time.After(waitFor)
		cmd := exec.Command(cmdName, "-deactivate")
		fmt.Printf("%+v\n", cmd)
		out, err := cmd.CombinedOutput()
		if err != nil {
			fmt.Fprintf(os.Stderr, "[!] %v\n", err)
		}

		if verbose {
			fmt.Printf("%s\n", bytes.TrimSpace(out))
		}
	}
}

func help() {
	fmt.Fprintf(os.Stderr, `hbxss [-i interval] [-t time] [-v]

	-f    	  	Force hbxss to run indefinitely.

	-i interval	Specify the interval between heartbeats. This
			should follow the form <number><unit>, where
			unit should be one of 's', 'm', or 'h' for
			seconds, minutes, or hours, respectively.

	-t time		Specify how long the program should run for;
	   		the default is two hours.

	-v		Print each heartbeat as it occurs.
`)
}

func init() {
	flag.Usage = help
}

func main() {
	var runFor time.Duration

	forceForever := flag.Bool("f", false, "Force hbxss to run forever.")
	showHelp := flag.Bool("h", false, "Display a short usage message and exit.")

	flag.DurationVar(&waitFor, "i", 5*time.Minute, "Time between heartbeats.")
	flag.DurationVar(&runFor, "t", 2 * time.Hour, "Duration program should run.")
	flag.BoolVar(&verbose, "v", false, "Print each heartbeat.")
	flag.Parse()

	if *showHelp {
		help()
		os.Exit(0)
	}

	scanForXScreenSaver()
	go heartbeat()

	if *forceForever {
		fmt.Fprintf(os.Stderr, "!!! Warning: xscreensaver will be indefinitely suppressed !!!\n")
		sigc := make(chan os.Signal, 1)
		signal.Notify(sigc, os.Kill, os.Interrupt, syscall.SIGTERM)
		<-sigc
	} else {
		<-time.After(runFor)
	}
}
<commit_msg>Remove debug print.<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
	"time"

	"github.com/kisom/goutils/die"
)

var (
	waitFor time.Duration
	verbose bool
	cmdName = "xscreensaver-command"
)

func scanForXScreenSaver() {
	_, err := exec.LookPath(cmdName)
	if err != nil {
		die.With("xscreensaver-command not found: please install it via your package manager.")
	}
}

func heartbeat() {
	for {
		<-time.After(waitFor)
		cmd := exec.Command(cmdName, "-deactivate")
			out, err := cmd.CombinedOutput()
		if err != nil {
			fmt.Fprintf(os.Stderr, "[!] %v\n", err)
		}

		if verbose {
			fmt.Printf("%s\n", bytes.TrimSpace(out))
		}
	}
}

func help() {
	fmt.Fprintf(os.Stderr, `hbxss [-i interval] [-t time] [-v]

	-f    	  	Force hbxss to run indefinitely.

	-i interval	Specify the interval between heartbeats. This
			should follow the form <number><unit>, where
			unit should be one of 's', 'm', or 'h' for
			seconds, minutes, or hours, respectively.

	-t time		Specify how long the program should run for;
	   		the default is two hours.

	-v		Print each heartbeat as it occurs.
`)
}

func init() {
	flag.Usage = help
}

func main() {
	var runFor time.Duration

	forceForever := flag.Bool("f", false, "Force hbxss to run forever.")
	showHelp := flag.Bool("h", false, "Display a short usage message and exit.")

	flag.DurationVar(&waitFor, "i", 5*time.Minute, "Time between heartbeats.")
	flag.DurationVar(&runFor, "t", 2 * time.Hour, "Duration program should run.")
	flag.BoolVar(&verbose, "v", false, "Print each heartbeat.")
	flag.Parse()

	if *showHelp {
		help()
		os.Exit(0)
	}

	scanForXScreenSaver()
	go heartbeat()

	if *forceForever {
		fmt.Fprintf(os.Stderr, "!!! Warning: xscreensaver will be indefinitely suppressed !!!\n")
		sigc := make(chan os.Signal, 1)
		signal.Notify(sigc, os.Kill, os.Interrupt, syscall.SIGTERM)
		<-sigc
	} else {
		<-time.After(runFor)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"time"

	"github.com/gummiboll/forgetful/commands"
	"github.com/gummiboll/forgetful/storage"
	"github.com/urfave/cli"
)

const version string = "1.0"

func printList(notes []string) {
	if len(notes) > 0 {
		fmt.Println(fmt.Sprintf("Found %d matching note(s):", len(notes)))

		for _, n := range notes {
			fmt.Println(n)
		}

	} else {
		fmt.Println("No matches")
	}
}

func printInfo(n storage.Note) {
	fmt.Println(fmt.Sprintf("%s:", n.Name))
	fmt.Println(fmt.Sprintf("Created at: %s, last updated at: %s", n.CreatedAt.Format("2006-01-02 15:04"), n.UpdatedAt.Format("2006-01-02 15:04")))
	if n.Temporary == true {
		validTo := n.UpdatedAt.Add(24 * time.Hour)
		dur := validTo.Sub(time.Now())
		fmt.Println(fmt.Sprintf("Is temporary, will expire in %s", dur-(dur%time.Second)))
	}
}

func main() {
	// Init
	i := storage.Impl{}
	if err := i.InitDB(); err != nil {
		panic(err)
	}

	i.InitSchema()
	if err := i.RemoveExpiredNotes(); err != nil {
		panic(err)
	}

	app := cli.NewApp()
	app.Name = "forgetful"
	app.Usage = "For your notes/cheat sheets"
	app.Version = version
	app.Commands = []cli.Command{
		{
			Name:    "add",
			Aliases: []string{"a"},
			Usage:   "Add a note",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "t",
					Usage: "Mark as temporary (expires after 24 hours)",
				},
				cli.BoolFlag{
					Name:  "p",
					Usage: "Create note with contents from clipboard",
				},
			},
			Action: func(c *cli.Context) error {
				n, err := commands.AddCommand(c, i)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Added note: %s", n.Name))
				return nil
			},
		},
		{
			Name:    "delete",
			Aliases: []string{"d"},
			Usage:   "Delete a note",
			Action: func(c *cli.Context) error {
				n, err := commands.DeleteCommand(c, i)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Deleted note: %s", n.Name))
				return nil
			},
		},
		{
			Name:    "edit",
			Aliases: []string{"e"},
			Usage:   "Edit/read a note",
			Action: func(c *cli.Context) error {
				n, err := commands.EditCommand(c, i)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Updated note: %s", n.Name))
				return nil
			},
		},
		{
			Name:    "info",
			Aliases: []string{"i"},
			Usage:   "Prints information about a note",
			Action: func(c *cli.Context) error {
				n, err := commands.InfoCommand(c, i)
				if err != nil {
					return err
				}

				printInfo(n)

				return nil
			},
		},
		{
			Name:    "read",
			Aliases: []string{"r"},
			Usage:   "Read a note",
			Action: func(c *cli.Context) error {
				if err := commands.ReadCommand(c, i); err != nil {
					return err
				}
				return nil
			},
		},
		{
			Name:    "rename",
			Aliases: []string{"mv"},
			Usage:   "Rename a note",
			Action: func(c *cli.Context) error {
				nName, newName, err := commands.RenameCommand(c, i)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Renamed %s to %s", nName, newName))

				return nil
			},
		},
		{
			Name:    "list",
			Aliases: []string{"l"},
			Usage:   "List all notes, filter result if argument i present",
			Action: func(c *cli.Context) error {
				notes := commands.ListCommand(c, i)

				printList(notes)

				return nil
			},
		},
		{
			Name:    "search",
			Aliases: []string{"s"},
			Usage:   "Search notes for argument",
			Action: func(c *cli.Context) error {
				notes, err := commands.SearchCommand(c, i)
				if err != nil {
					return err
				}

				printList(notes)

				return nil
			},
		},
		{
			Name:  "share",
			Usage: "Share a note (publicly) on hastebin.com",
			Action: func(c *cli.Context) error {
				n, url, err := commands.ShareCommand(c, i)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Shared note '%s': %s", n.Name, url))
				return nil
			},
		},
		{
			Name:    "keep",
			Aliases: []string{"k"},
			Usage:   "Sets a temporary note as permanent",
			Action: func(c *cli.Context) error {
				n, err := commands.KeepCommand(c, i, true)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Keeping note: %s", n.Name))
				return nil
			},
		},
		{
			Name:    "unkeep",
			Aliases: []string{"u"},
			Usage:   "Sets a permanent note as temporary",
			Action: func(c *cli.Context) error {
				n, err := commands.KeepCommand(c, i, false)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Unkeeping note: %s", n.Name))
				return nil
			},
		},
	}

	app.Run(os.Args)

}
<commit_msg>Version bump<commit_after>package main

import (
	"fmt"
	"os"
	"time"

	"github.com/gummiboll/forgetful/commands"
	"github.com/gummiboll/forgetful/storage"
	"github.com/urfave/cli"
)

const version string = "1.1"

func printList(notes []string) {
	if len(notes) > 0 {
		fmt.Println(fmt.Sprintf("Found %d matching note(s):", len(notes)))

		for _, n := range notes {
			fmt.Println(n)
		}

	} else {
		fmt.Println("No matches")
	}
}

func printInfo(n storage.Note) {
	fmt.Println(fmt.Sprintf("%s:", n.Name))
	fmt.Println(fmt.Sprintf("Created at: %s, last updated at: %s", n.CreatedAt.Format("2006-01-02 15:04"), n.UpdatedAt.Format("2006-01-02 15:04")))
	if n.Temporary == true {
		validTo := n.UpdatedAt.Add(24 * time.Hour)
		dur := validTo.Sub(time.Now())
		fmt.Println(fmt.Sprintf("Is temporary, will expire in %s", dur-(dur%time.Second)))
	}
}

func main() {
	// Init
	i := storage.Impl{}
	if err := i.InitDB(); err != nil {
		panic(err)
	}

	i.InitSchema()
	if err := i.RemoveExpiredNotes(); err != nil {
		panic(err)
	}

	app := cli.NewApp()
	app.Name = "forgetful"
	app.Usage = "For your notes/cheat sheets"
	app.Version = version
	app.Commands = []cli.Command{
		{
			Name:    "add",
			Aliases: []string{"a"},
			Usage:   "Add a note",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "t",
					Usage: "Mark as temporary (expires after 24 hours)",
				},
				cli.BoolFlag{
					Name:  "p",
					Usage: "Create note with contents from clipboard",
				},
			},
			Action: func(c *cli.Context) error {
				n, err := commands.AddCommand(c, i)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Added note: %s", n.Name))
				return nil
			},
		},
		{
			Name:    "delete",
			Aliases: []string{"d"},
			Usage:   "Delete a note",
			Action: func(c *cli.Context) error {
				n, err := commands.DeleteCommand(c, i)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Deleted note: %s", n.Name))
				return nil
			},
		},
		{
			Name:    "edit",
			Aliases: []string{"e"},
			Usage:   "Edit/read a note",
			Action: func(c *cli.Context) error {
				n, err := commands.EditCommand(c, i)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Updated note: %s", n.Name))
				return nil
			},
		},
		{
			Name:    "info",
			Aliases: []string{"i"},
			Usage:   "Prints information about a note",
			Action: func(c *cli.Context) error {
				n, err := commands.InfoCommand(c, i)
				if err != nil {
					return err
				}

				printInfo(n)

				return nil
			},
		},
		{
			Name:    "read",
			Aliases: []string{"r"},
			Usage:   "Read a note",
			Action: func(c *cli.Context) error {
				if err := commands.ReadCommand(c, i); err != nil {
					return err
				}
				return nil
			},
		},
		{
			Name:    "rename",
			Aliases: []string{"mv"},
			Usage:   "Rename a note",
			Action: func(c *cli.Context) error {
				nName, newName, err := commands.RenameCommand(c, i)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Renamed %s to %s", nName, newName))

				return nil
			},
		},
		{
			Name:    "list",
			Aliases: []string{"l"},
			Usage:   "List all notes, filter result if argument i present",
			Action: func(c *cli.Context) error {
				notes := commands.ListCommand(c, i)

				printList(notes)

				return nil
			},
		},
		{
			Name:    "search",
			Aliases: []string{"s"},
			Usage:   "Search notes for argument",
			Action: func(c *cli.Context) error {
				notes, err := commands.SearchCommand(c, i)
				if err != nil {
					return err
				}

				printList(notes)

				return nil
			},
		},
		{
			Name:  "share",
			Usage: "Share a note (publicly) on hastebin.com",
			Action: func(c *cli.Context) error {
				n, url, err := commands.ShareCommand(c, i)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Shared note '%s': %s", n.Name, url))
				return nil
			},
		},
		{
			Name:    "keep",
			Aliases: []string{"k"},
			Usage:   "Sets a temporary note as permanent",
			Action: func(c *cli.Context) error {
				n, err := commands.KeepCommand(c, i, true)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Keeping note: %s", n.Name))
				return nil
			},
		},
		{
			Name:    "unkeep",
			Aliases: []string{"u"},
			Usage:   "Sets a permanent note as temporary",
			Action: func(c *cli.Context) error {
				n, err := commands.KeepCommand(c, i, false)
				if err != nil {
					return err
				}

				fmt.Println(fmt.Sprintf("Unkeeping note: %s", n.Name))
				return nil
			},
		},
	}

	app.Run(os.Args)

}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
	"time"
)

type requestResult struct {
	Query struct {
		Count   int    `json:"count"`
		Created string `json:"created"`
		Lang    string `json:"lang"`
		Results string `json:"results"`
	} `json:"query"`
}

const url = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%27www.google.com%2Ffinance%2Fconverter%3Fa%3D1%26from%3DUSD%26to%3DBRL%27%20and%20xpath%3D%27%2F%2F*%5B%40id%3D\"currency_converter_result\"%5D%2Fspan%2Ftext()%27&format=json&callback="

// Make the request and return the content of body
func checker() (string, error) {
	resp, err := http.Get(url)

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

	defer func() {
		err := resp.Body.Close()
		if err != nil {
			log.Println("Error to close get request")
		}
	}()

	contents, err := ioutil.ReadAll(resp.Body)

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

	return string(contents), nil
}

// Parses the json and get only the value Results
func parseJSON(jsonResult string) string {
	log.Println("JSON REQUEST", jsonResult)
	result := new(requestResult)

	err := json.Unmarshal([]byte(jsonResult), result)

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

	log.Println(result)

	return result.Query.Results
}

// Checking the webservice each 30 minutes
func pool() chan string {
	ch := make(chan string)
	go func() {
		haveResponse := false
		requestJSON := func() {
			if res, err := checker(); err == nil {
				if jsonRes := parseJSON(res); jsonRes != "" {
					haveResponse = true
					ch <- jsonRes
				}
			}
		}

		for {
			for {
				requestJSON()
				if haveResponse {
					break
				} else {
					log.Println("No result try again ...")
				}
			}

			c := time.Tick(30 * time.Minute)
			for now := range c {
				log.Println("Updated at %v", now)
				requestJSON()
			}
		}
	}()
	return ch
}

func main() {
	// Get the first value
	checkerpool := pool()
	latestResult := <-checkerpool

	// To deploy at heroku :D
	env := os.Getenv("GO_ENV")
	host := "127.0.0.1"
	port := 9000
	//token := ""

	if env == "PRODUCTION" {
		host = ""
		port, _ = strconv.Atoi(os.Getenv("PORT"))
		//token = os.Getenv("TOKEN")
	}

	address := fmt.Sprintf("%s:%d", host, port)
	log.Println("Ready to serve at", address)

	http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
		select {
		case latestResult := <-checkerpool:
			log.Println("Get result", latestResult)
		default:
			log.Println("Get cache value")
		}

		_, err := rw.Write([]byte(latestResult))

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

	if err := http.ListenAndServe(address, nil); err != nil {
		log.Fatal("Failed to serve to address", address, err)
	}
}
<commit_msg>Too much for loops<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
	"time"
)

type requestResult struct {
	Query struct {
		Count   int    `json:"count"`
		Created string `json:"created"`
		Lang    string `json:"lang"`
		Results string `json:"results"`
	} `json:"query"`
}

const url = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%27www.google.com%2Ffinance%2Fconverter%3Fa%3D1%26from%3DUSD%26to%3DBRL%27%20and%20xpath%3D%27%2F%2F*%5B%40id%3D\"currency_converter_result\"%5D%2Fspan%2Ftext()%27&format=json&callback="

// Make the request and return the content of body
func checker() (string, error) {
	resp, err := http.Get(url)

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

	defer func() {
		err := resp.Body.Close()
		if err != nil {
			log.Println("Error to close get request")
		}
	}()

	contents, err := ioutil.ReadAll(resp.Body)

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

	return string(contents), nil
}

// Parses the json and get only the value Results
func parseJSON(jsonResult string) string {
	log.Println("JSON REQUEST", jsonResult)
	result := new(requestResult)

	err := json.Unmarshal([]byte(jsonResult), result)

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

	log.Println(result)

	return result.Query.Results
}

// Checking the webservice each 30 minutes
func pool() chan string {
	ch := make(chan string)
	go func() {
		haveResponse := false
		requestJSON := func() {
			if res, err := checker(); err == nil {
				if jsonRes := parseJSON(res); jsonRes != "" {
					haveResponse = true
					ch <- jsonRes
				}
			}
		}

		for {
			requestJSON()
			if haveResponse {
				break
			} else {
				log.Println("No result try again ...")
			}
		}

		c := time.Tick(30 * time.Minute)
		for now := range c {
			log.Println("Updated at %v", now)
			requestJSON()
		}
	}()
	return ch
}

func main() {
	// Get the first value
	checkerpool := pool()
	latestResult := <-checkerpool

	// To deploy at heroku :D
	env := os.Getenv("GO_ENV")
	host := "127.0.0.1"
	port := 9000
	//token := ""

	if env == "PRODUCTION" {
		host = ""
		port, _ = strconv.Atoi(os.Getenv("PORT"))
		//token = os.Getenv("TOKEN")
	}

	address := fmt.Sprintf("%s:%d", host, port)
	log.Println("Ready to serve at", address)

	http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
		select {
		case latestResult := <-checkerpool:
			log.Println("Get result", latestResult)
		default:
			log.Println("Get cache value")
		}

		_, err := rw.Write([]byte(latestResult))

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

	if err := http.ListenAndServe(address, nil); err != nil {
		log.Fatal("Failed to serve to address", address, err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	fp "path/filepath"
	"strings"
)

import "github.com/kataras/iris"

var ROOT string
var LISTEN = ":8000"

func main() {
	flag.Parse()
	ROOT = flag.Arg(0)
	if flag.Arg(1) != "" {
		LISTEN = flag.Arg(1)
	}
	fmt.Printf("To be listed direcotry: [%v]\n", ROOT)

	iris.Config.IsDevelopment = true // reloads the templates on each request, defaults to false
	iris.Config.Gzip = true          // compressed gzip contents to the client, the same for Serializers also, defaults to false

	iris.Get("/", func(ctx *iris.Context) {
		ctx.Writef(h_a("/public", "View your photos!"))
	})
	iris.StaticWeb("/img", ROOT)

	iris.Handle("GET", "/public/*path", MyAlbum{root: ROOT})
	iris.Listen(LISTEN)
}

type MyAlbum struct {
	root string
	dir  *DirStr
}

func (album MyAlbum) Serve(ctx *iris.Context) {
	path := ctx.Path()
	ext := strings.ToLower(fp.Ext(path))

	switch ext {
	case ".jpg", ".png", ".gif":
		ctx.WriteString("ok")
		//ctx.ServeFile(fp.Join(album.root, ctx.Param("path")))
	default:
		obj := NewDirstr(fp.Join(album.root, ctx.Param("path")))
		if obj == nil {
			ctx.WriteString("Invalid URL")
			return
		} else {
			album.dir = obj
		}
		ctx.WriteString(fmt.Sprintf(`
			<!DOCTYPE html>

				<meta charset="UTF-8">
				<title>My Photos</title>

Directories:

					%v

Photos:

					%v

			`,
			strings.Join(Dir2Html(album.dir.Root, album.dir.Dirs), "
"),
			strings.Join(Img2Html(path, album.dir.Root, album.dir.Images), "")))
	}
}

func Img2Html(path, root string, names []string) []string {
	rv := []string{}
	for _, file := range names {
		rv = append(rv, h_div(
			h_span(h_a("/img/"+fp.Join(path[8:], file), file), "link")+h_span(fileSize(fp.Join(root, file)), "size"), "img"))
	}
	return rv
}

func Dir2Html(root string, names []string) []string {
	rv := []string{}
	for _, file := range names {
		if len(NewDirstr(fp.Join(root, file)).Images) > 0 {
			rv = append(rv, h_a("/public/"+file, file+"/"))
		}
	}
	return rv
}
<commit_msg>feature: add total number<commit_after>package main

import (
	"flag"
	"fmt"
	fp "path/filepath"
	"strings"
)

import "github.com/kataras/iris"

var ROOT string
var LISTEN = ":8000"

func main() {
	flag.Parse()
	ROOT = flag.Arg(0)
	if flag.Arg(1) != "" {
		LISTEN = flag.Arg(1)
	}
	fmt.Printf("To be listed direcotry: [%v]\n", ROOT)

	iris.Config.IsDevelopment = true // reloads the templates on each request, defaults to false
	iris.Config.Gzip = true          // compressed gzip contents to the client, the same for Serializers also, defaults to false

	iris.Get("/", func(ctx *iris.Context) {
		ctx.Writef(h_a("/public", "View your photos!"))
	})
	iris.StaticWeb("/img", ROOT)

	iris.Handle("GET", "/public/*path", MyAlbum{root: ROOT})
	iris.Listen(LISTEN)
}

type MyAlbum struct {
	root string
	dir  *DirStr
}

func (album MyAlbum) Serve(ctx *iris.Context) {
	path := ctx.Path()
	ext := strings.ToLower(fp.Ext(path))

	switch ext {
	case ".jpg", ".png", ".gif":
		ctx.WriteString("ok")
		//ctx.ServeFile(fp.Join(album.root, ctx.Param("path")))
	default:
		obj := NewDirstr(fp.Join(album.root, ctx.Param("path")))
		if obj == nil {
			ctx.WriteString("Invalid URL")
			return
		} else {
			album.dir = obj
		}
		ctx.WriteString(fmt.Sprintf(`
			<!DOCTYPE html>

				<meta charset="UTF-8">
				<title>My Photos</title>

Directories: %v

					%v

Photos: %v

					%v

			`,
			len(album.dir.Dirs),
			strings.Join(Dir2Html(album.dir.Root, album.dir.Dirs), "
"),
			len(album.dir.Images),
			strings.Join(Img2Html(path, album.dir.Root, album.dir.Images), "")))
	}
}

func Img2Html(path, root string, names []string) []string {
	rv := []string{}
	for _, file := range names {
		rv = append(rv, h_div(
			h_span(h_a("/img/"+fp.Join(path[8:], file), file), "link")+h_span(fileSize(fp.Join(root, file)), "size"), "img"))
	}
	return rv
}

func Dir2Html(root string, names []string) []string {
	rv := []string{}
	for _, file := range names {
		if len(NewDirstr(fp.Join(root, file)).Images) > 0 {
			rv = append(rv, h_a("/public/"+file, file+"/"))
		}
	}
	return rv
}
<|endoftext|>


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

// tsuru-admin is under development.
package main

import (
	"os"

	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/provision"
	_ "github.com/tsuru/tsuru/provision/docker"
)

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

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header, nil)
	m.Register(&logRemove{})
	m.Register(&platformAdd{})
	m.Register(&platformUpdate{})
	m.Register(&platformRemove{})
	m.Register(&machineList{})
	m.Register(&machineDestroy{})
	m.Register(&appLockDelete{})
	m.RegisterDeprecated(&userQuotaView{}, "view-user-quota")
	m.RegisterDeprecated(&userChangeQuota{}, "change-user-quota")
	m.RegisterDeprecated(&appQuotaView{}, "view-app-quota")
	m.RegisterDeprecated(&appQuotaChange{}, "change-app-quota")
	m.Register(&planCreate{})
	m.Register(&planRemove{})
	m.Register(&planRoutersList{})
	m.Register(&templateList{})
	m.Register(&templateAdd{})
	m.Register(&templateRemove{})
	m.RegisterRemoved("user-list", "You should use `tsuru user-list` instead.")
	m.RegisterDeprecated(&addPoolToSchedulerCmd{}, "docker-pool-add")
	m.Register(&updatePoolToSchedulerCmd{})
	m.RegisterDeprecated(&removePoolFromSchedulerCmd{}, "docker-pool-remove")
	m.RegisterRemoved("pool-list", "You should use `tsuru pool-list` instead.")
	m.RegisterDeprecated(addTeamsToPoolCmd{}, "docker-pool-teams-add")
	m.RegisterDeprecated(removeTeamsFromPoolCmd{}, "docker-pool-teams-remove")
	m.Register(&cmd.ShellToContainerCmd{})
	m.Register(&appRoutesRebuild{})
	m.Register(&templateUpdate{})
	registerProvisionersCommands(m)
	return m
}

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

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

// tsuru-admin is under development.
package main

import (
	"os"

	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/provision"
	_ "github.com/tsuru/tsuru/provision/docker"
)

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

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header, nil)
	m.Register(&logRemove{})
	m.Register(&platformAdd{})
	m.Register(&platformUpdate{})
	m.Register(&platformRemove{})
	m.Register(&machineList{})
	m.Register(&machineDestroy{})
	m.Register(&appLockDelete{})
	m.RegisterDeprecated(&userQuotaView{}, "view-user-quota")
	m.RegisterDeprecated(&userChangeQuota{}, "change-user-quota")
	m.RegisterDeprecated(&appQuotaView{}, "view-app-quota")
	m.RegisterDeprecated(&appQuotaChange{}, "change-app-quota")
	m.Register(&planCreate{})
	m.Register(&planRemove{})
	m.Register(&planRoutersList{})
	m.Register(&templateList{})
	m.Register(&templateAdd{})
	m.Register(&templateRemove{})
	m.RegisterRemoved("user-list", "You should use `tsuru user-list` instead.")
	m.RegisterDeprecated(&addPoolToSchedulerCmd{}, "docker-pool-add")
	m.Register(&updatePoolToSchedulerCmd{})
	m.RegisterDeprecated(&removePoolFromSchedulerCmd{}, "docker-pool-remove")
	m.RegisterRemoved("pool-list", "You should use `tsuru pool-list` instead.")
	m.RegisterDeprecated(addTeamsToPoolCmd{}, "docker-pool-teams-add")
	m.RegisterDeprecated(removeTeamsFromPoolCmd{}, "docker-pool-teams-remove")
	m.Register(&cmd.ShellToContainerCmd{})
	m.Register(&appRoutesRebuild{})
	m.Register(&templateUpdate{})
	registerProvisionersCommands(m)
	return m
}

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

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


<commit_before>package main

import (
	"fmt"
	"os"
	"sync"
	"time"

	"github.com/codegangsta/cli"
	docker "github.com/fsouza/go-dockerclient"
	"github.com/montanaflynn/stats"
)

func worker(requests int, image string, completeCh chan time.Duration) {
	client, err := docker.NewClientFromEnv()
	if err != nil {
		panic(err)
	}

	for i := 0; i < requests; i++ {
		start := time.Now()

		container, err := client.CreateContainer(docker.CreateContainerOptions{
			Config: &docker.Config{
				Image: image,
			}})
		if err != nil {
			panic(err)
		}

		err = client.StartContainer(container.ID, nil)
		if err != nil {
			panic(err)
		}

		completeCh <- time.Since(start)
	}
}

func session(requests, concurrency int, image string, completeCh chan time.Duration) {
	var wg sync.WaitGroup

	n := requests / concurrency

	for i := 0; i < concurrency; i++ {
		wg.Add(1)
		go func() {
			worker(n, image, completeCh)
			wg.Done()
		}()
	}
	wg.Wait()

}

func bench(requests, concurrency int, image string) {
	start := time.Now()

	timings := make([]float64, requests)
	completeCh := make(chan time.Duration)
	current := 0
	go func() {
		for timing := range completeCh {
			timings = append(timings, timing.Seconds())
			current++
			percent := float64(current) / float64(requests) * 100
			fmt.Printf("[%3.f%%] %d/%d containers started\n", percent, current, requests)
		}
	}()
	session(requests, concurrency, image, completeCh)
	close(completeCh)

	total := time.Since(start)
	p50th, _ := stats.Median(timings)
	p90th, _ := stats.Percentile(timings, 90)
	p99th, _ := stats.Percentile(timings, 99)

	fmt.Println("")
	fmt.Printf("Time taken for tests: %s\n", total.String())
	fmt.Printf("Time per container: %vms [50th] | %vms [90th] | %vms [99th]\n", int(p50th*1000), int(p90th*1000), int(p99th*1000))
}

func main() {
	app := cli.NewApp()
	app.Name = "swarm-bench"
	app.Usage = "Swarm Benchmarking Tool"
	app.Version = "0.1.0"
	app.Author = ""
	app.Email = ""
	app.Flags = []cli.Flag{
		cli.IntFlag{
			Name:  "concurrency, c",
			Value: 1,
			Usage: "Number of multiple requests to perform at a time. Default is one request at a time.",
		},
		cli.IntFlag{
			Name:  "requests, n",
			Value: 1,
			Usage: "Number of containers to start for the benchmarking session. The default is to just start a single container.",
		},
		cli.StringFlag{
			Name:  "image, i",
			Usage: "Image to use for benchmarking.",
		},
	}

	app.Action = func(c *cli.Context) {
		if c.String("image") == "" {
			cli.ShowAppHelp(c)
			os.Exit(1)
		}
		bench(c.Int("requests"), c.Int("concurrency"), c.String("image"))
	}

	app.Run(os.Args)
}
<commit_msg>Fix 50th percentile<commit_after>package main

import (
	"fmt"
	"os"
	"sync"
	"time"

	"github.com/codegangsta/cli"
	docker "github.com/fsouza/go-dockerclient"
	"github.com/montanaflynn/stats"
)

func worker(requests int, image string, completeCh chan time.Duration) {
	client, err := docker.NewClientFromEnv()
	if err != nil {
		panic(err)
	}

	for i := 0; i < requests; i++ {
		start := time.Now()

		container, err := client.CreateContainer(docker.CreateContainerOptions{
			Config: &docker.Config{
				Image: image,
			}})
		if err != nil {
			panic(err)
		}

		err = client.StartContainer(container.ID, nil)
		if err != nil {
			panic(err)
		}

		completeCh <- time.Since(start)
	}
}

func session(requests, concurrency int, image string, completeCh chan time.Duration) {
	var wg sync.WaitGroup

	n := requests / concurrency

	for i := 0; i < concurrency; i++ {
		wg.Add(1)
		go func() {
			worker(n, image, completeCh)
			wg.Done()
		}()
	}
	wg.Wait()

}

func bench(requests, concurrency int, image string) {
	start := time.Now()

	timings := make([]float64, requests)
	completeCh := make(chan time.Duration)
	current := 0
	go func() {
		for timing := range completeCh {
			timings = append(timings, timing.Seconds())
			current++
			percent := float64(current) / float64(requests) * 100
			fmt.Printf("[%3.f%%] %d/%d containers started\n", percent, current, requests)
		}
	}()
	session(requests, concurrency, image, completeCh)
	close(completeCh)

	total := time.Since(start)
	p50th, _ := stats.Percentile(timings, 50)
	p90th, _ := stats.Percentile(timings, 90)
	p99th, _ := stats.Percentile(timings, 99)

	fmt.Println("")
	fmt.Printf("Time taken for tests: %s\n", total.String())
	fmt.Printf("Time per container: %vms [50th] | %vms [90th] | %vms [99th]\n", int(p50th*1000), int(p90th*1000), int(p99th*1000))
}

func main() {
	app := cli.NewApp()
	app.Name = "swarm-bench"
	app.Usage = "Swarm Benchmarking Tool"
	app.Version = "0.1.0"
	app.Author = ""
	app.Email = ""
	app.Flags = []cli.Flag{
		cli.IntFlag{
			Name:  "concurrency, c",
			Value: 1,
			Usage: "Number of multiple requests to perform at a time. Default is one request at a time.",
		},
		cli.IntFlag{
			Name:  "requests, n",
			Value: 1,
			Usage: "Number of containers to start for the benchmarking session. The default is to just start a single container.",
		},
		cli.StringFlag{
			Name:  "image, i",
			Usage: "Image to use for benchmarking.",
		},
	}

	app.Action = func(c *cli.Context) {
		if c.String("image") == "" {
			cli.ShowAppHelp(c)
			os.Exit(1)
		}
		bench(c.Int("requests"), c.Int("concurrency"), c.String("image"))
	}

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


<commit_before>package main

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

	"github.com/gosuri/uiprogress"
	"github.com/orivej/e"
	git "github.com/orivej/git2go"
)

type CommitInfo struct {
	Side     int
	Branches []string // Short names of branches containing this commit.
}

var (
	flVerbose = flag.Bool("v", false, "enable verbose logging")
)

const usage = `usage : git-compose [<options>] <repository>...

Compose all branches from repositories (URLs, paths, or remote names)
into a single repository in the current directory.

`

func main() {
	log.SetFlags(0)
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, usage)
		flag.PrintDefaults()
	}
	flag.Parse()
	remotePaths := flag.Args()
	if len(remotePaths) < 1 {
		flag.Usage()
		os.Exit(1)
	}

	nSides := len(remotePaths)
	sideNames := make([]string, nSides)
	commitInfo := make(map[git.Oid]CommitInfo)
	roots := []*git.Commit{}

	repo, err := git.InitRepository(".", false)
	e.Exit(err)

	for i, remotePath := range remotePaths {
		// Fetch.
		remotePath, err := filepath.Abs(remotePath)
		e.Exit(err)

		name := filepath.Base(remotePath)
		sideNames[i] = name
		remoteGlob := fmt.Sprint("refs/remotes/", name, "/*")

		remote, err := repo.Remotes.Lookup(name)
		if err != nil {
			log.Printf("fetching %q (%s)", name, err)
			remote, err = repo.Remotes.Create(name, remotePath)
			e.Exit(err)
			// Use "git fetch" because libgit2 fetch is horribly slow for big local repos.
			// err = remote.Fetch(nil, nil, "")
			_ = remote
			cmd := exec.Command("git", "fetch", name)
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			err = cmd.Run()
			e.Exit(err)
		}
		// Store commit info.
		remoteRoots := []*git.Commit{}

		log.Printf("walking %q", name)
		walker, err := repo.Walk()
		e.Exit(err)
		err = walker.PushGlob(remoteGlob)
		e.Exit(err)
		err = walker.Iterate(func(commit *git.Commit) bool {
			oid := *commit.Id()
			commitInfo[oid] = CommitInfo{Side: i}
			return true
		})
		e.Exit(err)

		iter, err := repo.NewReferenceIteratorGlob(remoteGlob)
		e.Exit(err)
		for {
			ref, err := iter.Next()
			if err, ok := err.(*git.GitError); ok && err.Code == git.ErrIterOver {
				break
			}
			e.Exit(err)
			// Seed search with head commit.
			refCommit, err := repo.LookupCommit(ref.Target())
			e.Exit(err)
			roots = append(roots, refCommit)
			remoteRoots = append(remoteRoots, refCommit)
			// Store commit branches.
			branchName, err := ref.Branch().Name()
			e.Exit(err)
			branchName = strings.TrimPrefix(branchName, name+"/")
			walker.Reset()
			err = walker.Push(ref.Target())
			e.Exit(err)
			walker.SimplifyFirstParent()
			err = walker.Iterate(func(commit *git.Commit) bool {
				oid := *commit.Id()
				ci := commitInfo[oid]
				ci.Branches = append(ci.Branches, branchName)
				if branchName == "master" {
					// Reduce risk of missing sibling trees
					// with our strategy that takes them
					// from the first parent by making
					// "master" the first parent.
					n := len(ci.Branches) - 1
					ci.Branches[0], ci.Branches[n] = ci.Branches[n], ci.Branches[0]
				}

				commitInfo[oid] = ci
				return true
			})
			e.Exit(err)
		}
	}

	log.Printf("composing %d sides (%d commits)", nSides, len(commitInfo))
	tb, err := repo.TreeBuilder()
	e.Exit(err)
	emptyTreeOid, err := tb.Write()
	e.Exit(err)
	emptyTree, err := repo.LookupTree(emptyTreeOid)
	e.Exit(err)
	sig := &git.Signature{Name: "root", Email: "root"} // Deterministic signature.
	composedOid, err := repo.CreateCommit("", sig, sig, "", emptyTree, roots...)
	e.Exit(err)
	if *flVerbose {
		log.Println("virtual common head:", composedOid)
	}

	filterMapping := make(map[git.Oid]git.Oid)
	newHeads := make(map[string]*git.Commit)

	var progress *uiprogress.Progress
	var bar *uiprogress.Bar
	if !*flVerbose {
		progress = uiprogress.New()
		progress.Out = os.Stderr
		bar = progress.AddBar(len(commitInfo))
		progress.Start()
	}

	// libgit2 chronological topological walker in fact is not chronological.
	// totalWalker, err := repo.Walk()
	totalWalker, err := NewReverseTopologicalDateOrderCommitWalker(repo)
	e.Exit(err)
	// totalWalker.Sorting(git.SortTopological | git.SortTime | git.SortReverse)
	totalWalker.Push(composedOid)
	err = totalWalker.Iterate(func(commit *git.Commit) bool {
		oid := *commit.Id()
		if oid == *composedOid {
			return true // Skip our composed oid (and immediately finish).
		}
		ci := commitInfo[oid]

		parents := []*git.Commit{}
		useParentsFrom := uint(0)
		if len(ci.Branches) > 0 {
			// Replace first parent (if any) with heads of relevant branches.
			useParentsFrom = 1
			usedHeads := map[git.Oid]bool{}
			for _, branch := range ci.Branches {
				head := newHeads[branch]
				if head != nil && !usedHeads[*head.Id()] {
					parents = append(parents, head)
					usedHeads[*head.Id()] = true
				}
			}
		}
		// Translate old parents.
		for i := useParentsFrom; i < commit.ParentCount(); i++ {
			oldParentOid := commit.Parent(uint(i)).Id()
			newParentOid := filterMapping[*oldParentOid]
			newParent, err := repo.LookupCommit(&newParentOid)
			if err != nil {
				e.Exit(fmt.Errorf("Error: %v parent %v in %q was not mapped yet", &oid, oldParentOid, sideNames[ci.Side]))
			}
			parents = append(parents, newParent)
		}
		// Update trees.
		var tb *git.TreeBuilder
		if len(parents) > 0 {
			parentTree, err := parents[0].Tree()
			e.Exit(err)
			tb, err = repo.TreeBuilderFromTree(parentTree)
			e.Exit(err)
		} else {
			tb, err = repo.TreeBuilder()
			e.Exit(err)
		}
		tree, err := commit.Tree()
		e.Exit(err)
		err = tb.Insert(sideNames[ci.Side], tree.Id(), int(git.FilemodeTree))
		e.Exit(err)
		newTreeId, err := tb.Write()
		e.Exit(err)
		newTree, err := repo.LookupTree(newTreeId)
		e.Exit(err)
		// Commit.
		newOid, err := repo.CreateCommit("", commit.Author(), commit.Committer(), commit.Message(), newTree, parents...)
		e.Exit(err)
		filterMapping[oid] = *newOid
		// Update cached heads.
		newCommit, err := repo.LookupCommit(newOid)
		e.Exit(err)
		for _, branch := range ci.Branches {
			newHeads[branch] = newCommit
		}

		if bar != nil {
			bar.Incr()
		}
		if *flVerbose {
			fmt.Println(commit.Committer().When, &oid, ci.Side, ci.Branches, "→", newOid, len(parents))
		}

		return true
	})
	e.Exit(err)
	if progress != nil {
		progress.Stop()
	}

	log.Printf("composed %d branch(es)", len(newHeads))
	for headName, commit := range newHeads {
		_, err = repo.References.Create("refs/heads/"+headName, commit.Id(), true, "")
		e.Exit(err)
		fmt.Println(headName, "→", commit.Id())
	}

	// err = repo.ResetToCommit(newMaster, git.ResetHard, nil)
}
<commit_msg>Decrease needless verbosity,<commit_after>package main

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

	"github.com/gosuri/uiprogress"
	"github.com/orivej/e"
	git "github.com/orivej/git2go"
)

type CommitInfo struct {
	Side     int
	Branches []string // Short names of branches containing this commit.
}

var (
	flVerbose = flag.Bool("v", false, "enable verbose logging")
)

const usage = `usage : git-compose [<options>] <repository>...

Compose all branches from repositories (URLs, paths, or remote names)
into a single repository in the current directory.

`

func main() {
	log.SetFlags(0)
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, usage)
		flag.PrintDefaults()
	}
	flag.Parse()
	remotePaths := flag.Args()
	if len(remotePaths) < 1 {
		flag.Usage()
		os.Exit(1)
	}

	nSides := len(remotePaths)
	sideNames := make([]string, nSides)
	commitInfo := make(map[git.Oid]CommitInfo)
	roots := []*git.Commit{}

	repo, err := git.InitRepository(".", false)
	e.Exit(err)

	for i, remotePath := range remotePaths {
		// Fetch.
		remotePath, err := filepath.Abs(remotePath)
		e.Exit(err)

		name := filepath.Base(remotePath)
		sideNames[i] = name
		remoteGlob := fmt.Sprint("refs/remotes/", name, "/*")

		remote, err := repo.Remotes.Lookup(name)
		if err != nil {
			log.Printf("fetching %q (%s)", name, err)
			remote, err = repo.Remotes.Create(name, remotePath)
			e.Exit(err)
			// Use "git fetch" because libgit2 fetch is horribly slow for big local repos.
			// err = remote.Fetch(nil, nil, "")
			_ = remote
			cmd := exec.Command("git", "fetch", name)
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			err = cmd.Run()
			e.Exit(err)
		}
		// Store commit info.
		remoteRoots := []*git.Commit{}

		log.Printf("walking %q", name)
		walker, err := repo.Walk()
		e.Exit(err)
		err = walker.PushGlob(remoteGlob)
		e.Exit(err)
		err = walker.Iterate(func(commit *git.Commit) bool {
			oid := *commit.Id()
			commitInfo[oid] = CommitInfo{Side: i}
			return true
		})
		e.Exit(err)

		iter, err := repo.NewReferenceIteratorGlob(remoteGlob)
		e.Exit(err)
		for {
			ref, err := iter.Next()
			if err, ok := err.(*git.GitError); ok && err.Code == git.ErrIterOver {
				break
			}
			e.Exit(err)
			// Seed search with head commit.
			refCommit, err := repo.LookupCommit(ref.Target())
			e.Exit(err)
			roots = append(roots, refCommit)
			remoteRoots = append(remoteRoots, refCommit)
			// Store commit branches.
			branchName, err := ref.Branch().Name()
			e.Exit(err)
			branchName = strings.TrimPrefix(branchName, name+"/")
			walker.Reset()
			err = walker.Push(ref.Target())
			e.Exit(err)
			walker.SimplifyFirstParent()
			err = walker.Iterate(func(commit *git.Commit) bool {
				oid := *commit.Id()
				ci := commitInfo[oid]
				ci.Branches = append(ci.Branches, branchName)
				if branchName == "master" {
					// Reduce risk of missing sibling trees
					// with our strategy that takes them
					// from the first parent by making
					// "master" the first parent.
					n := len(ci.Branches) - 1
					ci.Branches[0], ci.Branches[n] = ci.Branches[n], ci.Branches[0]
				}

				commitInfo[oid] = ci
				return true
			})
			e.Exit(err)
		}
	}

	log.Printf("composing %d sides (%d commits)", nSides, len(commitInfo))
	tb, err := repo.TreeBuilder()
	e.Exit(err)
	emptyTreeOid, err := tb.Write()
	e.Exit(err)
	emptyTree, err := repo.LookupTree(emptyTreeOid)
	e.Exit(err)
	sig := &git.Signature{Name: "root", Email: "root"} // Deterministic signature.
	composedOid, err := repo.CreateCommit("", sig, sig, "", emptyTree, roots...)
	e.Exit(err)
	if *flVerbose {
		log.Println("virtual common head:", composedOid)
	}

	filterMapping := make(map[git.Oid]git.Oid)
	newHeads := make(map[string]*git.Commit)

	var progress *uiprogress.Progress
	var bar *uiprogress.Bar
	if !*flVerbose {
		progress = uiprogress.New()
		progress.Out = os.Stderr
		bar = progress.AddBar(len(commitInfo))
		progress.Start()
	}

	// libgit2 chronological topological walker in fact is not chronological.
	// totalWalker, err := repo.Walk()
	totalWalker, err := NewReverseTopologicalDateOrderCommitWalker(repo)
	e.Exit(err)
	// totalWalker.Sorting(git.SortTopological | git.SortTime | git.SortReverse)
	totalWalker.Push(composedOid)
	err = totalWalker.Iterate(func(commit *git.Commit) bool {
		oid := *commit.Id()
		if oid == *composedOid {
			return true // Skip our composed oid (and immediately finish).
		}
		ci := commitInfo[oid]

		parents := []*git.Commit{}
		useParentsFrom := uint(0)
		if len(ci.Branches) > 0 {
			// Replace first parent (if any) with heads of relevant branches.
			useParentsFrom = 1
			usedHeads := map[git.Oid]bool{}
			for _, branch := range ci.Branches {
				head := newHeads[branch]
				if head != nil && !usedHeads[*head.Id()] {
					parents = append(parents, head)
					usedHeads[*head.Id()] = true
				}
			}
		}
		// Translate old parents.
		for i := useParentsFrom; i < commit.ParentCount(); i++ {
			oldParentOid := commit.Parent(uint(i)).Id()
			newParentOid := filterMapping[*oldParentOid]
			newParent, err := repo.LookupCommit(&newParentOid)
			if err != nil {
				e.Exit(fmt.Errorf("Error: %v parent %v in %q was not mapped yet", &oid, oldParentOid, sideNames[ci.Side]))
			}
			parents = append(parents, newParent)
		}
		// Update trees.
		var tb *git.TreeBuilder
		if len(parents) > 0 {
			parentTree, err := parents[0].Tree()
			e.Exit(err)
			tb, err = repo.TreeBuilderFromTree(parentTree)
			e.Exit(err)
		} else {
			tb, err = repo.TreeBuilder()
			e.Exit(err)
		}
		tree, err := commit.Tree()
		e.Exit(err)
		err = tb.Insert(sideNames[ci.Side], tree.Id(), int(git.FilemodeTree))
		e.Exit(err)
		newTreeId, err := tb.Write()
		e.Exit(err)
		newTree, err := repo.LookupTree(newTreeId)
		e.Exit(err)
		// Commit.
		newOid, err := repo.CreateCommit("", commit.Author(), commit.Committer(), commit.Message(), newTree, parents...)
		e.Exit(err)
		filterMapping[oid] = *newOid
		// Update cached heads.
		newCommit, err := repo.LookupCommit(newOid)
		e.Exit(err)
		for _, branch := range ci.Branches {
			newHeads[branch] = newCommit
		}

		if bar != nil {
			bar.Incr()
		}
		if *flVerbose {
			fmt.Println(commit.Committer().When, &oid, ci.Side, ci.Branches, "→", newOid, len(parents))
		}

		return true
	})
	e.Exit(err)
	if progress != nil {
		progress.Stop()
	}

	for headName, commit := range newHeads {
		_, err = repo.References.Create("refs/heads/"+headName, commit.Id(), true, "")
		e.Exit(err)
	}
	log.Printf("composed %d branch(es)", len(newHeads))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"math/rand"
	"net"
	"net/http"
	"os"
	"sort"
	"strconv"
	"strings"
	"sync"
	"time"
)

var (
	version   = "0.5.2"
	github    = "https://github.com/ekalinin/awsping"
	useragent = fmt.Sprintf("AwsPing/%s (+%s)", version, github)
)

var (
	repeats = flag.Int("repeats", 1, "Number of repeats")
	useHTTP = flag.Bool("http", false, "Use http transport (default is tcp)")
	showVer = flag.Bool("v", false, "Show version")
	verbose = flag.Int("verbose", 0, "Verbosity level")
	service = flag.String("service", "dynamodb", "AWS Service: ec2, sdb, sns, sqs, ...")
)

var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

// Duration2ms converts time.Duration to ms (float64)
func Duration2ms(d time.Duration) float64 {
	return float64(d.Nanoseconds()) / 1000 / 1000
}

func mkRandoString(n int) string {
	b := make([]rune, n)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}

// AWSRegion description of the AWS EC2 region
type AWSRegion struct {
	Name      string
	Code      string
	Service   string
	Latencies []time.Duration
	Error     error
}

// CheckLatencyHTTP Test Latency via HTTP
func (r *AWSRegion) CheckLatencyHTTP(wg *sync.WaitGroup) {
	defer wg.Done()
	url := fmt.Sprintf("http://%s.%s.amazonaws.com/ping?x=%s", r.Service,
		r.Code, mkRandoString(13))
	client := &http.Client{}

	req, err := http.NewRequest("GET", url, nil)
	req.Header.Set("User-Agent", useragent)

	start := time.Now()
	resp, err := client.Do(req)
	r.Latencies = append(r.Latencies, time.Since(start))
	defer resp.Body.Close()

	r.Error = err
}

// CheckLatencyTCP Test Latency via TCP
func (r *AWSRegion) CheckLatencyTCP(wg *sync.WaitGroup) {
	defer wg.Done()
	tcpURI := fmt.Sprintf("%s.%s.amazonaws.com:80", r.Service, r.Code)
	tcpAddr, err := net.ResolveTCPAddr("tcp4", tcpURI)
	if err != nil {
		r.Error = err
		return
	}
	start := time.Now()
	conn, err := net.DialTCP("tcp", nil, tcpAddr)
	r.Latencies = append(r.Latencies, time.Since(start))
	defer conn.Close()

	r.Error = err
}

// GetLatency returns Latency in ms
func (r *AWSRegion) GetLatency() float64 {
	sum := float64(0)
	for _, l := range r.Latencies {
		sum += Duration2ms(l)
	}
	return sum / float64(len(r.Latencies))
}

// AWSRegions slice of the AWSRegion
type AWSRegions []AWSRegion

func (rs AWSRegions) Len() int {
	return len(rs)
}

func (rs AWSRegions) Less(i, j int) bool {
	return rs[i].GetLatency() < rs[j].GetLatency()
}

func (rs AWSRegions) Swap(i, j int) {
	rs[i], rs[j] = rs[j], rs[i]
}

// CalcLatency returns list of aws regions sorted by Latency
func CalcLatency(repeats int, useHTTP bool, service string) *AWSRegions {
	regions := AWSRegions{
		{Service: service, Name: "US-East (Virginia)", Code: "us-east-1"},
		{Service: service, Name: "US-East (Ohio)", Code: "us-east-2"},
		{Service: service, Name: "US-West (California)", Code: "us-west-1"},
		{Service: service, Name: "US-West (Oregon)", Code: "us-west-2"},
		{Service: service, Name: "Asia Pacific (Mumbai)", Code: "ap-south-1"},
		{Service: service, Name: "Asia Pacific (Seoul)", Code: "ap-northeast-2"},
		{Service: service, Name: "Asia Pacific (Singapore)", Code: "ap-southeast-1"},
		{Service: service, Name: "Asia Pacific (Sydney)", Code: "ap-southeast-2"},
		{Service: service, Name: "Asia Pacific (Tokyo)", Code: "ap-northeast-1"},
		{Service: service, Name: "Europe (Ireland)", Code: "eu-west-1"},
		{Service: service, Name: "Europe (London)", Code: "eu-west-2"},
		{Service: service, Name: "Europe (Frankfurt)", Code: "eu-central-1"},
		{Service: service, Name: "South America (São Paulo)", Code: "sa-east-1"},
		//{Name: "China (Beijing)", Code: "cn-north-1"},
	}
	var wg sync.WaitGroup

	for n := 1; n <= repeats; n++ {
		wg.Add(len(regions))
		for i := range regions {
			if useHTTP {
				go regions[i].CheckLatencyHTTP(&wg)
			} else {
				go regions[i].CheckLatencyTCP(&wg)
			}
		}
		wg.Wait()
	}

	sort.Sort(regions)
	return &regions
}

// LatencyOutput prints data into console
type LatencyOutput struct {
	Level int
}

func (lo *LatencyOutput) show0(regions *AWSRegions) {
	for _, r := range *regions {
		fmt.Printf("%-25s %20s\n", r.Name,
			fmt.Sprintf("%.2f ms", r.GetLatency()))
	}
}

func (lo *LatencyOutput) show1(regions *AWSRegions) {
	outFmt := "%5v %-15s %-30s %20s\n"
	fmt.Printf(outFmt, "", "Code", "Region", "Latency")
	for i, r := range *regions {
		ms := fmt.Sprintf("%.2f ms", r.GetLatency())
		fmt.Printf(outFmt, i, r.Code, r.Name, ms)
	}
}

func (lo *LatencyOutput) show2(regions *AWSRegions) {
	// format
	outFmt := "%5v %-15s %-25s"
	outFmt += strings.Repeat(" %15s", *repeats) + " %15s\n"
	// header
	outStr := []interface{}{"", "Code", "Region"}
	for i := 0; i < *repeats; i++ {
		outStr = append(outStr, "Try #"+strconv.Itoa(i+1))
	}
	outStr = append(outStr, "Avg Latency")

	// show header
	fmt.Printf(outFmt, outStr...)

	// each region stats
	for i, r := range *regions {
		outData := []interface{}{strconv.Itoa(i), r.Code, r.Name}
		for n := 0; n < *repeats; n++ {
			outData = append(outData, fmt.Sprintf("%.2f ms",
				Duration2ms(r.Latencies[n])))
		}
		outData = append(outData, fmt.Sprintf("%.2f ms", r.GetLatency()))
		fmt.Printf(outFmt, outData...)
	}
}

// Show print data
func (lo *LatencyOutput) Show(regions *AWSRegions) {
	switch lo.Level {
	case 0:
		lo.show0(regions)
	case 1:
		lo.show1(regions)
	case 2:
		lo.show2(regions)
	}
}

func main() {

	flag.Parse()

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

	regions := CalcLatency(*repeats, *useHTTP, *service)
	lo := LatencyOutput{*verbose}
	lo.Show(regions)
}

func init() {
	rand.Seed(time.Now().UnixNano())
}
<commit_msg>fixed #5. unhandled error<commit_after>package main

import (
	"flag"
	"fmt"
	"math/rand"
	"net"
	"net/http"
	"os"
	"sort"
	"strconv"
	"strings"
	"sync"
	"time"
)

var (
	version   = "0.5.2"
	github    = "https://github.com/ekalinin/awsping"
	useragent = fmt.Sprintf("AwsPing/%s (+%s)", version, github)
)

var (
	repeats = flag.Int("repeats", 1, "Number of repeats")
	useHTTP = flag.Bool("http", false, "Use http transport (default is tcp)")
	showVer = flag.Bool("v", false, "Show version")
	verbose = flag.Int("verbose", 0, "Verbosity level")
	service = flag.String("service", "dynamodb", "AWS Service: ec2, sdb, sns, sqs, ...")
)

var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

// Duration2ms converts time.Duration to ms (float64)
func Duration2ms(d time.Duration) float64 {
	return float64(d.Nanoseconds()) / 1000 / 1000
}

func mkRandoString(n int) string {
	b := make([]rune, n)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}

// AWSRegion description of the AWS EC2 region
type AWSRegion struct {
	Name      string
	Code      string
	Service   string
	Latencies []time.Duration
	Error     error
}

// CheckLatencyHTTP Test Latency via HTTP
func (r *AWSRegion) CheckLatencyHTTP(wg *sync.WaitGroup) {
	defer wg.Done()
	url := fmt.Sprintf("http://%s.%s.amazonaws.com/ping?x=%s", r.Service,
		r.Code, mkRandoString(13))
	client := &http.Client{}

	req, err := http.NewRequest("GET", url, nil)
	req.Header.Set("User-Agent", useragent)

	start := time.Now()
	resp, err := client.Do(req)
	r.Latencies = append(r.Latencies, time.Since(start))
	defer resp.Body.Close()

	r.Error = err
}

// CheckLatencyTCP Test Latency via TCP
func (r *AWSRegion) CheckLatencyTCP(wg *sync.WaitGroup) {
	defer wg.Done()
	tcpURI := fmt.Sprintf("%s.%s.amazonaws.com:80", r.Service, r.Code)
	tcpAddr, err := net.ResolveTCPAddr("tcp4", tcpURI)
	if err != nil {
		r.Error = err
		return
	}
	start := time.Now()
	conn, err := net.DialTCP("tcp", nil, tcpAddr)
	if err != nil {
		r.Error = err
		return
	}
	r.Latencies = append(r.Latencies, time.Since(start))
	defer conn.Close()

	r.Error = err
}

// GetLatency returns Latency in ms
func (r *AWSRegion) GetLatency() float64 {
	sum := float64(0)
	for _, l := range r.Latencies {
		sum += Duration2ms(l)
	}
	return sum / float64(len(r.Latencies))
}

// GetLatencyStr returns Latency in string
func (r *AWSRegion) GetLatencyStr() string {
	if r.Error != nil {
		return r.Error.Error()
	}
	return fmt.Sprintf("%.2f ms", r.GetLatency())
}

// AWSRegions slice of the AWSRegion
type AWSRegions []AWSRegion

func (rs AWSRegions) Len() int {
	return len(rs)
}

func (rs AWSRegions) Less(i, j int) bool {
	return rs[i].GetLatency() < rs[j].GetLatency()
}

func (rs AWSRegions) Swap(i, j int) {
	rs[i], rs[j] = rs[j], rs[i]
}

// CalcLatency returns list of aws regions sorted by Latency
func CalcLatency(repeats int, useHTTP bool, service string) *AWSRegions {
	regions := AWSRegions{
		{Service: service, Name: "US-East (Virginia)", Code: "us-east-1"},
		{Service: service, Name: "US-East (Ohio)", Code: "us-east-2"},
		{Service: service, Name: "US-West (California)", Code: "us-west-1"},
		{Service: service, Name: "US-West (Oregon)", Code: "us-west-2"},
		{Service: service, Name: "Asia Pacific (Mumbai)", Code: "ap-south-1"},
		{Service: service, Name: "Asia Pacific (Seoul)", Code: "ap-northeast-2"},
		{Service: service, Name: "Asia Pacific (Singapore)", Code: "ap-southeast-1"},
		{Service: service, Name: "Asia Pacific (Sydney)", Code: "ap-southeast-2"},
		{Service: service, Name: "Asia Pacific (Tokyo)", Code: "ap-northeast-1"},
		{Service: service, Name: "Europe (Ireland)", Code: "eu-west-1"},
		{Service: service, Name: "Europe (London)", Code: "eu-west-2"},
		{Service: service, Name: "Europe (Frankfurt)", Code: "eu-central-1"},
		{Service: service, Name: "South America (São Paulo)", Code: "sa-east-1"},
		//{Name: "China (Beijing)", Code: "cn-north-1"},
	}
	var wg sync.WaitGroup

	for n := 1; n <= repeats; n++ {
		wg.Add(len(regions))
		for i := range regions {
			if useHTTP {
				go regions[i].CheckLatencyHTTP(&wg)
			} else {
				go regions[i].CheckLatencyTCP(&wg)
			}
		}
		wg.Wait()
	}

	sort.Sort(regions)
	return &regions
}

// LatencyOutput prints data into console
type LatencyOutput struct {
	Level int
}

func (lo *LatencyOutput) show0(regions *AWSRegions) {
	for _, r := range *regions {
		fmt.Printf("%-25s %20s\n", r.Name, r.GetLatencyStr())
	}
}

func (lo *LatencyOutput) show1(regions *AWSRegions) {
	outFmt := "%5v %-15s %-30s %20s\n"
	fmt.Printf(outFmt, "", "Code", "Region", "Latency")
	for i, r := range *regions {
		fmt.Printf(outFmt, i, r.Code, r.Name, r.GetLatencyStr())
	}
}

func (lo *LatencyOutput) show2(regions *AWSRegions) {
	// format
	outFmt := "%5v %-15s %-25s"
	outFmt += strings.Repeat(" %15s", *repeats) + " %15s\n"
	// header
	outStr := []interface{}{"", "Code", "Region"}
	for i := 0; i < *repeats; i++ {
		outStr = append(outStr, "Try #"+strconv.Itoa(i+1))
	}
	outStr = append(outStr, "Avg Latency")

	// show header
	fmt.Printf(outFmt, outStr...)

	// each region stats
	for i, r := range *regions {
		outData := []interface{}{strconv.Itoa(i), r.Code, r.Name}
		for n := 0; n < *repeats; n++ {
			outData = append(outData, fmt.Sprintf("%.2f ms",
				Duration2ms(r.Latencies[n])))
		}
		outData = append(outData, fmt.Sprintf("%.2f ms", r.GetLatency()))
		fmt.Printf(outFmt, outData...)
	}
}

// Show print data
func (lo *LatencyOutput) Show(regions *AWSRegions) {
	switch lo.Level {
	case 0:
		lo.show0(regions)
	case 1:
		lo.show1(regions)
	case 2:
		lo.show2(regions)
	}
}

func main() {

	flag.Parse()

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

	regions := CalcLatency(*repeats, *useHTTP, *service)
	lo := LatencyOutput{*verbose}
	lo.Show(regions)
}

func init() {
	rand.Seed(time.Now().UnixNano())
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/splitsh/lite/splitter"
)

type prefixesFlag []*splitter.Prefix

func (p *prefixesFlag) String() string {
	return fmt.Sprint(*p)
}

func (p *prefixesFlag) Set(value string) error {
	parts := strings.Split(value, ":")
	from := parts[0]
	to := ""
	if len(parts) > 1 {
		to = parts[1]
	}

	// value must be unique
	for _, prefix := range []*splitter.Prefix(*p) {
		// FIXME: to should be normalized (xxx vs xxx/ for instance)
		if prefix.To == to {
			return fmt.Errorf("Cannot have two prefix splits under the same directory: %s -> %s vs %s -> %s", prefix.From, prefix.To, from, to)
		}
	}

	*p = append(*p, &splitter.Prefix{From: from, To: to})
	return nil
}

var prefixes prefixesFlag
var origin, target, commit, path, gitVersion string
var scratch, debug, quiet, legacy, progress bool

func init() {
	flag.Var(&prefixes, "prefix", "The directory(ies) to split")
	flag.StringVar(&origin, "origin", "HEAD", "The branch to split (optional, defaults to the current one)")
	flag.StringVar(&target, "target", "", "The branch to create when split is finished (optional)")
	flag.StringVar(&commit, "commit", "", "The commit at which to start the split (optional)")
	flag.StringVar(&path, "path", ".", "The repository path (optional, current directory by default)")
	flag.BoolVar(&scratch, "scratch", false, "Flush the cache (optional)")
	flag.BoolVar(&debug, "debug", false, "Enable the debug mode (optional)")
	flag.BoolVar(&quiet, "quiet", false, "Suppress the output (optional)")
	flag.BoolVar(&legacy, "legacy", false, "[DEPRECATED] Enable the legacy mode for projects migrating from an old version of git subtree split (optional)")
	flag.StringVar(&gitVersion, "git", "latest", "Simulate a given version of Git (optional)")
	flag.BoolVar(&progress, "progress", false, "Show progress bar (optional, cannot be enabled when debug is enabled)")
}

func main() {
	flag.Parse()

	if len(prefixes) == 0 {
		fmt.Println("You must provide the directory to split via the --prefix flag")
		os.Exit(1)
	}

	if legacy {
		fmt.Fprintf(os.Stderr, `The --legacy option is deprecated (use --git="<1.8.2" instead)`)
		gitVersion = "<1.8.2"
	}

	config := &splitter.Config{
		Path:       path,
		Origin:     origin,
		Prefixes:   []*splitter.Prefix(prefixes),
		Target:     target,
		Commit:     commit,
		Debug:      debug && !quiet,
		Scratch:    scratch,
		GitVersion: gitVersion,
	}

	result := &splitter.Result{}

	var ticker *time.Ticker
	if progress && !debug && !quiet {
		ticker = time.NewTicker(time.Millisecond * 50)
		go func() {
			for range ticker.C {
				fmt.Fprintf(os.Stderr, "%d commits created, %d commits traversed\r", result.Created(), result.Traversed())
			}
		}()
	}

	err := splitter.Split(config, result)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if ticker != nil {
		ticker.Stop()
	}

	if !quiet {
		fmt.Fprintf(os.Stderr, "%d commits created, %d commits traversed, in %s\n", result.Created(), result.Traversed(), result.Duration(time.Millisecond))
	}

	if result.Head() != nil {
		fmt.Println(result.Head().String())
	}
}
<commit_msg>added --version flag<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/splitsh/lite/splitter"
)

var (
	version = "dev"
)

type prefixesFlag []*splitter.Prefix

func (p *prefixesFlag) String() string {
	return fmt.Sprint(*p)
}

func (p *prefixesFlag) Set(value string) error {
	parts := strings.Split(value, ":")
	from := parts[0]
	to := ""
	if len(parts) > 1 {
		to = parts[1]
	}

	// value must be unique
	for _, prefix := range []*splitter.Prefix(*p) {
		// FIXME: to should be normalized (xxx vs xxx/ for instance)
		if prefix.To == to {
			return fmt.Errorf("Cannot have two prefix splits under the same directory: %s -> %s vs %s -> %s", prefix.From, prefix.To, from, to)
		}
	}

	*p = append(*p, &splitter.Prefix{From: from, To: to})
	return nil
}

var prefixes prefixesFlag
var origin, target, commit, path, gitVersion string
var scratch, debug, quiet, legacy, progress, v bool

func init() {
	flag.Var(&prefixes, "prefix", "The directory(ies) to split")
	flag.StringVar(&origin, "origin", "HEAD", "The branch to split (optional, defaults to the current one)")
	flag.StringVar(&target, "target", "", "The branch to create when split is finished (optional)")
	flag.StringVar(&commit, "commit", "", "The commit at which to start the split (optional)")
	flag.StringVar(&path, "path", ".", "The repository path (optional, current directory by default)")
	flag.BoolVar(&scratch, "scratch", false, "Flush the cache (optional)")
	flag.BoolVar(&debug, "debug", false, "Enable the debug mode (optional)")
	flag.BoolVar(&quiet, "quiet", false, "Suppress the output (optional)")
	flag.BoolVar(&legacy, "legacy", false, "[DEPRECATED] Enable the legacy mode for projects migrating from an old version of git subtree split (optional)")
	flag.StringVar(&gitVersion, "git", "latest", "Simulate a given version of Git (optional)")
	flag.BoolVar(&progress, "progress", false, "Show progress bar (optional, cannot be enabled when debug is enabled)")
	flag.BoolVar(&v, "version", false, "Show version")
}

func main() {
	flag.Parse()

	if v {
		fmt.Printf("splitsh-lite version %s\n", version)
		os.Exit(0)
	}

	if len(prefixes) == 0 {
		fmt.Println("You must provide the directory to split via the --prefix flag")
		os.Exit(1)
	}

	if legacy {
		fmt.Fprintf(os.Stderr, `The --legacy option is deprecated (use --git="<1.8.2" instead)`)
		gitVersion = "<1.8.2"
	}

	config := &splitter.Config{
		Path:       path,
		Origin:     origin,
		Prefixes:   []*splitter.Prefix(prefixes),
		Target:     target,
		Commit:     commit,
		Debug:      debug && !quiet,
		Scratch:    scratch,
		GitVersion: gitVersion,
	}

	result := &splitter.Result{}

	var ticker *time.Ticker
	if progress && !debug && !quiet {
		ticker = time.NewTicker(time.Millisecond * 50)
		go func() {
			for range ticker.C {
				fmt.Fprintf(os.Stderr, "%d commits created, %d commits traversed\r", result.Created(), result.Traversed())
			}
		}()
	}

	err := splitter.Split(config, result)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if ticker != nil {
		ticker.Stop()
	}

	if !quiet {
		fmt.Fprintf(os.Stderr, "%d commits created, %d commits traversed, in %s\n", result.Created(), result.Traversed(), result.Duration(time.Millisecond))
	}

	if result.Head() != nil {
		fmt.Println(result.Head().String())
	}
}
<|endoftext|>


<commit_before>package main

import (
    "os"
    "log"

    "github.com/joho/godotenv"
    "github.com/urfave/cli"

    "github.com/earaujoassis/space/tasks"
    "github.com/earaujoassis/space/config"
)

func init() {
    err := godotenv.Load()
    if err != nil {
        log.Printf("> The environment file (.env) doesn't exist; skipping .env\n")
    }

    config.LoadConfig()
}

func main() {
    app := cli.NewApp()
    app.Name = "space"
    app.Usage = "A user management microservice; OAuth 2 provider"
    app.EnableBashCompletion = true
    app.Commands = []cli.Command{
        {
            Name:    "serve",
            Aliases: []string{"s"},
            Usage:   "Serve the application server",
            Action:  func(c *cli.Context) error {
                tasks.Server()
                return nil
            },
        },
        {
            Name:    "client",
            Aliases: []string{"c"},
            Usage:   "Manage client application",
            Subcommands: []cli.Command{
                {
                    Name:  "create",
                    Usage: "Create a new client application",
                    Action: func(c *cli.Context) error {
                        tasks.CreateClient()
                        return nil
                    },
                },
            },
        },
        {
            Name: "feature",
            Aliases: []string{"c"},
            Usage:   "Toggle features flags ON/OFF",
            Action:  func(c *cli.Context) error {
                tasks.ToggleFeature()
                return nil
            },
        },
    }

    app.Run(os.Args)
}
<commit_msg>hotfix: update client subcommand alias<commit_after>package main

import (
    "os"
    "log"

    "github.com/joho/godotenv"
    "github.com/urfave/cli"

    "github.com/earaujoassis/space/tasks"
    "github.com/earaujoassis/space/config"
)

func init() {
    err := godotenv.Load()
    if err != nil {
        log.Printf("> The environment file (.env) doesn't exist; skipping .env\n")
    }

    config.LoadConfig()
}

func main() {
    app := cli.NewApp()
    app.Name = "space"
    app.Usage = "A user management microservice; OAuth 2 provider"
    app.EnableBashCompletion = true
    app.Commands = []cli.Command{
        {
            Name:    "serve",
            Aliases: []string{"s"},
            Usage:   "Serve the application server",
            Action:  func(c *cli.Context) error {
                tasks.Server()
                return nil
            },
        },
        {
            Name:    "client",
            Aliases: []string{"c"},
            Usage:   "Manage client application",
            Subcommands: []cli.Command{
                {
                    Name:  "create",
                    Usage: "Create a new client application",
                    Action: func(c *cli.Context) error {
                        tasks.CreateClient()
                        return nil
                    },
                },
            },
        },
        {
            Name: "feature",
            Aliases: []string{"f"},
            Usage:   "Toggle features flags ON/OFF",
            Action:  func(c *cli.Context) error {
                tasks.ToggleFeature()
                return nil
            },
        },
    }

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


<commit_before>package main

import (
	"os"
	"path"
	"path/filepath"
	"plugin"
	"sync"

	log "github.com/Sirupsen/logrus"
	"github.com/patrobinson/go-fish/input"
	"github.com/patrobinson/go-fish/output"
)

// Rule is an interface for rule implementations
type Rule interface {
	Start(*chan interface{}, *chan interface{}, *sync.WaitGroup)
	Process(interface{}) bool
	String() string
}

// Input is an interface for input implemenations
type Input interface {
	Retrieve(*chan []byte)
	Init() error
}

// Output is an interface for output implementations
type Output interface {
	Sink(*chan interface{}, *sync.WaitGroup)
}

func main() {
	configFile := os.Args[1]
	file, err := os.Open(configFile)
	if err != nil {
		log.Fatalf("Failed to open Config File: %v", err)
	}
	config, err := parseConfig(file)
	if err != nil {
		log.Fatalf("Failed to load config: %v", err)
	}
	var in Input
	if config.KinesisConfig != nil {
		in = input.KinesisInput{
			StreamName: (*config.KinesisConfig).StreamName,
		}
	} else {
		in = input.FileInput{FileName: (*config.FileConfig).InputFile}
	}
	in.Init()
	out := output.FileOutput{FileName: (*config.FileConfig).OutputFile}

	run(config.RuleFolder, config.EventTypeFolder, in, out)
}

func run(rulesFolder string, eventFolder string, in interface{}, out interface{}) {
	log.SetLevel(log.DebugLevel)

	var outWg sync.WaitGroup
	var ruleWg sync.WaitGroup

	outChan := startOutput(out, &outWg)
	rChans := startRules(rulesFolder, outChan, &ruleWg)
	inChan := startInput(in)
	eventTypes, err := getEventTypes(eventFolder)
	if err != nil {
		log.Fatalf("Failed to get Event plugins: %v", err)
	}

	// receive from inputs and send to all rules
	func(iChan *chan []byte, ruleChans []*chan interface{}) {
		for data := range *iChan {
			evt, err := matchEventType(eventTypes, data)
			if err != nil {
				log.Infof("Error matching event: %v", err)
			}
			for _, i := range ruleChans {
				*i <- evt
			}
		}
	}(inChan, rChans)

	log.Debug("Input done, closing rule channels\n")

	for _, c := range rChans {
		close(*c)
	}
	ruleWg.Wait()

	log.Debug("Closing output channels\n")
	close(*outChan)
	outWg.Wait()
}

func startOutput(out interface{}, wg *sync.WaitGroup) *chan interface{} {
	(*wg).Add(1)
	outChan := make(chan interface{})
	outSender := out.(Output)
	go outSender.Sink(&outChan, wg)
	return &outChan
}

func startInput(in interface{}) *chan []byte {
	inChan := make(chan []byte)
	inReceiver := in.(Input)
	go inReceiver.Retrieve(&inChan)
	return &inChan
}

func startRules(rulesFolder string, output *chan interface{}, wg *sync.WaitGroup) []*chan interface{} {
	pluginGlob := path.Join(rulesFolder, "/*.so")
	plugins, err := filepath.Glob(pluginGlob)
	if err != nil {
		log.Fatal(err)
	}

	var rules []*plugin.Plugin
	for _, pFile := range plugins {
		if plug, err := plugin.Open(pFile); err == nil {
			rules = append(rules, plug)
		}
	}

	log.Infof("Found %v rules", len(rules))

	var inputs []*chan interface{}
	for _, r := range rules {
		symRule, err := r.Lookup("Rule")
		if err != nil {
			log.Errorf("Rule has no Rule symbol: %v", err)
			continue
		}
		var rule Rule
		rule, ok := symRule.(Rule)
		if !ok {
			log.Errorf("Rule is not a rule type. Does it implement the Process() function?")
			continue
		}
		input := make(chan interface{})
		inputs = append(inputs, &input)
		log.Debugf("Starting %v\n", rule.String())
		(*wg).Add(1)
		go rule.Start(&input, output, wg)
	}

	return inputs
}
<commit_msg>Use the input field to determine what input type to use<commit_after>package main

import (
	"os"
	"path"
	"path/filepath"
	"plugin"
	"sync"

	log "github.com/Sirupsen/logrus"
	"github.com/patrobinson/go-fish/input"
	"github.com/patrobinson/go-fish/output"
)

// Rule is an interface for rule implementations
type Rule interface {
	Start(*chan interface{}, *chan interface{}, *sync.WaitGroup)
	Process(interface{}) bool
	String() string
}

// Input is an interface for input implemenations
type Input interface {
	Retrieve(*chan []byte)
	Init() error
}

// Output is an interface for output implementations
type Output interface {
	Sink(*chan interface{}, *sync.WaitGroup)
}

func main() {
	configFile := os.Args[1]
	file, err := os.Open(configFile)
	if err != nil {
		log.Fatalf("Failed to open Config File: %v", err)
	}
	config, err := parseConfig(file)
	if err != nil {
		log.Fatalf("Failed to load config: %v", err)
	}
	var in Input
	if config.Input == "Kinesis" {
		in = input.KinesisInput{
			StreamName: (*config.KinesisConfig).StreamName,
		}
	} else if config.Input == "File" {
		in = input.FileInput{FileName: (*config.FileConfig).InputFile}
	} else {
		log.Fatalf("Invalid input type: %v", config.Input)
	}
	in.Init()
	out := output.FileOutput{FileName: (*config.FileConfig).OutputFile}

	run(config.RuleFolder, config.EventTypeFolder, in, out)
}

func run(rulesFolder string, eventFolder string, in interface{}, out interface{}) {
	log.SetLevel(log.DebugLevel)

	var outWg sync.WaitGroup
	var ruleWg sync.WaitGroup

	outChan := startOutput(out, &outWg)
	rChans := startRules(rulesFolder, outChan, &ruleWg)
	inChan := startInput(in)
	eventTypes, err := getEventTypes(eventFolder)
	if err != nil {
		log.Fatalf("Failed to get Event plugins: %v", err)
	}

	// receive from inputs and send to all rules
	func(iChan *chan []byte, ruleChans []*chan interface{}) {
		for data := range *iChan {
			evt, err := matchEventType(eventTypes, data)
			if err != nil {
				log.Infof("Error matching event: %v", err)
			}
			for _, i := range ruleChans {
				*i <- evt
			}
		}
	}(inChan, rChans)

	log.Debug("Input done, closing rule channels\n")

	for _, c := range rChans {
		close(*c)
	}
	ruleWg.Wait()

	log.Debug("Closing output channels\n")
	close(*outChan)
	outWg.Wait()
}

func startOutput(out interface{}, wg *sync.WaitGroup) *chan interface{} {
	(*wg).Add(1)
	outChan := make(chan interface{})
	outSender := out.(Output)
	go outSender.Sink(&outChan, wg)
	return &outChan
}

func startInput(in interface{}) *chan []byte {
	inChan := make(chan []byte)
	inReceiver := in.(Input)
	go inReceiver.Retrieve(&inChan)
	return &inChan
}

func startRules(rulesFolder string, output *chan interface{}, wg *sync.WaitGroup) []*chan interface{} {
	pluginGlob := path.Join(rulesFolder, "/*.so")
	plugins, err := filepath.Glob(pluginGlob)
	if err != nil {
		log.Fatal(err)
	}

	var rules []*plugin.Plugin
	for _, pFile := range plugins {
		if plug, err := plugin.Open(pFile); err == nil {
			rules = append(rules, plug)
		}
	}

	log.Infof("Found %v rules", len(rules))

	var inputs []*chan interface{}
	for _, r := range rules {
		symRule, err := r.Lookup("Rule")
		if err != nil {
			log.Errorf("Rule has no Rule symbol: %v", err)
			continue
		}
		var rule Rule
		rule, ok := symRule.(Rule)
		if !ok {
			log.Errorf("Rule is not a rule type. Does it implement the Process() function?")
			continue
		}
		input := make(chan interface{})
		inputs = append(inputs, &input)
		log.Debugf("Starting %v\n", rule.String())
		(*wg).Add(1)
		go rule.Start(&input, output, wg)
	}

	return inputs
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"runtime"
	"strings"
	"time"
)

var knownPaths []string
var boottime time.Time

func main() {

	boottime = time.Now()

	tls := true

	currDir, err := os.Getwd()
	if err != nil {
		log.Fatalf("Getwd: %s", err)
	}

	var addr, httpsAddr, key, cert string

	flag.StringVar(&key, "key", "key.pem", "TLS key file")
	flag.StringVar(&cert, "cert", "cert.pem", "TLS cert file")
	flag.StringVar(&addr, "addr", ":8080", "HTTP listen address")
	flag.StringVar(&httpsAddr, "httpsAddr", ":8443", "HTTPS listen address")
	flag.Parse()

	if !fileExists(key) {
		log.Printf("TLS key file not found: %s - disabling TLS", key)
		tls = false
	}

	if !fileExists(cert) {
		log.Printf("TLS cert file not found: %s - disabling TLS", cert)
		tls = false
	}

	http.HandleFunc("/", rootHandler) // default handler

	registerStatic("/www/", currDir)

	log.Printf("serving on port TCP HTTP=%s HTTPS=%s TLS=%v", addr, httpsAddr, tls)

	if tls {

		httpPort := "80"
		h := strings.Split(addr, ":")
		if len(h) > 1 {
			httpPort = h[1]
		}

		httpsPort := "443"
		hs := strings.Split(httpsAddr, ":")
		if len(hs) > 1 {
			httpsPort = hs[1]
		}

		if httpPort != httpsPort {
			log.Printf("installing redirect from HTTP=%s to HTTPS=%s", addr, httpsPort)

			redirectTLS := func(w http.ResponseWriter, r *http.Request) {
				host := strings.Split(r.Host, ":")[0]
				http.Redirect(w, r, "https://"+host+":"+httpsPort+r.RequestURI, http.StatusMovedPermanently)
			}

			// http-to-https redirect server
			go func() {
				if err := http.ListenAndServe(addr, http.HandlerFunc(redirectTLS)); err != nil {
					log.Fatalf("redirect: ListenAndServe: %s: %v", addr, err)
				}
			}()
		}

		// Serve TLS
		if err := http.ListenAndServeTLS(httpsAddr, cert, key, nil); err != nil {
			log.Fatalf("ListenAndServeTLS: %s: %v", httpsAddr, err)
		}
		return
	}

	if err := http.ListenAndServe(addr, nil); err != nil {
		log.Fatalf("ListenAndServe: %s: %v", addr, err)
	}
}

func fileExists(path string) bool {
	_, err := os.Stat(path)
	return err == nil
}

type staticHandler struct {
	innerHandler http.Handler
}

func registerStatic(path, dir string) {
	http.Handle(path, staticHandler{http.StripPrefix(path, http.FileServer(http.Dir(dir)))})
	knownPaths = append(knownPaths, path)
	log.Printf("registering static directory %s as www path %s", dir, path)
}

func (handler staticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Printf("staticHandler.ServeHTTP url=%s from=%s", r.URL.Path, r.RemoteAddr)
	handler.innerHandler.ServeHTTP(w, r)
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	msg := fmt.Sprintf("rootHandler: url=%s from=%s", r.URL.Path, r.RemoteAddr)
	log.Print(msg)

	var paths string
	for _, p := range knownPaths {
		paths += fmt.Sprintf("%s
", p, p)
	}

	var errMsg string
	if r.URL.Path != "/" {
		errMsg = fmt.Sprintf("
Path not found!
Path not found: [%s]", r.URL.Path)
	}

	rootStr :=
		`<!DOCTYPE html>

    <title>gowebhello root page</title>

gowebhello root page

    gowebhello is a simple golang replacement for 'python -m SimpleHTTPServer'.

Welcome!

	Golang version: %s

	Application version: 3

	Application arguments: %v

	Application dir: %s

	Server hostname: %s

	Your address: %s

	Current time: %s

	Uptime: %s

    %s

All known paths:

    %s

`

	cwd, errCwd := os.Getwd()
	if errCwd != nil {
		cwd = cwd + " (error: " + errCwd.Error() + ")"
	}

	host, errHost := os.Hostname()
	if errHost != nil {
		host = host + " (error: " + errHost.Error() + ")"
	}

	now := time.Now()

	rootPage := fmt.Sprintf(rootStr, runtime.Version(), os.Args, cwd, host, r.RemoteAddr, now, time.Since(boottime), errMsg, paths)

	io.WriteString(w, rootPage)
}
<commit_msg>Clean-up messages.<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"runtime"
	"strings"
	"time"
)

var knownPaths []string
var boottime time.Time

func main() {

	boottime = time.Now()

	tls := true

	currDir, err := os.Getwd()
	if err != nil {
		log.Fatalf("Getwd: %s", err)
	}

	var addr, httpsAddr, key, cert string

	flag.StringVar(&key, "key", "key.pem", "TLS key file")
	flag.StringVar(&cert, "cert", "cert.pem", "TLS cert file")
	flag.StringVar(&addr, "addr", ":8080", "HTTP listen address")
	flag.StringVar(&httpsAddr, "httpsAddr", ":8443", "HTTPS listen address")
	flag.Parse()

	if !fileExists(key) {
		log.Printf("TLS key file not found: %s - disabling TLS", key)
		tls = false
	}

	if !fileExists(cert) {
		log.Printf("TLS cert file not found: %s - disabling TLS", cert)
		tls = false
	}

	http.HandleFunc("/", rootHandler) // default handler

	registerStatic("/www/", currDir)

	log.Printf("using TCP ports HTTP=%s HTTPS=%s TLS=%v", addr, httpsAddr, tls)

	if tls {

		httpPort := "80"
		h := strings.Split(addr, ":")
		if len(h) > 1 {
			httpPort = h[1]
		}

		httpsPort := "443"
		hs := strings.Split(httpsAddr, ":")
		if len(hs) > 1 {
			httpsPort = hs[1]
		}

		if httpPort != httpsPort {
			log.Printf("installing redirect from HTTP=%s to HTTPS=%s", addr, httpsPort)

			redirectTLS := func(w http.ResponseWriter, r *http.Request) {
				host := strings.Split(r.Host, ":")[0]
				http.Redirect(w, r, "https://"+host+":"+httpsPort+r.RequestURI, http.StatusMovedPermanently)
			}

			// http-to-https redirect server
			go func() {
				if err := http.ListenAndServe(addr, http.HandlerFunc(redirectTLS)); err != nil {
					log.Fatalf("redirect: ListenAndServe: %s: %v", addr, err)
				}
			}()
		}

		log.Printf("serving HTTPS on TCP %s", httpsAddr)
		if err := http.ListenAndServeTLS(httpsAddr, cert, key, nil); err != nil {
			log.Fatalf("ListenAndServeTLS: %s: %v", httpsAddr, err)
		}
		return
	}

	log.Printf("serving HTTP on TCP %s", addr)
	if err := http.ListenAndServe(addr, nil); err != nil {
		log.Fatalf("ListenAndServe: %s: %v", addr, err)
	}
}

func fileExists(path string) bool {
	_, err := os.Stat(path)
	return err == nil
}

type staticHandler struct {
	innerHandler http.Handler
}

func registerStatic(path, dir string) {
	http.Handle(path, staticHandler{http.StripPrefix(path, http.FileServer(http.Dir(dir)))})
	knownPaths = append(knownPaths, path)
	log.Printf("registering static directory %s as www path %s", dir, path)
}

func (handler staticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Printf("staticHandler.ServeHTTP url=%s from=%s", r.URL.Path, r.RemoteAddr)
	handler.innerHandler.ServeHTTP(w, r)
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	msg := fmt.Sprintf("rootHandler: url=%s from=%s", r.URL.Path, r.RemoteAddr)
	log.Print(msg)

	var paths string
	for _, p := range knownPaths {
		paths += fmt.Sprintf("%s
", p, p)
	}

	var errMsg string
	if r.URL.Path != "/" {
		errMsg = fmt.Sprintf("
Path not found!
Path not found: [%s]", r.URL.Path)
	}

	rootStr :=
		`<!DOCTYPE html>

    <title>gowebhello root page</title>

gowebhello root page

    gowebhello is a simple golang replacement for 'python -m SimpleHTTPServer'.

Welcome!

	Golang version: %s

	Application version: 3

	Application arguments: %v

	Application dir: %s

	Server hostname: %s

	Your address: %s

	Current time: %s

	Uptime: %s

    %s

All known paths:

    %s

`

	cwd, errCwd := os.Getwd()
	if errCwd != nil {
		cwd = cwd + " (error: " + errCwd.Error() + ")"
	}

	host, errHost := os.Hostname()
	if errHost != nil {
		host = host + " (error: " + errHost.Error() + ")"
	}

	now := time.Now()

	rootPage := fmt.Sprintf(rootStr, runtime.Version(), os.Args, cwd, host, r.RemoteAddr, now, time.Since(boottime), errMsg, paths)

	io.WriteString(w, rootPage)
}
<|endoftext|>