<commit_before>package cli

import (
	"fmt"
	"github.com/mattes/fugu/config"
	"github.com/mattes/fugu/docker"
	"github.com/mattes/fugu/file"
	"io/ioutil"
	"os"
	"os/exec"
	"sort"
	"strings"
)

func CmdRun(fugufilePath string, args []string, label string) {

	// docker options
	// see http://docs.docker.com/reference/commandline/cli/#run

	var conf = []config.Value{

		// add new options: image, command and args
		&config.StringValue{Name: []string{"image"}},
		&config.StringValue{Name: []string{"command"}},
		&config.StringSliceValue{Name: []string{"args"}},

		// official docker options ...
		&config.BoolValue{Name: []string{"rm"}},
		&config.BoolValue{Name: []string{"detach", "d"}},
		&config.BoolValue{Name: []string{"networking", "n"}},
		&config.BoolValue{Name: []string{"privileged"}},
		&config.BoolValue{Name: []string{"publish-all", "P"}},
		&config.BoolValue{Name: []string{"interactive", "i"}},
		&config.BoolValue{Name: []string{"tty", "t"}},

		&config.StringValue{Name: []string{"cidfile"}},
		&config.StringValue{Name: []string{"entrypoint"}},
		&config.StringValue{Name: []string{"hostname", "h"}},
		&config.StringValue{Name: []string{"memory", "m"}},
		&config.StringValue{Name: []string{"user", "u"}},
		&config.StringValue{Name: []string{"workdir", "w"}},
		&config.Int64Value{Name: []string{"cpu-shares", "c"}},
		&config.StringValue{Name: []string{"cpuset"}},
		&config.StringValue{Name: []string{"net"}},
		&config.StringValue{Name: []string{"restart"}},
		&config.StringValue{Name: []string{"name"}},
		&config.BoolValue{Name: []string{"sig-proxy"}},

		&config.StringSliceValue{Name: []string{"attach", "a"}},
		&config.StringSliceValue{Name: []string{"volume", "v"}},
		&config.StringSliceValue{Name: []string{"link"}},
		&config.StringSliceValue{Name: []string{"device"}},
		&config.StringSliceValue{Name: []string{"env", "e"}},
		&config.StringSliceValue{Name: []string{"env-file"}},
		&config.StringSliceValue{Name: []string{"publish", "p"}},
		&config.StringSliceValue{Name: []string{"expose"}},
		&config.StringSliceValue{Name: []string{"dns"}},
		&config.StringSliceValue{Name: []string{"dns-search"}},
		&config.StringSliceValue{Name: []string{"volumes-from"}},
		&config.StringSliceValue{Name: []string{"lxc-conf"}},
		&config.StringSliceValue{Name: []string{"cap-add"}},
		&config.StringSliceValue{Name: []string{"cap-drop"}},
	}

	// read fugufile
	data, err := ioutil.ReadFile(fugufilePath)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	err = MergeConfig(data, args, label, &conf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// add --interactive and --tty when command or args are given
	// interactive := false
	// dockerCommand := config.Get(conf, "command")
	// if dockerCommand != nil {
	// 	if dockerCommand.Get().(string) != "" {
	// 		interactive = true
	// 	}
	// }
	// dockerArgs := config.Get(conf, "args")
	// if dockerArgs != nil {
	// 	if len(dockerArgs.Get().([]string)) > 0 {
	// 		interactive = true
	// 	}
	// }
	// if interactive {
	// 	config.Set(&conf, "interactive", true)
	// 	config.Set(&conf, "tty", true)
	// }

	// finally build args
	a := BuildRunArgs(&conf)

	a = append(a, "")
	copy(a[1:], a[0:])
	a[0] = "run"

	fmt.Println("docker", strings.Join(a, " "))

	cmd := exec.Command("docker", a...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	cmd.Run()
}

func CmdBuild(fugufilePath string, args []string, label string) {

	// use image as --tag option
	var fugufileConf = []config.Value{
		&config.StringValue{Name: []string{"image"}},
	}

	// docker options
	// see http://docs.docker.com/reference/commandline/cli/#build

	var dockerBuildConf = []config.Value{
		// add new option: path
		&config.StringValue{Name: []string{"path"}},

		&config.BoolValue{Name: []string{"force-rm"}},
		&config.BoolValue{Name: []string{"no-cache"}},
		&config.BoolValue{Name: []string{"quit", "q"}},
		&config.BoolValue{Name: []string{"rm"}},
		&config.StringValue{Name: []string{"tag", "t"}},
	}

	// read fugufile
	data, err := ioutil.ReadFile(fugufilePath)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// parse fugufile
	_, err = file.Load(data, label, &fugufileConf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// parse docker args
	err = docker.Load(args, &dockerBuildConf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// build docker build args
	dockerTag := ""
	dockerPath := ""
	a := make([]string, 0)
	for _, c := range dockerBuildConf {
		if c.Names()[0] == "tag" {
			dockerTag = c.Get().(string)
		} else if c.Names()[0] == "path" {
			dockerPath = c.Get().(string)
		} else {
			v := c.Arg()
			if len(v) > 0 {
				a = append(a, c.Arg()...)
			}
		}
	}

	// append dockerImage
	if dockerTag == "" {
		dockerImage := fugufileConf[0].Get().(string)
		a = append(a, fmt.Sprintf(`--tag="%v"`, dockerImage))
	}

	sort.Sort(sort.StringSlice(a))

	// get path | url | -
	if dockerPath != "" {
		a = append(a, dockerPath)
	} else {
		a = append(a, ".")
	}

	a = append(a, "")
	copy(a[1:], a[0:])
	a[0] = "build"

	fmt.Println("docker", strings.Join(a, " "))

	cmd := exec.Command("docker", a...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	cmd.Run()
}

func CmdDestroy(fugufilePath string, args []string, label string) {

	var fugufileConf = []config.Value{
		&config.StringValue{Name: []string{"name"}},
	}

	// read fugufile
	data, err := ioutil.ReadFile(fugufilePath)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// parse fugufile
	_, err = file.Load(data, label, &fugufileConf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// parse docker args
	err = docker.Load(args, &fugufileConf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	a := make([]string, 0)
	a = append(a, []string{"rm", "-f"}...)

	dockerName := fugufileConf[0].Get()
	if dockerName != nil {
		a = append(a, dockerName.(string))
	} else {
		fmt.Println("Could not find container name.")
		os.Exit(1)
	}

	fmt.Println("docker", strings.Join(a, " "))

	cmd := exec.Command("docker", a...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	cmd.Run()
}
<commit_msg>fix missing container name check for fugu destroy<commit_after>package cli

import (
	"fmt"
	"github.com/mattes/fugu/config"
	"github.com/mattes/fugu/docker"
	"github.com/mattes/fugu/file"
	"io/ioutil"
	"os"
	"os/exec"
	"sort"
	"strings"
)

func CmdRun(fugufilePath string, args []string, label string) {

	// docker options
	// see http://docs.docker.com/reference/commandline/cli/#run

	var conf = []config.Value{

		// add new options: image, command and args
		&config.StringValue{Name: []string{"image"}},
		&config.StringValue{Name: []string{"command"}},
		&config.StringSliceValue{Name: []string{"args"}},

		// official docker options ...
		&config.BoolValue{Name: []string{"rm"}},
		&config.BoolValue{Name: []string{"detach", "d"}},
		&config.BoolValue{Name: []string{"networking", "n"}},
		&config.BoolValue{Name: []string{"privileged"}},
		&config.BoolValue{Name: []string{"publish-all", "P"}},
		&config.BoolValue{Name: []string{"interactive", "i"}},
		&config.BoolValue{Name: []string{"tty", "t"}},

		&config.StringValue{Name: []string{"cidfile"}},
		&config.StringValue{Name: []string{"entrypoint"}},
		&config.StringValue{Name: []string{"hostname", "h"}},
		&config.StringValue{Name: []string{"memory", "m"}},
		&config.StringValue{Name: []string{"user", "u"}},
		&config.StringValue{Name: []string{"workdir", "w"}},
		&config.Int64Value{Name: []string{"cpu-shares", "c"}},
		&config.StringValue{Name: []string{"cpuset"}},
		&config.StringValue{Name: []string{"net"}},
		&config.StringValue{Name: []string{"restart"}},
		&config.StringValue{Name: []string{"name"}},
		&config.BoolValue{Name: []string{"sig-proxy"}},

		&config.StringSliceValue{Name: []string{"attach", "a"}},
		&config.StringSliceValue{Name: []string{"volume", "v"}},
		&config.StringSliceValue{Name: []string{"link"}},
		&config.StringSliceValue{Name: []string{"device"}},
		&config.StringSliceValue{Name: []string{"env", "e"}},
		&config.StringSliceValue{Name: []string{"env-file"}},
		&config.StringSliceValue{Name: []string{"publish", "p"}},
		&config.StringSliceValue{Name: []string{"expose"}},
		&config.StringSliceValue{Name: []string{"dns"}},
		&config.StringSliceValue{Name: []string{"dns-search"}},
		&config.StringSliceValue{Name: []string{"volumes-from"}},
		&config.StringSliceValue{Name: []string{"lxc-conf"}},
		&config.StringSliceValue{Name: []string{"cap-add"}},
		&config.StringSliceValue{Name: []string{"cap-drop"}},
	}

	// read fugufile
	data, err := ioutil.ReadFile(fugufilePath)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	err = MergeConfig(data, args, label, &conf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// add --interactive and --tty when command or args are given
	// interactive := false
	// dockerCommand := config.Get(conf, "command")
	// if dockerCommand != nil {
	// 	if dockerCommand.Get().(string) != "" {
	// 		interactive = true
	// 	}
	// }
	// dockerArgs := config.Get(conf, "args")
	// if dockerArgs != nil {
	// 	if len(dockerArgs.Get().([]string)) > 0 {
	// 		interactive = true
	// 	}
	// }
	// if interactive {
	// 	config.Set(&conf, "interactive", true)
	// 	config.Set(&conf, "tty", true)
	// }

	// finally build args
	a := BuildRunArgs(&conf)

	a = append(a, "")
	copy(a[1:], a[0:])
	a[0] = "run"

	fmt.Println("docker", strings.Join(a, " "))

	cmd := exec.Command("docker", a...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	cmd.Run()
}

func CmdBuild(fugufilePath string, args []string, label string) {

	// use image as --tag option
	var fugufileConf = []config.Value{
		&config.StringValue{Name: []string{"image"}},
	}

	// docker options
	// see http://docs.docker.com/reference/commandline/cli/#build

	var dockerBuildConf = []config.Value{
		// add new option: path
		&config.StringValue{Name: []string{"path"}},

		&config.BoolValue{Name: []string{"force-rm"}},
		&config.BoolValue{Name: []string{"no-cache"}},
		&config.BoolValue{Name: []string{"quit", "q"}},
		&config.BoolValue{Name: []string{"rm"}},
		&config.StringValue{Name: []string{"tag", "t"}},
	}

	// read fugufile
	data, err := ioutil.ReadFile(fugufilePath)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// parse fugufile
	_, err = file.Load(data, label, &fugufileConf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// parse docker args
	err = docker.Load(args, &dockerBuildConf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// build docker build args
	dockerTag := ""
	dockerPath := ""
	a := make([]string, 0)
	for _, c := range dockerBuildConf {
		if c.Names()[0] == "tag" {
			dockerTag = c.Get().(string)
		} else if c.Names()[0] == "path" {
			dockerPath = c.Get().(string)
		} else {
			v := c.Arg()
			if len(v) > 0 {
				a = append(a, c.Arg()...)
			}
		}
	}

	// append dockerImage
	if dockerTag == "" {
		dockerImage := fugufileConf[0].Get().(string)
		a = append(a, fmt.Sprintf(`--tag="%v"`, dockerImage))
	}

	sort.Sort(sort.StringSlice(a))

	// get path | url | -
	if dockerPath != "" {
		a = append(a, dockerPath)
	} else {
		a = append(a, ".")
	}

	a = append(a, "")
	copy(a[1:], a[0:])
	a[0] = "build"

	fmt.Println("docker", strings.Join(a, " "))

	cmd := exec.Command("docker", a...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	cmd.Run()
}

func CmdDestroy(fugufilePath string, args []string, label string) {

	var fugufileConf = []config.Value{
		&config.StringValue{Name: []string{"name"}},
	}

	// read fugufile
	data, err := ioutil.ReadFile(fugufilePath)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// parse fugufile
	_, err = file.Load(data, label, &fugufileConf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// parse docker args
	err = docker.Load(args, &fugufileConf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	a := make([]string, 0)
	a = append(a, []string{"rm", "-f"}...)

	dockerName := fugufileConf[0].Get()
	if dockerName != nil && dockerName != "" {
		a = append(a, dockerName.(string))
	} else {
		fmt.Println("Could not find container name.")
		os.Exit(1)
	}

	fmt.Println("docker", strings.Join(a, " "))

	cmd := exec.Command("docker", a...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	cmd.Run()
}
<|endoftext|>


<commit_before>/*

cli is a simple package to allow a game to render to the screen and be
interacted with. It's intended primarily as a tool to diagnose and play around
with a game while its moves and logic are being defined.

*/
package cli

import (
	"github.com/jkomoros/boardgame"
	"github.com/nsf/termbox-go"
)

//Controller is the primary type of the package.
type Controller struct {
	game *boardgame.Game
}

func NewController(game *boardgame.Game) *Controller {
	return &Controller{
		game: game,
	}
}

//Once the controller is set up, call MainLoop. It will block until it is time
//to exit.
func (c *Controller) MainLoop() {

	termbox.Init()

	defer termbox.Close()

	c.draw()

	for {
		evt := termbox.PollEvent()

		switch evt.Type {
		case termbox.EventKey:
			switch evt.Key {
			case termbox.KeyCtrlC:
				return
			}
		}

		c.draw()

	}

}

//draw draws the entire app to the screen
func (c *Controller) draw() {

	clearScreen()

	//TODO: do real drawing
	x := 0
	y := 0
	for _, ch := range "Hello World!" {
		termbox.SetCell(x, y, ch, termbox.ColorWhite, termbox.ColorBlack)
		x++
	}
}

func clearScreen() {
	width, height := termbox.Size()
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			termbox.SetCell(x, y, ' ', termbox.ColorDefault, termbox.ColorDefault)
		}
	}
}
<commit_msg>Actually render the temporary fake text to the screen.<commit_after>/*

cli is a simple package to allow a game to render to the screen and be
interacted with. It's intended primarily as a tool to diagnose and play around
with a game while its moves and logic are being defined.

*/
package cli

import (
	"github.com/jkomoros/boardgame"
	"github.com/nsf/termbox-go"
)

//Controller is the primary type of the package.
type Controller struct {
	game *boardgame.Game
}

func NewController(game *boardgame.Game) *Controller {
	return &Controller{
		game: game,
	}
}

//Once the controller is set up, call MainLoop. It will block until it is time
//to exit.
func (c *Controller) MainLoop() {

	termbox.Init()

	defer termbox.Close()

	c.draw()

	for {
		evt := termbox.PollEvent()

		switch evt.Type {
		case termbox.EventKey:
			switch evt.Key {
			case termbox.KeyCtrlC:
				return
			}
		}

		c.draw()

	}

}

//draw draws the entire app to the screen
func (c *Controller) draw() {

	clearScreen()

	//TODO: do real drawing
	x := 0
	y := 0
	for _, ch := range "Hello World!" {
		termbox.SetCell(x, y, ch, termbox.ColorWhite, termbox.ColorBlack)
		x++
	}

	termbox.Flush()
}

func clearScreen() {
	width, height := termbox.Size()
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			termbox.SetCell(x, y, ' ', termbox.ColorDefault, termbox.ColorDefault)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/contrib/static"
	"github.com/gin-gonic/gin"
	"github.com/kurrik/twittergo"
	"os"
    "beautifulsky/twitter"
)

func main() {
	r := gin.Default()

	pwd, err := os.Getwd()
	if err != nil {
		panic(err)
	}

	r.Use(static.Serve(pwd + "/frontend/public"))
	r.NoRoute(static.Serve(pwd + "/frontend/public"))

	r.GET("/ping", func(c *gin.Context) {
		c.String(200, "pong")
	})

	r.GET("/images", func(c *gin.Context) {

		k := make(chan *twittergo.SearchResults)
		r := make(chan *twittergo.APIResponse)
		t := make(chan map[string]string)
		done := make(chan bool)
		tweetsFromCacheDone := make(chan bool)
        tw := twitter.Twitter{}

		go tw.SearchTweets(k, r)
		go tw.TweetsFromCache(t, tweetsFromCacheDone)

        // parse tweets from twitter
		go func() {
            <- tweetsFromCacheDone
			for {
                results, more := <-k

				if more {
					tw.TweetsFromResults(c, results, t, done)
				} else {
					close(t)
					return
				}
			}

		}()

        // pipe results to response
		go func() {
            i := 0
            c.Data(200, "application/json", []byte("["))

            for {
				resp, more := <-t
                if more {
					fmt.Println("received response")
					if i != 0 {
						c.Data(200, "application/json", []byte(","))
					}

					jsonString, _ := json.Marshal(resp)
					c.Data(200, "application/json", []byte(jsonString))
					i++

				} else {
					fmt.Println("received all jobs")
					c.Data(200, "application/json", []byte("]"))
					done <- true
					return
				}
			}
		}()
		<-done
        tw.PrintRateLimit(r)
	})

	r.Run(":" + os.Getenv("PORT"))

}
<commit_msg>changing url<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/contrib/static"
	"github.com/gin-gonic/gin"
	"github.com/kurrik/twittergo"
	"os"
    "beautifulsky/twitter"
)

func main() {
	r := gin.Default()

	pwd, err := os.Getwd()
	if err != nil {
		panic(err)
	}

	r.Use(static.Serve(pwd + "/frontend/public"))
	r.NoRoute(static.Serve(pwd + "/frontend/public"))

	r.GET("/ping", func(c *gin.Context) {
		c.String(200, "pong")
	})

	r.GET("/tweets", func(c *gin.Context) {

		k := make(chan *twittergo.SearchResults)
		r := make(chan *twittergo.APIResponse)
		t := make(chan map[string]string)
		done := make(chan bool)
		tweetsFromCacheDone := make(chan bool)
        tw := twitter.Twitter{}

		go tw.SearchTweets(k, r)
		go tw.TweetsFromCache(t, tweetsFromCacheDone)

        // parse tweets from twitter
		go func() {
            <- tweetsFromCacheDone
			for {
                results, more := <-k

				if more {
					tw.TweetsFromResults(c, results, t, done)
				} else {
					close(t)
					return
				}
			}

		}()

        // pipe results to response
		go func() {
            i := 0
            c.Data(200, "application/json", []byte("["))

            for {
				resp, more := <-t
                if more {
					fmt.Println("received response")
					if i != 0 {
						c.Data(200, "application/json", []byte(","))
					}

					jsonString, _ := json.Marshal(resp)
					c.Data(200, "application/json", []byte(jsonString))
					i++

				} else {
					fmt.Println("received all jobs")
					c.Data(200, "application/json", []byte("]"))
					done <- true
					return
				}
			}
		}()
		<-done
        tw.PrintRateLimit(r)
	})

	r.Run(":" + os.Getenv("PORT"))

}
<|endoftext|>


<commit_before>//todo: add copyright notice

package cmd

import (
	"os"
	"path/filepath"

	"github.com/spf13/cobra"
	"github.com/wso2/wum-uc/constant"
	"github.com/wso2/wum-uc/util"
	"gopkg.in/yaml.v2"
)

// initCmd represents the validate command
var initCmd = &cobra.Command{
	Use:   "init",
	Short: "A brief description of your command",
	Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) == 0 {
			initCurrentDirectory()
		} else if len(args) == 1 {
			initDirectory(args[0])
		} else {
			util.PrintErrorAndExit("Invalid number of argumants. Run with --help for more details about the argumants")
		}

	},
}

func init() {
	RootCmd.AddCommand(initCmd)
	RootCmd.Flags().BoolVarP(&isDebugLogsEnabled, "debug", "d", false, "Enable debug logs")
	RootCmd.Flags().BoolVarP(&isTraceLogsEnabled, "trace", "t", false, "Enable trace logs")
}

func initCurrentDirectory() {
	currentDirectory := "./"
	initDirectory(currentDirectory)
}

func initDirectory(destination string) {
	err := util.CreateDirectory(destination)
	util.HandleError(err)

	updateDescriptorFile := filepath.Join(destination, constant.UPDATE_DESCRIPTOR_FILE)
	updateDescriptor := util.UpdateDescriptor{}
	data, err := yaml.Marshal(&updateDescriptor)
	if err != nil {
		util.HandleError(err)
	}

	file, err := os.OpenFile(
		updateDescriptorFile,
		os.O_WRONLY | os.O_TRUNC | os.O_CREATE,
		0600,
	)
	if err != nil {
		util.HandleError(err)
	}
	defer file.Close()

	// Write bytes to file
	_, err = file.Write(data)
	if err != nil {
		util.HandleError(err)
	}
}
<commit_msg>Sample update-descriptor file added to the init command<commit_after>//todo: add copyright notice

package cmd

import (
	"os"
	"path/filepath"

	"github.com/spf13/cobra"
	"github.com/wso2/wum-uc/constant"
	"github.com/wso2/wum-uc/util"
	"gopkg.in/yaml.v2"
	"fmt"
)

// initCmd represents the validate command
var initCmd = &cobra.Command{
	Use:   "init",
	Short: "A brief description of your command",
	Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) == 0 {
			initCurrentDirectory()
		} else if len(args) == 1 {
			initDirectory(args[0])
		} else {
			util.PrintErrorAndExit("Invalid number of argumants. Run with --help for more details about the argumants")
		}

	},
}

func init() {
	RootCmd.AddCommand(initCmd)
	RootCmd.Flags().BoolVarP(&isDebugLogsEnabled, "debug", "d", false, "Enable debug logs")
	RootCmd.Flags().BoolVarP(&isTraceLogsEnabled, "trace", "t", false, "Enable trace logs")
}

func initCurrentDirectory() {
	currentDirectory := "./"
	initDirectory(currentDirectory)
}

func initDirectory(destination string) {
	err := util.CreateDirectory(destination)
	util.HandleError(err)

	updateDescriptorFile := filepath.Join(destination, constant.UPDATE_DESCRIPTOR_FILE)
	updateDescriptor := util.UpdateDescriptor{}
	data, err := yaml.Marshal(&updateDescriptor)
	if err != nil {
		util.HandleError(err)
	}

	file, err := os.OpenFile(
		updateDescriptorFile,
		os.O_WRONLY | os.O_TRUNC | os.O_CREATE,
		0600,
	)
	if err != nil {
		util.HandleError(err)
	}
	defer file.Close()

	// Write bytes to file
	_, err = file.Write(data)
	if err != nil {
		util.HandleError(err)
	}
	sample := `  update_number: 0001
  platform_version: 4.4.0
  platform_name: wilkes
  applies_to: All the products based on carbon 4.4.1
  bug_fixes:
    CARBON-15395: Upgrade Hazelcast version to 3.5.2
    <MORE_JIRAS_HERE>
  description: |
    This update contain the relavent fixes for upgrading Hazelcast version
    to its latest 3.5.2 version. When applying this update it requires a
    full cluster estart since if the nodes has multiple client versions of
    Hazelcast it can cause issues during connectivity.
  file_changes:
    added_files: []
    removed_files: []
    modified_files:
    - repository/components/plugins/hazelcast_3.5.0.wso2v1.jar`
	fmt.Println("\nSample Usage:")
	fmt.Println(sample)
	fmt.Println()
}
<|endoftext|>


<commit_before>package cmd

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

	"github.com/koding/kite/kitekey"
)

type List struct{}

func NewList() *List {
	return &List{}
}

func (*List) Definition() string {
	return "List installed kites"
}

func (*List) Exec(args []string) error {
	kites, err := getInstalledKites("")
	if err != nil {
		return err
	}

	for _, k := range kites {
		fmt.Println(k)
	}

	return nil
}

// getIntalledKites returns installed kites in .kd/kites folder.
// an empty argument returns all kites.
func getInstalledKites(kiteName string) ([]string, error) {
	kiteHome, err := kitekey.KiteHome()
	if err != nil {
		return nil, err
	}
	kitesPath := filepath.Join(kiteHome, "kites")

	domains, err := ioutil.ReadDir(kitesPath)
	if err != nil {
		if os.IsNotExist(err) {
			return []string{}, nil
		}

		return nil, err
	}

	installedKites := []string{} // to be returned

	for _, domain := range domains {
		usernames, err := ioutil.ReadDir(filepath.Join(kitesPath, domain.Name()))
		if err != nil {
			fmt.Println(err)
			continue
		}

		for _, username := range usernames {
			repos, err := ioutil.ReadDir(filepath.Join(kitesPath, domain.Name(), username.Name()))
			if err != nil {
				fmt.Println(err)
				continue
			}

			for _, repo := range repos {
				versions, err := ioutil.ReadDir(filepath.Join(kitesPath, domain.Name(), username.Name(), repo.Name()))
				if err != nil {
					fmt.Println(err)
					continue
				}

				for _, version := range versions {
					_, err := os.Stat(filepath.Join(kitesPath, domain.Name(), username.Name(), repo.Name(), version.Name(), "bin", strings.TrimSuffix(repo.Name(), ".kite")))
					if err != nil {
						fmt.Println(err)
						continue
					}

					fullName := filepath.Join(domain.Name(), username.Name(), repo.Name(), version.Name())
					installedKites = append(installedKites, fullName)
				}
			}
		}
	}

	return installedKites, nil
}
<commit_msg>refactor paths<commit_after>package cmd

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

	"github.com/koding/kite/kitekey"
)

type List struct{}

func NewList() *List {
	return &List{}
}

func (*List) Definition() string {
	return "List installed kites"
}

func (*List) Exec(args []string) error {
	kites, err := getInstalledKites("")
	if err != nil {
		return err
	}

	for _, k := range kites {
		fmt.Println(k)
	}

	return nil
}

// getIntalledKites returns installed kites in .kd/kites folder.
// an empty argument returns all kites.
func getInstalledKites(kiteName string) ([]string, error) {
	kiteHome, err := kitekey.KiteHome()
	if err != nil {
		return nil, err
	}
	kitesPath := filepath.Join(kiteHome, "kites")

	domains, err := ioutil.ReadDir(kitesPath)
	if err != nil {
		if os.IsNotExist(err) {
			return []string{}, nil
		}

		return nil, err
	}

	installedKites := []string{} // to be returned

	for _, domain := range domains {
		domainPath := filepath.Join(kitesPath, domain.Name())
		usernames, err := ioutil.ReadDir(domainPath)
		if err != nil {
			fmt.Println(err)
			continue
		}

		for _, username := range usernames {
			usernamePath := filepath.Join(domainPath, username.Name())
			repos, err := ioutil.ReadDir(usernamePath)
			if err != nil {
				fmt.Println(err)
				continue
			}

			for _, repo := range repos {
				repoPath := filepath.Join(usernamePath, repo.Name())
				versions, err := ioutil.ReadDir(repoPath)
				if err != nil {
					fmt.Println(err)
					continue
				}

				for _, version := range versions {
					versionPath := filepath.Join(repoPath, version.Name())
					binaryPath := filepath.Join(versionPath, "bin", strings.TrimSuffix(repo.Name(), ".kite"))
					_, err := os.Stat(binaryPath)
					if err != nil {
						fmt.Println(err)
						continue
					}

					fullName := filepath.Join(domain.Name(), username.Name(), repo.Name(), version.Name())
					installedKites = append(installedKites, fullName)
				}
			}
		}
	}

	return installedKites, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/printer"
	"go/token"
	"log"
	"os"
)

// visitFn is a wrapper to make plain functions implement the ast.Visitor interface.
type visitFn func(ast.Node) ast.Visitor

// Visit is part of the ast.Visitor interface.
func (v visitFn) Visit(n ast.Node) ast.Visitor {
	return v(n)
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Must pass a single *.go file.")
		os.Exit(1)
	}
	fs := token.NewFileSet()
	parsed, err := parser.ParseFile(fs, os.Args[1], nil, 0)
	if err != nil {
		log.Fatalf("error during parsing: %v", err)
	}
	ast.Walk(visitFn(addImport), parsed)
	/*
		//ast.Inspect(parsed, inspect)
		//cfg := printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8}
		//cfg.Fprint(os.Stdout, fs, parsed)
		for fn := range fnsCalled {
			fmt.Println(fn.Name)
		}
	*/
	ast.Walk(visitFn(addLineFuncs), parsed)
	cfg := printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8}
	cfg.Fprint(os.Stdout, fs, parsed)
}

func newGodebugCall(fnName string) *ast.ExprStmt {
	return &ast.ExprStmt{
		X: &ast.CallExpr{
			Fun: &ast.SelectorExpr{
				X:   ast.NewIdent("godebug"),
				Sel: ast.NewIdent(fnName),
			},
		},
	}
}

func addLineFuncsToIf(ifstmt *ast.IfStmt) {
	addLineFuncsToBlock(ifstmt.Body)
	switch i := ifstmt.Else.(type) {
	case *ast.IfStmt:
		addLineFuncsToIf(i)
	case *ast.BlockStmt:
		addLineFuncsToBlock(i)
	}
}

func addLineFuncsToBlock(blk *ast.BlockStmt) {
	if blk == nil {
		return
	}
	newBody := make([]ast.Stmt, 0, 2*len(blk.List))
	for _, stmt := range blk.List {
		newBody = append(newBody, newGodebugCall("Line"))
		if ifstmt, ok := stmt.(*ast.IfStmt); ok {
			addLineFuncsToIf(ifstmt)
		}
		newBody = append(newBody, stmt)
	}
	blk.List = newBody
}

func addLineFuncs(node ast.Node) ast.Visitor {
	if _, ok := node.(*ast.File); ok {
		return visitFn(addLineFuncs)
	}
	fn, ok := node.(*ast.FuncDecl)
	if !ok {
		return nil
	}
	/*
		for i := range fn.Body.List {
			fmt.Printf("%T\n", fn.Body.List[i].(*ast.ExprStmt).X.(*ast.CallExpr).Fun.(*ast.SelectorExpr).X)
		}
	*/
	addLineFuncsToBlock(fn.Body)
	return nil
}

func addImport(node ast.Node) ast.Visitor {
	if _, ok := node.(*ast.File); ok {
		return visitFn(addImport)
	}
	genDecl, ok := node.(*ast.GenDecl)
	if !ok || genDecl.Tok != token.IMPORT {
		return nil
	}
	genDecl.Specs = append(genDecl.Specs, &ast.ImportSpec{
		Path: &ast.BasicLit{
			Kind:  token.STRING,
			Value: `"github.com/jeremyschlatter/godebug"`,
		},
	})
	return nil
}

/*
var fnsCalled map[*ast.Object]bool
func findMain(node ast.Node) ast.Visitor {
	fn, ok := node.(*ast.FuncDecl)
	if ok && fn.Name.Name == "main" {
		return visitFn(traceMain)
	}
	return visitFn(findMain)
}

func traceMain(node ast.Node) ast.Visitor {
	callExpr, ok := node.(*ast.CallExpr)
	if !ok {
		return visitFn(traceMain)
	}
	var fn *ast.Ident
	switch i := callExpr.Fun.(type) {
	case *ast.Ident:
		fn = i
	case *ast.SelectorExpr:
		fmt.Printf("%#v\n", i.X.(*ast.Ident).Obj)
		fmt.Printf("%#v\n", i.Sel)
		fn = i.Sel
	default:
		return visitFn(traceMain)
	}
	if fn.Obj == nil || fn.Obj.Name == "Hello" {
		fmt.Println("hello")
		return visitFn(traceMain)
	}
	if fnsCalled[fn.Obj] {
		return visitFn(traceMain)
	}
	fnsCalled[fn.Obj] = true
	ast.Walk(visitFn(traceMain), fn.Obj.Decl.(*ast.FuncDecl))
	return visitFn(traceMain)
}
*/

/*
func inspect(node ast.Node) bool {
	fn, ok := node.(*ast.FuncDecl)
	if !ok {
		return true
	}
	switch fn.Name.Name {
	case "foo":
	default:
		return true
	}
	ctx := ast.Field{
		Names: []*ast.Ident{ast.NewIdent("ctx")},
		Type:  ast.NewIdent("Context"),
	}
	fn.Type.Params.List = append([]*ast.Field{&ctx}, fn.Type.Params.List...)
	return true
}
*/
<commit_msg>cmd: add godebug.Line() calls inside of for and range statements<commit_after>package main

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/printer"
	"go/token"
	"log"
	"os"
)

// visitFn is a wrapper to make plain functions implement the ast.Visitor interface.
type visitFn func(ast.Node) ast.Visitor

// Visit is part of the ast.Visitor interface.
func (v visitFn) Visit(n ast.Node) ast.Visitor {
	return v(n)
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Must pass a single *.go file.")
		os.Exit(1)
	}
	fs := token.NewFileSet()
	parsed, err := parser.ParseFile(fs, os.Args[1], nil, 0)
	if err != nil {
		log.Fatalf("error during parsing: %v", err)
	}
	ast.Walk(visitFn(addImport), parsed)
	/*
		//ast.Inspect(parsed, inspect)
		//cfg := printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8}
		//cfg.Fprint(os.Stdout, fs, parsed)
		for fn := range fnsCalled {
			fmt.Println(fn.Name)
		}
	*/
	ast.Walk(visitFn(addLineFuncs), parsed)
	cfg := printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8}
	cfg.Fprint(os.Stdout, fs, parsed)
}

func newGodebugCall(fnName string) *ast.ExprStmt {
	return &ast.ExprStmt{
		X: &ast.CallExpr{
			Fun: &ast.SelectorExpr{
				X:   ast.NewIdent("godebug"),
				Sel: ast.NewIdent(fnName),
			},
		},
	}
}

func addLineFuncsToIf(ifstmt *ast.IfStmt) {
	addLineFuncsToBlock(ifstmt.Body)
	switch i := ifstmt.Else.(type) {
	case *ast.IfStmt:
		addLineFuncsToIf(i)
	case *ast.BlockStmt:
		addLineFuncsToBlock(i)
	}
}

func addLineFuncsToFor(forstmt *ast.ForStmt) {
	addLineFuncsToBlock(forstmt.Body)
}

func addLineFuncsToRange(rangestmt *ast.RangeStmt) {
	addLineFuncsToBlock(rangestmt.Body)
}

func addLineFuncsToBlock(blk *ast.BlockStmt) {
	if blk == nil {
		return
	}
	newBody := make([]ast.Stmt, 0, 2*len(blk.List))
	for _, stmt := range blk.List {
		newBody = append(newBody, newGodebugCall("Line"))
		if ifstmt, ok := stmt.(*ast.IfStmt); ok {
			addLineFuncsToIf(ifstmt)
		}
		if forstmt, ok := stmt.(*ast.ForStmt); ok {
			addLineFuncsToFor(forstmt)
		}
		if forstmt, ok := stmt.(*ast.RangeStmt); ok {
			addLineFuncsToRange(forstmt)
		}
		newBody = append(newBody, stmt)
	}
	blk.List = newBody
}

func addLineFuncs(node ast.Node) ast.Visitor {
	if _, ok := node.(*ast.File); ok {
		return visitFn(addLineFuncs)
	}
	fn, ok := node.(*ast.FuncDecl)
	if !ok {
		return nil
	}
	/*
		for i := range fn.Body.List {
			fmt.Printf("%T\n", fn.Body.List[i].(*ast.ExprStmt).X.(*ast.CallExpr).Fun.(*ast.SelectorExpr).X)
		}
	*/
	addLineFuncsToBlock(fn.Body)
	return nil
}

func addImport(node ast.Node) ast.Visitor {
	if _, ok := node.(*ast.File); ok {
		return visitFn(addImport)
	}
	genDecl, ok := node.(*ast.GenDecl)
	if !ok || genDecl.Tok != token.IMPORT {
		return nil
	}
	genDecl.Specs = append(genDecl.Specs, &ast.ImportSpec{
		Path: &ast.BasicLit{
			Kind:  token.STRING,
			Value: `"github.com/jeremyschlatter/godebug"`,
		},
	})
	return nil
}

/*
var fnsCalled map[*ast.Object]bool
func findMain(node ast.Node) ast.Visitor {
	fn, ok := node.(*ast.FuncDecl)
	if ok && fn.Name.Name == "main" {
		return visitFn(traceMain)
	}
	return visitFn(findMain)
}

func traceMain(node ast.Node) ast.Visitor {
	callExpr, ok := node.(*ast.CallExpr)
	if !ok {
		return visitFn(traceMain)
	}
	var fn *ast.Ident
	switch i := callExpr.Fun.(type) {
	case *ast.Ident:
		fn = i
	case *ast.SelectorExpr:
		fmt.Printf("%#v\n", i.X.(*ast.Ident).Obj)
		fmt.Printf("%#v\n", i.Sel)
		fn = i.Sel
	default:
		return visitFn(traceMain)
	}
	if fn.Obj == nil || fn.Obj.Name == "Hello" {
		fmt.Println("hello")
		return visitFn(traceMain)
	}
	if fnsCalled[fn.Obj] {
		return visitFn(traceMain)
	}
	fnsCalled[fn.Obj] = true
	ast.Walk(visitFn(traceMain), fn.Obj.Decl.(*ast.FuncDecl))
	return visitFn(traceMain)
}
*/

/*
func inspect(node ast.Node) bool {
	fn, ok := node.(*ast.FuncDecl)
	if !ok {
		return true
	}
	switch fn.Name.Name {
	case "foo":
	default:
		return true
	}
	ctx := ast.Field{
		Names: []*ast.Ident{ast.NewIdent("ctx")},
		Type:  ast.NewIdent("Context"),
	}
	fn.Type.Params.List = append([]*ast.Field{&ctx}, fn.Type.Params.List...)
	return true
}
*/
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Frank Wessels <fwessels@xs4all.nl>
 *
 * 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 cmd

import (
	"github.com/s3git/s3git-go"
	"github.com/spf13/cobra"
)

// pushCmd represents the push command
var pushCmd = &cobra.Command{
	Use:   "push",
	Short: "Update remote repositories",
	Long: "Update remote repositories",
	Run: func(cmd *cobra.Command, args []string) {

		repo, err := s3git.OpenRepository(".")
		if err != nil {
			er(err)
		}

		err = repo.Push()
		if err != nil {
			er(err)
		}
	},
}

func init() {
	RootCmd.AddCommand(pushCmd)
}
<commit_msg>Progress and hydrated support for pushing<commit_after>/*
 * Copyright 2016 Frank Wessels <fwessels@xs4all.nl>
 *
 * 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 cmd

import (
	"fmt"
	"github.com/s3git/s3git-go"
	"github.com/spf13/cobra"
	"github.com/cheggaaa/pb"
)

var hydrated bool

// pushCmd represents the push command
var pushCmd = &cobra.Command{
	Use:   "push",
	Short: "Update remote repositories",
	Long: "Update remote repositories",
	Run: func(cmd *cobra.Command, args []string) {

		repo, err := s3git.OpenRepository(".")
		if err != nil {
			er(err)
		}

		var barPushing *pb.ProgressBar

		progressPush := func(total int64) {
			if barPushing == nil {
				barPushing = pb.New64(total).Start()
				barPushing.Prefix("Pushing ")
			}
			if barPushing.Increment() == int(total) {
				barPushing.Finish()
			}
		}

		err = repo.Push(hydrated, progressPush)
		if err != nil {
			er(err)
		}

		if barPushing == nil {
			fmt.Println("Already up-to-date.")
		}
	},
}

func init() {
	RootCmd.AddCommand(pushCmd)

	// Add local message flags
	pushCmd.Flags().BoolVar(&hydrated, "hydrated", false, "Store in hydrated (concatenated) format at remote")
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"log"

	"github.com/openpixel/rise/runner"
	"github.com/spf13/cobra"
)

const version = "v0.0.6"

var inputs string
var outputs string
var configFiles []string

func init() {
	RootCmd.PersistentFlags().StringVarP(&inputs, "input", "i", "", "The file to perform interpolation on")
	RootCmd.PersistentFlags().StringVarP(&outputs, "output", "o", "", "The file to output")
	RootCmd.PersistentFlags().StringSliceVarP(&configFiles, "config", "c", []string{}, "The files that define the configuration to use for interpolation")
	RootCmd.AddCommand(versionCmd)
}

// RootCmd is the root command for the entire cli
var RootCmd = &cobra.Command{
	Use:   "rise",
	Short: "Rise is a powerful text interpolation tool.",
	Long:  `A powerful text interpolation tool.`,
	Run: func(cmd *cobra.Command, args []string) {
		if inputs == "" {
			log.Fatal("Must have an input")
		}
		err := runner.Run(&inputs, &outputs, &configFiles)
		if err != nil {
			log.Fatal(err)
		}
	},
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of rise",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println(version)
	},
}
<commit_msg>Bump version to 0.1.0<commit_after>package cmd

import (
	"fmt"
	"log"

	"github.com/openpixel/rise/runner"
	"github.com/spf13/cobra"
)

const version = "v0.1.0"

var inputs string
var outputs string
var configFiles []string

func init() {
	RootCmd.PersistentFlags().StringVarP(&inputs, "input", "i", "", "The file to perform interpolation on")
	RootCmd.PersistentFlags().StringVarP(&outputs, "output", "o", "", "The file to output")
	RootCmd.PersistentFlags().StringSliceVarP(&configFiles, "config", "c", []string{}, "The files that define the configuration to use for interpolation")
	RootCmd.AddCommand(versionCmd)
}

// RootCmd is the root command for the entire cli
var RootCmd = &cobra.Command{
	Use:   "rise",
	Short: "Rise is a powerful text interpolation tool.",
	Long:  `A powerful text interpolation tool.`,
	Run: func(cmd *cobra.Command, args []string) {
		if inputs == "" {
			log.Fatal("Must have an input")
		}
		err := runner.Run(&inputs, &outputs, &configFiles)
		if err != nil {
			log.Fatal(err)
		}
	},
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of rise",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println(version)
	},
}
<|endoftext|>


<commit_before>package cmd

import (
	"path/filepath"
	"strings"

	"github.com/spf13/cobra"
	"github.com/wallix/awless/config"
	"github.com/wallix/awless/rdf"
	"github.com/wallix/awless/stats"
)

var (
	statsDB *stats.DB

	verboseFlag bool
)

var RootCmd = &cobra.Command{
	Use:   "awless",
	Short: "Manage your cloud",
	Long:  "Awless is a powerful command line tool to inspect, sync and manage your infrastructure",
	PersistentPostRun: func(cmd *cobra.Command, args []string) {
		if statsDB != nil {
			defer statsDB.Close()
			statsDB.AddHistoryCommand(append(strings.Split(cmd.CommandPath(), " "), args...))
		}
	},
}

func init() {
	RootCmd.PersistentFlags().BoolVarP(&verboseFlag, "verbose", "v", false, "Turn on verbose mode for all commands")

	var err error

	statsDB, err = stats.OpenDB(config.DatabasePath)
	if err != nil {
		if statsDB != nil {
			statsDB.AddLog("can not save history: " + err.Error())
		}
	} else if statsDB.CheckStatsToSend(config.StatsExpirationDuration) {
		publicKey, err := config.LoadPublicKey()
		if err != nil {
			statsDB.AddLog(err.Error())
		} else {
			if !config.AwlessFirstSync {
				localInfra, err := rdf.NewGraphFromFile(filepath.Join(config.GitDir, config.InfraFilename))
				if err != nil {
					statsDB.AddLog(err.Error())
				}
				localAccess, err := rdf.NewGraphFromFile(filepath.Join(config.GitDir, config.AccessFilename))
				if err != nil {
					statsDB.AddLog(err.Error())
				}

				if err := statsDB.SendStats(config.StatsServerUrl, *publicKey, localInfra, localAccess); err != nil {
					statsDB.AddLog(err.Error())
				}
			}
		}
	}
}

func ExecuteRoot() error {
	err := RootCmd.Execute()
	if err != nil && statsDB != nil {
		statsDB.AddLog(err.Error())
	}

	return err
}
<commit_msg>Send stats in another goroutine. This fixes #16.<commit_after>package cmd

import (
	"path/filepath"
	"strings"

	"github.com/spf13/cobra"
	"github.com/wallix/awless/config"
	"github.com/wallix/awless/rdf"
	"github.com/wallix/awless/stats"
)

var (
	statsDB *stats.DB

	verboseFlag bool
)

var RootCmd = &cobra.Command{
	Use:   "awless",
	Short: "Manage your cloud",
	Long:  "Awless is a powerful command line tool to inspect, sync and manage your infrastructure",
	PersistentPostRun: func(cmd *cobra.Command, args []string) {
		if statsDB != nil {
			defer statsDB.Close()
			statsDB.AddHistoryCommand(append(strings.Split(cmd.CommandPath(), " "), args...))
		}
	},
}

func init() {
	RootCmd.PersistentFlags().BoolVarP(&verboseFlag, "verbose", "v", false, "Turn on verbose mode for all commands")

	var err error

	statsDB, err = stats.OpenDB(config.DatabasePath)
	if err != nil {
		if statsDB != nil {
			statsDB.AddLog("can not save history: " + err.Error())
		}
	} else if statsDB.CheckStatsToSend(config.StatsExpirationDuration) {
		publicKey, err := config.LoadPublicKey()
		if err != nil {
			statsDB.AddLog(err.Error())
		} else {
			if !config.AwlessFirstSync {
				go func() {
					localInfra, err := rdf.NewGraphFromFile(filepath.Join(config.GitDir, config.InfraFilename))
					if err != nil {
						statsDB.AddLog(err.Error())
					}
					localAccess, err := rdf.NewGraphFromFile(filepath.Join(config.GitDir, config.AccessFilename))
					if err != nil {
						statsDB.AddLog(err.Error())
					}

					if err := statsDB.SendStats(config.StatsServerUrl, *publicKey, localInfra, localAccess); err != nil {
						statsDB.AddLog(err.Error())
					}
				}()
			}
		}
	}
}

func ExecuteRoot() error {
	err := RootCmd.Execute()
	if err != nil && statsDB != nil {
		statsDB.AddLog(err.Error())
	}

	return err
}
<|endoftext|>


<commit_before>package cmd

import (
	"github.com/rebuy-de/aws-nuke/pkg/awsutil"
	"github.com/spf13/cobra"
)

func NewRootCommand() *cobra.Command {
	var (
		params NukeParameters
		creds  awsutil.Credentials
	)

	command := &cobra.Command{
		Use:   "aws-nuke",
		Short: "aws-nuke removes every resource from AWS",
		Long:  `A tool which removes every resource from an AWS account.  Use it with caution, since it cannot distinguish between production and non-production.`,
	}

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

		err = params.Validate()
		if err != nil {
			return err
		}

		err = creds.Validate()
		if err != nil {
			return err
		}

		command.SilenceUsage = true

		account, err := awsutil.NewAccount(creds)
		if err != nil {
			return err
		}

		n := NewNuke(params, *account)

		n.Config, err = LoadConfig(n.Parameters.ConfigPath)
		if err != nil {
			return err
		}

		return n.Run()
	}

	command.PersistentFlags().StringVarP(
		&params.ConfigPath, "config", "c", "",
		"path to config (required)")
	command.PersistentFlags().StringVar(
		&creds.Profile, "profile", "",
		"profile name to nuke")
	command.PersistentFlags().StringVar(
		&creds.AccessKeyID, "access-key-id", "",
		"AWS access-key-id")
	command.PersistentFlags().StringVar(
		&creds.SecretAccessKey, "secret-access-key", "",
		"AWS secret-access-key")
	command.PersistentFlags().StringSliceVarP(
		&params.Targets, "target", "t", []string{},
		"limit nuking to certain resource types (eg IAMServerCertificate)")
	command.PersistentFlags().BoolVar(
		&params.NoDryRun, "no-dry-run", false,
		"actually delete found resources")
	command.PersistentFlags().BoolVar(
		&params.Force, "force", false,
		"don't ask for confirmation")

	command.AddCommand(NewVersionCommand())

	return command
}
<commit_msg>add command for listing resource types<commit_after>package cmd

import (
	"fmt"
	"sort"

	"github.com/rebuy-de/aws-nuke/pkg/awsutil"
	"github.com/rebuy-de/aws-nuke/resources"
	"github.com/spf13/cobra"
)

func NewRootCommand() *cobra.Command {
	var (
		params NukeParameters
		creds  awsutil.Credentials
	)

	command := &cobra.Command{
		Use:   "aws-nuke",
		Short: "aws-nuke removes every resource from AWS",
		Long:  `A tool which removes every resource from an AWS account.  Use it with caution, since it cannot distinguish between production and non-production.`,
	}

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

		err = params.Validate()
		if err != nil {
			return err
		}

		err = creds.Validate()
		if err != nil {
			return err
		}

		command.SilenceUsage = true

		account, err := awsutil.NewAccount(creds)
		if err != nil {
			return err
		}

		n := NewNuke(params, *account)

		n.Config, err = LoadConfig(n.Parameters.ConfigPath)
		if err != nil {
			return err
		}

		return n.Run()
	}

	command.PersistentFlags().StringVarP(
		&params.ConfigPath, "config", "c", "",
		"path to config (required)")
	command.PersistentFlags().StringVar(
		&creds.Profile, "profile", "",
		"profile name to nuke")
	command.PersistentFlags().StringVar(
		&creds.AccessKeyID, "access-key-id", "",
		"AWS access-key-id")
	command.PersistentFlags().StringVar(
		&creds.SecretAccessKey, "secret-access-key", "",
		"AWS secret-access-key")
	command.PersistentFlags().StringSliceVarP(
		&params.Targets, "target", "t", []string{},
		"limit nuking to certain resource types (eg IAMServerCertificate)")
	command.PersistentFlags().BoolVar(
		&params.NoDryRun, "no-dry-run", false,
		"actually delete found resources")
	command.PersistentFlags().BoolVar(
		&params.Force, "force", false,
		"don't ask for confirmation")

	command.AddCommand(NewVersionCommand())
	command.AddCommand(NewResourceTypesCommand())

	return command
}

func NewResourceTypesCommand() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "resource-types",
		Short: "lists all available resource types",
		Run: func(cmd *cobra.Command, args []string) {
			types := []string{}
			for resourceType, _ := range resources.GetListers() {
				types = append(types, resourceType)
			}

			sort.Strings(types)

			for _, resourceType := range types {
				fmt.Println(resourceType)
			}
		},
	}

	return cmd
}
<|endoftext|>


<commit_before>package cmd

import (
	"crypto/rand"
	"crypto/tls"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/http/httputil"
	"os"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/mdp/gloss/certs"
	"github.com/spf13/cobra"
)

// StdLog is our default logger
var StdLog = log.New(os.Stdout, "", 0)

var mappings string
var certPath string
var keyPath string
var sport int
var port int

// Config for the reverse proxy
type Config struct {
	mappings map[string]int
}

func init() {
	RootCmd.Flags().StringVarP(&mappings, "map", "m", "", "Source directory to read from")
	RootCmd.Flags().StringVar(&certPath, "cert", os.Getenv("HOME")+"/.gloss/cert.pem", "Path to cert")
	RootCmd.Flags().StringVar(&keyPath, "key", os.Getenv("HOME")+"/.gloss/key.pem", "Path to cert key")
	RootCmd.Flags().IntVar(&sport, "sport", 4443, "SSL listening port")
	RootCmd.Flags().IntVar(&port, "port", 0, "HTTP listening port")
}

func (c *Config) setupMapping(mappingStr *string) {
	c.mappings = make(map[string]int)
	for _, mapping := range strings.Split(*mappingStr, ",") {
		mapping = strings.TrimSpace(mapping)
		s := strings.Split(mapping, ":")
		proxyPort, err := strconv.Atoi(s[1])
		if err != nil {
			log.Fatalf("Mapping error: %s", err)
		}
		if s[0] == "*" {
			StdLog.Printf("Mapping * to %d\n", proxyPort)
		} else {
			StdLog.Printf("Mapping %s.* to %d\n", s[0], proxyPort)
		}
		c.mappings[s[0]] = proxyPort
	}
}

type upstreamTransport struct {
	config *Config
}

func (trans *upstreamTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	res, err := http.DefaultTransport.RoundTrip(req)
	if err != nil {
		errorMsg := fmt.Sprintf("Gloss proxy error: %v", err)
		return &http.Response{
			StatusCode: http.StatusBadGateway,
			Body:       ioutil.NopCloser(strings.NewReader(errorMsg)),
		}, nil
	}
	user, _, ok := req.BasicAuth()
	if !ok {
		user = "-"
	}
	timeFmtd := time.Now().Format("02/Jan/2006 03:04:05")
	StdLog.Printf("%s %s %s [%s] \"%s %s %s\" %d %d\n", req.RemoteAddr, req.Host, user, timeFmtd, req.Method, req.RequestURI, req.Proto, res.StatusCode, res.ContentLength)
	return res, err
}

func multipleHostReverseProxy(config *Config) *httputil.ReverseProxy {
	// Fairly simple right now:
	// use the subdomain to route to a specific port
	director := func(req *http.Request) {
		domains := strings.Split(req.Host, ".")
		topSubdomain := domains[0]
		port := config.mappings["*"]
		if config.mappings[topSubdomain] > 0 {
			port = config.mappings[topSubdomain]
		}
		req.URL.Scheme = "http"
		req.URL.Host = "localhost:" + strconv.Itoa(port)
	}
	return &httputil.ReverseProxy{Director: director, Transport: &upstreamTransport{config: config}}
}

type httpHandler struct {
	proxy httputil.ReverseProxy
}

func (c *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.TLS != nil {
		r.Header.Add("X-Forwarded-Proto", "https")
	}
	r.Header.Add("X-Forwarded-For", r.RemoteAddr)
	c.proxy.ServeHTTP(w, r)
}

func printPortRedirHelp(port int) {
	StdLog.Printf("*Helpful hint on how to redirect port %d -> 443*\n", port)
	if runtime.GOOS == "windows" {
		StdLog.Println("Windows instuctions")
		StdLog.Printf("\tnetsh interface portproxy add v4tov4 connectport=%d listenport=443 connectaddress=127.0.0.1 listenaddress=127.0.0.1\n", port)
	} else if runtime.GOOS == "darwin" {
		StdLog.Println("OSX instuctions")
		StdLog.Printf("\techo \"rdr pass on lo0 inet proto tcp from any to any port 443 -> 127.0.0.1 port %d\" | sudo pfctl -ef -\n", port)
	} else if runtime.GOOS == "linux" {
		StdLog.Println("Linux instuctions")
		StdLog.Printf("\tsudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port %d", port)
	}
}

// RootCmd is what runs by default
var RootCmd = &cobra.Command{
	Use:   "gloss",
	Short: "gloss is a very simple https reverse proxy",
	Long:  `more information about gloss can be found at https://github.com/mdp/gloss`,
	RunE: func(cmd *cobra.Command, args []string) error {
		cert, err := certs.GetCerts(&certPath, &keyPath)
		if err != nil {
			return errors.New("Unable to find SSL cert, make sure you run setup first\ne.g.\tgloss setup --host='*.local.dev,local.dev'")
		}
		config := Config{}
		if len(mappings) < 1 {
			return errors.New("What ports do you want to map to?\ne.g.\t`gloss --map '*:3000,someapp:4000'`\n")
		}
		config.setupMapping(&mappings)
		tlsConfig := tls.Config{Certificates: []tls.Certificate{cert}}
		tlsConfig.Rand = rand.Reader
		tlsService := ":" + strconv.Itoa(sport)
		httpService := ":" + strconv.Itoa(port)
		tlsListener, err := tls.Listen("tcp", tlsService, &tlsConfig)
		httpListener, err := net.Listen("tcp", httpService)
		printPortRedirHelp(sport)
		proxy := multipleHostReverseProxy(&config)
		s := &http.Server{
			Handler:        &httpHandler{proxy: *proxy},
			ReadTimeout:    10 * time.Second,
			WriteTimeout:   10 * time.Second,
			MaxHeaderBytes: 1 << 20,
		}
		go s.Serve(tlsListener)
		s.Serve(httpListener)
		return nil
	},
}
<commit_msg>Final fixes<commit_after>package cmd

import (
	"crypto/rand"
	"crypto/tls"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/http/httputil"
	"os"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/mdp/gloss/certs"
	"github.com/spf13/cobra"
)

// StdLog is our default logger
var StdLog = log.New(os.Stdout, "", 0)

var mappings string
var certPath string
var keyPath string
var sport int
var port int

// Config for the reverse proxy
type Config struct {
	mappings map[string]int
}

func init() {
	RootCmd.Flags().StringVarP(&mappings, "map", "m", "", "Source directory to read from")
	RootCmd.Flags().StringVar(&certPath, "cert", os.Getenv("HOME")+"/.gloss/cert.pem", "Path to cert")
	RootCmd.Flags().StringVar(&keyPath, "key", os.Getenv("HOME")+"/.gloss/key.pem", "Path to cert key")
	RootCmd.Flags().IntVar(&sport, "sport", 4443, "SSL listening port")
	RootCmd.Flags().IntVar(&port, "port", 0, "HTTP listening port")
}

func (c *Config) setupMapping(mappingStr *string) {
	c.mappings = make(map[string]int)
	for _, mapping := range strings.Split(*mappingStr, ",") {
		mapping = strings.TrimSpace(mapping)
		s := strings.Split(mapping, ":")
		proxyPort, err := strconv.Atoi(s[1])
		if err != nil {
			log.Fatalf("Mapping error: %s", err)
		}
		if s[0] == "*" {
			StdLog.Printf("Mapping * to %d\n", proxyPort)
		} else {
			StdLog.Printf("Mapping %s.* to %d\n", s[0], proxyPort)
		}
		c.mappings[s[0]] = proxyPort
	}
}

type upstreamTransport struct {
	config *Config
}

func (trans *upstreamTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	res, err := http.DefaultTransport.RoundTrip(req)
	if err != nil {
		errorMsg := fmt.Sprintf("Gloss proxy error: %v", err)
		return &http.Response{
			StatusCode: http.StatusBadGateway,
			Body:       ioutil.NopCloser(strings.NewReader(errorMsg)),
		}, nil
	}
	user, _, ok := req.BasicAuth()
	if !ok {
		user = "-"
	}
	timeFmtd := time.Now().Format("02/Jan/2006 03:04:05")
	StdLog.Printf("%s %s %s [%s] \"%s %s %s\" %d %d\n", req.RemoteAddr, req.Host, user, timeFmtd, req.Method, req.RequestURI, req.Proto, res.StatusCode, res.ContentLength)
	return res, err
}

func multipleHostReverseProxy(config *Config) *httputil.ReverseProxy {
	// Fairly simple right now:
	// use the subdomain to route to a specific port
	director := func(req *http.Request) {
		domains := strings.Split(req.Host, ".")
		topSubdomain := domains[0]
		port := config.mappings["*"]
		if config.mappings[topSubdomain] > 0 {
			port = config.mappings[topSubdomain]
		}
		req.URL.Scheme = "http"
		req.URL.Host = "localhost:" + strconv.Itoa(port)
	}
	return &httputil.ReverseProxy{Director: director, Transport: &upstreamTransport{config: config}}
}

type httpHandler struct {
	proxy httputil.ReverseProxy
}

func (c *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.TLS != nil {
		r.Header.Add("X-Forwarded-Proto", "https")
	}
	r.Header.Add("X-Forwarded-For", r.RemoteAddr)
	c.proxy.ServeHTTP(w, r)
}

func printPortRedirHelp(port int) {
	StdLog.Printf("*Helpful hint on how to redirect port %d -> 443*\n", port)
	if runtime.GOOS == "windows" {
		StdLog.Println("Windows instuctions")
		StdLog.Printf("\tnetsh interface portproxy add v4tov4 connectport=%d listenport=443 connectaddress=127.0.0.1 listenaddress=127.0.0.1\n", port)
	} else if runtime.GOOS == "darwin" {
		StdLog.Println("OSX instuctions")
		StdLog.Printf("\techo \"rdr pass on lo0 inet proto tcp from any to any port 443 -> 127.0.0.1 port %d\" | sudo pfctl -ef -\n", port)
	} else if runtime.GOOS == "linux" {
		StdLog.Println("Linux instuctions")
		StdLog.Printf("\tsudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port %d", port)
	}
}

// RootCmd is what runs by default
var RootCmd = &cobra.Command{
	Use:   "gloss",
	Short: "gloss is a very simple https reverse proxy",
	Long:  `more information about gloss can be found at https://github.com/mdp/gloss`,
	RunE: func(cmd *cobra.Command, args []string) error {
		cert, err := certs.GetCerts(&certPath, &keyPath)
		if err != nil {
			return errors.New("Unable to find SSL cert, make sure you run setup first\ne.g.\tgloss setup --host='*.local.dev,local.dev'")
		}
		config := Config{}
		if len(mappings) < 1 {
			return errors.New("What ports do you want to map to?\ne.g.\t`gloss --map '*:3000,someapp:4000'`\n")
		}
		config.setupMapping(&mappings)
		tlsConfig := tls.Config{Certificates: []tls.Certificate{cert}}
		tlsConfig.Rand = rand.Reader
		printPortRedirHelp(sport)
		proxy := multipleHostReverseProxy(&config)
		s := &http.Server{
			Handler:        &httpHandler{proxy: *proxy},
			ReadTimeout:    10 * time.Second,
			WriteTimeout:   10 * time.Second,
			MaxHeaderBytes: 1 << 20,
		}
		if port > 0 {
			httpService := ":" + strconv.Itoa(port)
			httpListener, err := net.Listen("tcp", httpService)
			if err != nil {
				return err
			}
			go s.Serve(httpListener)
		}
		tlsService := ":" + strconv.Itoa(sport)
		tlsListener, err := tls.Listen("tcp", tlsService, &tlsConfig)
		if err != nil {
			return err
		}
		s.Serve(tlsListener)
		return nil
	},
}
<|endoftext|>


<commit_before>// Copyright © 2015 NAME HERE <EMAIL ADDRESS>
//
// 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 cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var cfgFile string

// This represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "cluster",
	Short: "cluster controls the Droi platform",
	Long: `cluster controls the Droi platform.

Find more information at https://github.com/gosharplite/cluster.`,
	// Uncomment the following line if your bare application
	// has an action associated with it:
	//	Run: func(cmd *cobra.Command, args []string) { },
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	// Here you will define your flags and configuration settings.
	// Cobra supports Persistent Flags, which, if defined here,
	// will be global for your application.

	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cluster.yaml)")
	// Cobra also supports local flags, which will only run
	// when this action is called directly.
	RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" { // enable ability to specify config file via flag
		viper.SetConfigFile(cfgFile)
	}

	viper.SetConfigName(".cluster") // name of config file (without extension)
	viper.AddConfigPath("$HOME")    // adding home directory as first search path
	viper.AutomaticEnv()            // read in environment variables that match

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}
}
<commit_msg>Remove root local flag.<commit_after>// Copyright © 2015 NAME HERE <EMAIL ADDRESS>
//
// 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 cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var cfgFile string

// This represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "cluster",
	Short: "cluster controls the Droi platform",
	Long: `cluster controls the Droi platform.

Find more information at https://github.com/gosharplite/cluster.`,
	// Uncomment the following line if your bare application
	// has an action associated with it:
	//	Run: func(cmd *cobra.Command, args []string) {},
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	// Here you will define your flags and configuration settings.
	// Cobra supports Persistent Flags, which, if defined here,
	// will be global for your application.
	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cluster.yaml)")

	// Cobra also supports local flags, which will only run
	// when this action is called directly.
	//	RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" { // enable ability to specify config file via flag
		viper.SetConfigFile(cfgFile)
	}

	viper.SetConfigName(".cluster") // name of config file (without extension)
	viper.AddConfigPath("$HOME")    // adding home directory as first search path
	viper.AutomaticEnv()            // read in environment variables that match

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}
}
<|endoftext|>


<commit_before>package cmd

import (
	"os"

	"bytes"
	"context"
	"fmt"
	"sort"
	"strings"

	"github.com/kr/pretty"
	"github.com/spf13/cobra"
	"github.com/zrepl/zrepl/logger"
	"github.com/zrepl/zrepl/zfs"
	"time"
)

var testCmd = &cobra.Command{
	Use:              "test",
	Short:            "test configuration",
	PersistentPreRun: testCmdGlobalInit,
}

var testCmdGlobal struct {
	log  Logger
	conf *Config
}

var testConfigSyntaxCmd = &cobra.Command{
	Use:   "config",
	Short: "parse config file and dump parsed datastructure",
	Run:   doTestConfig,
}

var testDatasetMapFilter = &cobra.Command{
	Use:     "pattern jobname test/zfs/dataset/path",
	Short:   "test dataset mapping / filter specified in config",
	Example: ` zrepl test pattern prune.clean_backups tank/backups/legacyscript/foo`,
	Run:     doTestDatasetMapFilter,
}

var testPrunePolicyArgs struct {
	side        PrunePolicySide
	showKept    bool
	showRemoved bool
}

var testPrunePolicyCmd = &cobra.Command{
	Use:   "prune jobname",
	Short: "do a dry-run of the pruning part of a job",
	Run:   doTestPrunePolicy,
}

func init() {
	RootCmd.AddCommand(testCmd)
	testCmd.AddCommand(testConfigSyntaxCmd)
	testCmd.AddCommand(testDatasetMapFilter)

	testPrunePolicyCmd.Flags().VarP(&testPrunePolicyArgs.side, "side", "s", "prune_lhs (left) or prune_rhs (right)")
	testPrunePolicyCmd.Flags().BoolVar(&testPrunePolicyArgs.showKept, "kept", false, "show kept snapshots")
	testPrunePolicyCmd.Flags().BoolVar(&testPrunePolicyArgs.showRemoved, "removed", true, "show removed snapshots")
	testCmd.AddCommand(testPrunePolicyCmd)
}

func testCmdGlobalInit(cmd *cobra.Command, args []string) {

	out := logger.NewOutlets()
	out.Add(WriterOutlet{&NoFormatter{}, os.Stdout}, logger.Info)
	log := logger.NewLogger(out, 1*time.Second)
	testCmdGlobal.log = log

	var err error
	if testCmdGlobal.conf, err = ParseConfig(rootArgs.configFile); err != nil {
		testCmdGlobal.log.Printf("error parsing config file: %s", err)
		os.Exit(1)
	}

}

func doTestConfig(cmd *cobra.Command, args []string) {

	log, conf := testCmdGlobal.log, testCmdGlobal.conf

	log.Printf("config ok")
	log.Printf("%# v", pretty.Formatter(conf))
	return
}

func doTestDatasetMapFilter(cmd *cobra.Command, args []string) {

	log, conf := testCmdGlobal.log, testCmdGlobal.conf

	if len(args) != 2 {
		log.Printf("specify job name as first postitional argument, test input as second")
		log.Printf(cmd.UsageString())
		os.Exit(1)
	}
	n, i := args[0], args[1]

	jobi, err := conf.LookupJob(n)
	if err != nil {
		log.Printf("%s", err)
		os.Exit(1)
	}

	var mf *DatasetMapFilter
	switch j := jobi.(type) {
	case *PullJob:
		mf = j.Mapping
	case *SourceJob:
		mf = j.Filesystems
	case *LocalJob:
		mf = j.Mapping
	default:
		panic("incomplete implementation")
	}

	ip, err := zfs.NewDatasetPath(i)
	if err != nil {
		log.Printf("cannot parse test input as ZFS dataset path: %s", err)
		os.Exit(1)
	}

	if mf.filterMode {
		pass, err := mf.Filter(ip)
		if err != nil {
			log.Printf("error evaluating filter: %s", err)
			os.Exit(1)
		}
		log.Printf("filter result: %v", pass)
	} else {
		res, err := mf.Map(ip)
		if err != nil {
			log.Printf("error evaluating mapping: %s", err)
			os.Exit(1)
		}
		toStr := "NO MAPPING"
		if res != nil {
			toStr = res.ToString()
		}
		log.Printf("%s => %s", ip.ToString(), toStr)

	}

}

func doTestPrunePolicy(cmd *cobra.Command, args []string) {

	log, conf := testCmdGlobal.log, testCmdGlobal.conf

	if cmd.Flags().NArg() != 1 {
		log.Printf("specify job name as first positional argument")
		log.Printf(cmd.UsageString())
		os.Exit(1)
	}

	jobname := cmd.Flags().Arg(0)
	jobi, err := conf.LookupJob(jobname)
	if err != nil {
		log.Printf("%s", err)
		os.Exit(1)
	}

	jobp, ok := jobi.(PruningJob)
	if !ok {
		log.Printf("job doesn't do any prunes")
		os.Exit(0)
	}

	log.Printf("job dump:\n%s", pretty.Sprint(jobp))

	task := NewTask("", log)
	pruner, err := jobp.Pruner(task, testPrunePolicyArgs.side, true)
	if err != nil {
		log.Printf("cannot create test pruner: %s", err)
		os.Exit(1)
	}

	log.Printf("start pruning")

	ctx := context.WithValue(context.Background(), contextKeyLog, log)
	result, err := pruner.Run(ctx)
	if err != nil {
		log.Printf("error running pruner: %s", err)
		os.Exit(1)
	}

	sort.Slice(result, func(i, j int) bool {
		return strings.Compare(result[i].Filesystem.ToString(), result[j].Filesystem.ToString()) == -1
	})

	var b bytes.Buffer
	for _, r := range result {
		fmt.Fprintf(&b, "%s\n", r.Filesystem.ToString())

		if testPrunePolicyArgs.showKept {
			fmt.Fprintf(&b, "\tkept:\n")
			for _, v := range r.Keep {
				fmt.Fprintf(&b, "\t- %s\n", v.Name)
			}
		}

		if testPrunePolicyArgs.showRemoved {
			fmt.Fprintf(&b, "\tremoved:\n")
			for _, v := range r.Remove {
				fmt.Fprintf(&b, "\t- %s\n", v.Name)
			}
		}

	}

	log.Printf("pruning result:\n%s", b.String())

}
<commit_msg>test pattern subcommand: better example command<commit_after>package cmd

import (
	"os"

	"bytes"
	"context"
	"fmt"
	"sort"
	"strings"

	"github.com/kr/pretty"
	"github.com/spf13/cobra"
	"github.com/zrepl/zrepl/logger"
	"github.com/zrepl/zrepl/zfs"
	"time"
)

var testCmd = &cobra.Command{
	Use:              "test",
	Short:            "test configuration",
	PersistentPreRun: testCmdGlobalInit,
}

var testCmdGlobal struct {
	log  Logger
	conf *Config
}

var testConfigSyntaxCmd = &cobra.Command{
	Use:   "config",
	Short: "parse config file and dump parsed datastructure",
	Run:   doTestConfig,
}

var testDatasetMapFilter = &cobra.Command{
	Use:     "pattern jobname test/zfs/dataset/path",
	Short:   "test dataset mapping / filter specified in config",
	Example: ` zrepl test pattern my_pull_job tank/tmp`,
	Run:     doTestDatasetMapFilter,
}

var testPrunePolicyArgs struct {
	side        PrunePolicySide
	showKept    bool
	showRemoved bool
}

var testPrunePolicyCmd = &cobra.Command{
	Use:   "prune jobname",
	Short: "do a dry-run of the pruning part of a job",
	Run:   doTestPrunePolicy,
}

func init() {
	RootCmd.AddCommand(testCmd)
	testCmd.AddCommand(testConfigSyntaxCmd)
	testCmd.AddCommand(testDatasetMapFilter)

	testPrunePolicyCmd.Flags().VarP(&testPrunePolicyArgs.side, "side", "s", "prune_lhs (left) or prune_rhs (right)")
	testPrunePolicyCmd.Flags().BoolVar(&testPrunePolicyArgs.showKept, "kept", false, "show kept snapshots")
	testPrunePolicyCmd.Flags().BoolVar(&testPrunePolicyArgs.showRemoved, "removed", true, "show removed snapshots")
	testCmd.AddCommand(testPrunePolicyCmd)
}

func testCmdGlobalInit(cmd *cobra.Command, args []string) {

	out := logger.NewOutlets()
	out.Add(WriterOutlet{&NoFormatter{}, os.Stdout}, logger.Info)
	log := logger.NewLogger(out, 1*time.Second)
	testCmdGlobal.log = log

	var err error
	if testCmdGlobal.conf, err = ParseConfig(rootArgs.configFile); err != nil {
		testCmdGlobal.log.Printf("error parsing config file: %s", err)
		os.Exit(1)
	}

}

func doTestConfig(cmd *cobra.Command, args []string) {

	log, conf := testCmdGlobal.log, testCmdGlobal.conf

	log.Printf("config ok")
	log.Printf("%# v", pretty.Formatter(conf))
	return
}

func doTestDatasetMapFilter(cmd *cobra.Command, args []string) {

	log, conf := testCmdGlobal.log, testCmdGlobal.conf

	if len(args) != 2 {
		log.Printf("specify job name as first postitional argument, test input as second")
		log.Printf(cmd.UsageString())
		os.Exit(1)
	}
	n, i := args[0], args[1]

	jobi, err := conf.LookupJob(n)
	if err != nil {
		log.Printf("%s", err)
		os.Exit(1)
	}

	var mf *DatasetMapFilter
	switch j := jobi.(type) {
	case *PullJob:
		mf = j.Mapping
	case *SourceJob:
		mf = j.Filesystems
	case *LocalJob:
		mf = j.Mapping
	default:
		panic("incomplete implementation")
	}

	ip, err := zfs.NewDatasetPath(i)
	if err != nil {
		log.Printf("cannot parse test input as ZFS dataset path: %s", err)
		os.Exit(1)
	}

	if mf.filterMode {
		pass, err := mf.Filter(ip)
		if err != nil {
			log.Printf("error evaluating filter: %s", err)
			os.Exit(1)
		}
		log.Printf("filter result: %v", pass)
	} else {
		res, err := mf.Map(ip)
		if err != nil {
			log.Printf("error evaluating mapping: %s", err)
			os.Exit(1)
		}
		toStr := "NO MAPPING"
		if res != nil {
			toStr = res.ToString()
		}
		log.Printf("%s => %s", ip.ToString(), toStr)

	}

}

func doTestPrunePolicy(cmd *cobra.Command, args []string) {

	log, conf := testCmdGlobal.log, testCmdGlobal.conf

	if cmd.Flags().NArg() != 1 {
		log.Printf("specify job name as first positional argument")
		log.Printf(cmd.UsageString())
		os.Exit(1)
	}

	jobname := cmd.Flags().Arg(0)
	jobi, err := conf.LookupJob(jobname)
	if err != nil {
		log.Printf("%s", err)
		os.Exit(1)
	}

	jobp, ok := jobi.(PruningJob)
	if !ok {
		log.Printf("job doesn't do any prunes")
		os.Exit(0)
	}

	log.Printf("job dump:\n%s", pretty.Sprint(jobp))

	task := NewTask("", log)
	pruner, err := jobp.Pruner(task, testPrunePolicyArgs.side, true)
	if err != nil {
		log.Printf("cannot create test pruner: %s", err)
		os.Exit(1)
	}

	log.Printf("start pruning")

	ctx := context.WithValue(context.Background(), contextKeyLog, log)
	result, err := pruner.Run(ctx)
	if err != nil {
		log.Printf("error running pruner: %s", err)
		os.Exit(1)
	}

	sort.Slice(result, func(i, j int) bool {
		return strings.Compare(result[i].Filesystem.ToString(), result[j].Filesystem.ToString()) == -1
	})

	var b bytes.Buffer
	for _, r := range result {
		fmt.Fprintf(&b, "%s\n", r.Filesystem.ToString())

		if testPrunePolicyArgs.showKept {
			fmt.Fprintf(&b, "\tkept:\n")
			for _, v := range r.Keep {
				fmt.Fprintf(&b, "\t- %s\n", v.Name)
			}
		}

		if testPrunePolicyArgs.showRemoved {
			fmt.Fprintf(&b, "\tremoved:\n")
			for _, v := range r.Remove {
				fmt.Fprintf(&b, "\t- %s\n", v.Name)
			}
		}

	}

	log.Printf("pruning result:\n%s", b.String())

}
<|endoftext|>


<commit_before>package main

import (
	"./src/gdssh"
	"fmt"
	"log"
	"os"
	"strings"
)

type pushTask struct {
	local  string
	remote string
}

func parsePushOptions(opt GdshOptions) *pushTask {
	task := pushTask{}

	// bare argument style, e.g. gdsh push /etc/hosts /etc/hosts
	if len(opt.Args) == 2 {
		if strings.HasPrefix(opt.Args[0], "-") {
			log.Fatal("Malformed command? Leading dashes are not allowed with bare arguments.")
		}

		if strings.HasPrefix(opt.Args[1], "-") {
			log.Fatal("Malformed command? Leading dashes are not allowed with bare arguments.")
		}

		_, err := os.Stat(opt.Args[0])
		if err != nil {
			log.Fatal(fmt.Sprintf("Not enough arguments. '%s' is not a file: %s", opt.Args[0], err))
		}

		task.local = opt.Args[0]
		task.remote = opt.Args[1]

		// fully-specified style, e.g. gdsh scp --local /etc/hosts --remote /etc/hosts
	} else if len(opt.Args) == 4 {
		skip := false
		for i, arg := range opt.Args {
			if skip {
				skip = false
				continue
			} else if arg == "--local" || arg == "-L" {
				_, err := os.Stat(opt.Args[i+1])
				if err != nil {
					log.Fatal(fmt.Sprintf("Invalid local file '%s': %s", opt.Args[i+1], err))
				}
				task.local = opt.Args[i+1]
				skip = true
			} else if arg == "--remote" || arg == "-R" {
				task.remote = opt.Args[i+1]
				skip = true
			}
		}
	} else {
		log.Fatal("Wrong number of arguments.")
	}

	return &task
}

// the file will be opened for each remote host, but that's fine since
// the reads will end up shared on modern operating systems
func (task *pushTask) Run(conn *gdssh.Conn) error {
	conn.Scp(task.local, task.remote)
	return nil
}

func cmdPush(opt GdshOptions) int {
	pool := sshPool(opt)
	task := parsePushOptions(opt)
	pool.All(task)
	pool.Close()

	return 1
}

// vim: ts=4 sw=4 noet tw=120 softtabstop=4
<commit_msg>Update comments.<commit_after>package main

import (
	"./src/gdssh"
	"fmt"
	"log"
	"os"
	"strings"
)

type pushTask struct {
	local  string
	remote string
}

func parsePushOptions(opt GdshOptions) *pushTask {
	task := pushTask{}

	if len(opt.Args) == 2 {
		// bare argument style, e.g. gdsh push /etc/hosts /etc/hosts
		if strings.HasPrefix(opt.Args[0], "-") {
			log.Fatal("Malformed command? Leading dashes are not allowed with bare arguments.")
		}

		if strings.HasPrefix(opt.Args[1], "-") {
			log.Fatal("Malformed command? Leading dashes are not allowed with bare arguments.")
		}

		_, err := os.Stat(opt.Args[0])
		if err != nil {
			log.Fatal(fmt.Sprintf("Not enough arguments. '%s' is not a file: %s", opt.Args[0], err))
		}

		task.local = opt.Args[0]
		task.remote = opt.Args[1]

	} else if len(opt.Args) == 4 {
		// fully-specified style, e.g. gdsh push -L /etc/hosts -R /etc
		skip := false
		for i, arg := range opt.Args {
			if skip {
				skip = false
				continue
			} else if arg == "--local" || arg == "-L" {
				_, err := os.Stat(opt.Args[i+1])
				if err != nil {
					log.Fatal(fmt.Sprintf("Invalid local file '%s': %s", opt.Args[i+1], err))
				}
				task.local = opt.Args[i+1]
				skip = true
			} else if arg == "--remote" || arg == "-R" {
				task.remote = opt.Args[i+1]
				skip = true
			}
		}
	} else {
		log.Fatal("Wrong number of arguments.")
	}

	return &task
}

// the file will be opened for each remote host, but that's fine since
// the reads will end up shared on modern operating systems
func (task *pushTask) Run(conn *gdssh.Conn) error {
	conn.ScpPush(task.local, task.remote)
	return nil
}

func cmdPush(opt GdshOptions) int {
	pool := sshPool(opt)
	task := parsePushOptions(opt)
	pool.All(task)
	pool.Close()

	return 1
}

// vim: ts=4 sw=4 noet tw=120 softtabstop=4
<|endoftext|>


<commit_before>package timeoutcmd

import (
	"io"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
	"time"

	"github.com/bitrise-io/go-utils/log"
)

// Command controls the command run.
type Command struct {
	cmd *exec.Cmd

	timeout       time.Duration
	timeoutTimer  *time.Timer
	interruptChan chan os.Signal
}

// New creates a command model.
func New(dir, name string, args ...string) Command {
	c := Command{}

	c.cmd = exec.Command(name, args...)
	c.cmd.Dir = dir

	return c
}

// SetTimeout sets the max runtime of the command.
func (c *Command) SetTimeout(t time.Duration) {
	c.timeout = t
}

// AppendEnv appends and env to the command's env list.
func (c *Command) AppendEnv(env string) {
	if c.cmd.Env != nil {
		c.cmd.Env = append(c.cmd.Env, env)
		return
	}
	c.cmd.Env = append(os.Environ(), env)
}

// SetStandardIO sets the input and outputs of the command.
func (c *Command) SetStandardIO(in io.Reader, out, err io.Writer) {
	c.cmd.Stdin = in
	c.cmd.Stdout = out
	c.cmd.Stderr = err
}

// Start starts the command run.
func (c *Command) Start() error {
	if c.timeout > 0 {
		// Setpgid: true creates a new process group for cmd and its subprocesses
		// this way we can kill the whole process group
		c.cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
	}

	if err := c.cmd.Start(); err != nil {
		return err
	}

	if c.timeout > 0 {
		// terminate the process after the given timeout
		c.timeoutTimer = time.AfterFunc(c.timeout, func() {
			if err := c.Stop(); err != nil {
				log.Warnf("Failed to kill the process, error: %s", err)
			}
		})

		// Setpgid: true creates a new process group for cmd and its subprocesses
		// this way cmd will not belong to its parent process group,
		// cmd will not be killed when you hit ^C in your terminal
		// to fix this, we listen and handle Interrupt signal manually
		c.interruptChan = make(chan os.Signal, 1)
		signal.Notify(c.interruptChan, os.Interrupt)
		go func() {
			<-c.interruptChan
			signal.Stop(c.interruptChan)
			if err := c.Stop(); err != nil {
				log.Warnf("Failed to kill the process, error: %s", err)
			}
		}()
	}

	return c.cmd.Wait()
}

// Stop terminates the command run.
func (c *Command) Stop() error {
	if c.cmd.Process == nil {
		// not yet started
		return nil
	}

	pid := c.cmd.Process.Pid
	if c.timeout > 0 {
		// stop listening on os.Interrupt signal
		signal.Stop(c.interruptChan)
		// stop the timeout timer
		c.timeoutTimer.Stop()

		// use the negative process group id, to kill the whole process group
		pgid, err := syscall.Getpgid(c.cmd.Process.Pid)
		if err != nil {
			return err
		}
		pid = -1 * pgid
	}

	// kill the process
	return syscall.Kill(pid, syscall.SIGKILL)
}

// ExitStatus returns the error's exit status
// if the error is an exec.ExitError
// if the error is nil it return 0
// otherwise returns 1.
func ExitStatus(err error) int {
	if err == nil {
		return 0
	}

	code := 1
	if exiterr, ok := err.(*exec.ExitError); ok {
		if waitStatus, ok := exiterr.Sys().(syscall.WaitStatus); ok {
			code = waitStatus.ExitStatus()
		}
	}
	return code
}
<commit_msg>Fix process signals not being captured by child processes (#652)<commit_after>package timeoutcmd

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
	"time"

	"github.com/bitrise-io/go-utils/log"
)

// Command controls the command run.
type Command struct {
	cmd     *exec.Cmd
	timeout time.Duration
}

// New creates a command model.
func New(dir, name string, args ...string) Command {
	c := Command{
		cmd: exec.Command(name, args...),
	}
	c.cmd.Dir = dir
	return c
}

// SetTimeout sets the max runtime of the command.
func (c *Command) SetTimeout(t time.Duration) {
	c.timeout = t
}

// AppendEnv appends and env to the command's env list.
func (c *Command) AppendEnv(env string) {
	if c.cmd.Env != nil {
		c.cmd.Env = append(c.cmd.Env, env)
		return
	}
	c.cmd.Env = append(os.Environ(), env)
}

// SetStandardIO sets the input and outputs of the command.
func (c *Command) SetStandardIO(in io.Reader, out, err io.Writer) {
	c.cmd.Stdin, c.cmd.Stdout, c.cmd.Stderr = in, out, err
}

// Start starts the command run.
func (c *Command) Start() error {
	// setting up notification for signals so we can have
	// separated logic to end the process
	interruptChan := make(chan os.Signal)
	signal.Notify(interruptChan, os.Interrupt, os.Kill)
	var interrupted bool
	go func() {
		<-interruptChan
		interrupted = true
	}()

	// start the process
	if err := c.cmd.Start(); err != nil {
		return err
	}

	// Wait for the process to finish
	done := make(chan error, 1)
	go func() {
		done <- c.cmd.Wait()
	}()

	// or kill it after a timeout (whichever happens first)
	var timeoutChan <-chan time.Time
	if c.timeout > 0 {
		timeoutChan = time.After(c.timeout)
	}

	// exiting the method for the two supported cases: finish/error or timeout
	select {
	case <-timeoutChan:
		if err := c.cmd.Process.Kill(); err != nil {
			log.Warnf("Failed to kill process: %s", err)
		}
		return fmt.Errorf("timed out")
	case err := <-done:
		if interrupted {
			os.Exit(ExitStatus(err))
		}
		return err
	}
}

// ExitStatus returns the error's exit status
// if the error is an exec.ExitError
// if the error is nil it return 0
// otherwise returns 1.
func ExitStatus(err error) int {
	if err == nil {
		return 0
	}

	code := 1
	if exiterr, ok := err.(*exec.ExitError); ok {
		if waitStatus, ok := exiterr.Sys().(syscall.WaitStatus); ok {
			code = waitStatus.ExitStatus()
		}
	}
	return code
}
<|endoftext|>