<commit_before>package main

import (
	"bytes"
	"fmt"
	"html/template"
	"io"
	"log"
	"os"
	path "path/filepath"
	"strings"

	"github.com/codegangsta/cli"
)

var (
	cmd     string
	appname string
)

func copyFile(source string, dest string) (err error) {
	sourcefile, err := os.Open(source)
	if err != nil {
		return err
	}

	defer sourcefile.Close()

	destfile, err := os.Create(dest)
	if err != nil {
		return err
	}

	defer destfile.Close()

	_, err = io.Copy(destfile, sourcefile)
	if err == nil {
		sourceinfo, err := os.Stat(source)
		if err != nil {
			err = os.Chmod(dest, sourceinfo.Mode())
		}

	}

	return
}

func copyDir(source string, dest string) (err error) {

	// get properties of source dir
	sourceinfo, err := os.Stat(source)
	if err != nil {
		return err
	}

	// create dest dir

	err = os.MkdirAll(dest, sourceinfo.Mode())
	if err != nil {
		return err
	}

	directory, _ := os.Open(source)

	objects, err := directory.Readdir(-1)

	for _, obj := range objects {

		sourcefilepointer := source + "/" + obj.Name()

		destinationfilepointer := dest + "/" + obj.Name()

		if obj.IsDir() {
			// create sub-directories - recursively
			err = copyDir(sourcefilepointer, destinationfilepointer)
			if err != nil {
				fmt.Println(err)
			}
		} else {
			// perform copy
			err = copyFile(sourcefilepointer, destinationfilepointer)
			if err != nil {
				fmt.Println(err)
			}
		}

	}
	return
}

func writetofile(filename, content string) {
	f, err := os.Create(filename)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	f.WriteString(content)
}

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

func containsString(slice []string, element string) bool {
	for _, elem := range slice {
		if elem == element {
			return true
		}
	}
	return false
}

func askForConfirmation() bool {
	var response string
	_, err := fmt.Scanln(&response)
	if err != nil {
		log.Fatal(err)
	}
	okayResponses := []string{"y", "Y", "yes", "Yes", "YES"}
	nokayResponses := []string{"n", "N", "no", "No", "NO"}
	if containsString(okayResponses, response) {
		return true
	} else if containsString(nokayResponses, response) {
		return false
	} else {
		fmt.Println("Please type yes or no and then press enter:")
		return askForConfirmation()
	}
}

func createApp(name string) {
	curpath, _ := os.Getwd()
	log.Println("current path:", curpath)
	gopath := os.Getenv("GOPATH")
	log.Println("gopath:", gopath)
	if gopath == "" {
		log.Println("[ERRO] $GOPATH not found\n")
		log.Println("[HINT] Set $GOPATH in your environment vairables\n")
		os.Exit(2)
	}

	haspath := false
	appsrcpath := ""

	wgopath := path.SplitList(gopath)
	for _, wg := range wgopath {

		wg = path.Join(wg, "src")

		if strings.HasPrefix(strings.ToLower(curpath), strings.ToLower(wg)) {
			haspath = true
			appsrcpath = wg
			break
		}

		wg, _ = path.EvalSymlinks(wg)

		if strings.HasPrefix(strings.ToLower(curpath), strings.ToLower(wg)) {
			haspath = true
			appsrcpath = wg
			break
		}

	}

	if !haspath {
		log.Printf("[ERRO] Unable to create an application outside of $GOPATH%ssrc(%s%ssrc)\n", string(path.Separator), gopath, string(path.Separator))
		log.Printf("[HINT] Change your work directory by `cd ($GOPATH%ssrc)`\n", string(path.Separator))
		os.Exit(2)
	}

	apppath := path.Join(curpath, name)

	if isExist(apppath) {
		log.Printf("[ERRO] Path (%s) already exists\n", apppath)
		log.Printf("[WARN] Do you want to overwrite it? [yes|no]]")
		if !askForConfirmation() {
			os.Exit(2)
		}
	}
	pathToValente := path.Join(appsrcpath, "github.com", "trumae", "valente")
	pathToValenteData := path.Join(pathToValente, "data")
	pathToValenteDataPublic := path.Join(pathToValenteData, "public")
	pathToValenteDataForms := path.Join(pathToValenteData, "forms")

	log.Println("Creating application ...")

	os.MkdirAll(apppath, 0755)
	fmt.Println(apppath + string(path.Separator))

	copyDir(pathToValenteDataPublic, path.Join(apppath, "public"))
	copyDir(pathToValenteDataForms, path.Join(apppath, "forms"))

	packageForms := path.Join(apppath[len(appsrcpath)+1:], "forms")

	tmpl, err := template.New("forms").Parse(tplMainGo)
	if err != nil {
		panic(err)
	}

	buf := new(bytes.Buffer)
	err = tmpl.Execute(buf, packageForms)
	if err != nil {
		panic(err)
	}
	writetofile(path.Join(apppath, "main.go"), buf.String())

}

func main() {
	app := cli.NewApp()
	app.Name = "valente"
	app.Usage = "Tool for easy use of valente websocket micro-framework"

	app.Commands = []cli.Command{
		{
			Name:    "new",
			Aliases: []string{"n"},
			Usage:   "create a new project",
			Action: func(c *cli.Context) {
				appname := c.Args().First()
				log.Println("Creating app ", appname)
				createApp(appname)
			},
		},
		/*		{
					Name:    "complete",
					Aliases: []string{"c"},
					Usage:   "complete a task on the list",
					Action: func(c *cli.Context) {
						println("completed task: ", c.Args().First())
					},
				},
				{
					Name:    "template",
					Aliases: []string{"r"},
					Usage:   "options for task templates",
					Subcommands: []cli.Command{
						{
							Name:  "add",
							Usage: "add a new template",
							Action: func(c *cli.Context) {
								println("new task template: ", c.Args().First())
							},
						},
						{
							Name:  "remove",
							Usage: "remove an existing template",
							Action: func(c *cli.Context) {
								println("removed task template: ", c.Args().First())
							},
						},
					},
				},*/
	}

	app.Run(os.Args)
}

const tplMainGo = `package main

import (
   "log"
   "runtime"

   "github.com/labstack/echo"
   "github.com/labstack/echo/engine/standard"
   "github.com/labstack/echo/middleware"
   "github.com/trumae/valente"
	 "{{ . }}"

   "golang.org/x/net/websocket"
)

//App is a Web Application representation
type App struct {
    valente.App
}

//Initialize inits the App
func (app *App) Initialize() {
    log.Println("App Initialize")

    app.AddForm("login", forms.FormLogin{})
    app.AddForm("home", forms.FormHome{})

    app.GoTo("login", nil)
}

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())

    e := echo.New()

    e.Use(middleware.Logger())
    e.Use(middleware.Recover())
    e.Use(middleware.Static("public"))

    e.Get("/ws", standard.WrapHandler(websocket.Handler(func(ws *websocket.Conn) {
       app := App{}
       app.WS = ws
       app.Initialize()
       app.Run()
    })))

		log.Println("Server running")
    e.Run(standard.New(":8000"))
}

`
<commit_msg>author in tool<commit_after>package main

import (
	"bytes"
	"fmt"
	"html/template"
	"io"
	"log"
	"os"
	path "path/filepath"
	"strings"

	"github.com/codegangsta/cli"
)

func copyFile(source string, dest string) (err error) {
	sourcefile, err := os.Open(source)
	if err != nil {
		return err
	}

	defer sourcefile.Close()

	destfile, err := os.Create(dest)
	if err != nil {
		return err
	}

	defer destfile.Close()

	_, err = io.Copy(destfile, sourcefile)
	if err == nil {
		sourceinfo, err := os.Stat(source)
		if err != nil {
			err = os.Chmod(dest, sourceinfo.Mode())
		}

	}

	return
}

func copyDir(source string, dest string) (err error) {

	// get properties of source dir
	sourceinfo, err := os.Stat(source)
	if err != nil {
		return err
	}

	// create dest dir

	err = os.MkdirAll(dest, sourceinfo.Mode())
	if err != nil {
		return err
	}

	directory, _ := os.Open(source)

	objects, err := directory.Readdir(-1)

	for _, obj := range objects {

		sourcefilepointer := source + "/" + obj.Name()

		destinationfilepointer := dest + "/" + obj.Name()

		if obj.IsDir() {
			// create sub-directories - recursively
			err = copyDir(sourcefilepointer, destinationfilepointer)
			if err != nil {
				fmt.Println(err)
			}
		} else {
			// perform copy
			err = copyFile(sourcefilepointer, destinationfilepointer)
			if err != nil {
				fmt.Println(err)
			}
		}

	}
	return
}

func writetofile(filename, content string) {
	f, err := os.Create(filename)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	f.WriteString(content)
}

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

func containsString(slice []string, element string) bool {
	for _, elem := range slice {
		if elem == element {
			return true
		}
	}
	return false
}

func askForConfirmation() bool {
	var response string
	_, err := fmt.Scanln(&response)
	if err != nil {
		log.Fatal(err)
	}
	okayResponses := []string{"y", "Y", "yes", "Yes", "YES"}
	nokayResponses := []string{"n", "N", "no", "No", "NO"}
	if containsString(okayResponses, response) {
		return true
	} else if containsString(nokayResponses, response) {
		return false
	} else {
		fmt.Println("Please type yes or no and then press enter:")
		return askForConfirmation()
	}
}

func createApp(name string) {
	curpath, _ := os.Getwd()
	log.Println("current path:", curpath)
	gopath := os.Getenv("GOPATH")
	log.Println("gopath:", gopath)
	if gopath == "" {
		log.Println("[ERRO] $GOPATH not found\n")
		log.Println("[HINT] Set $GOPATH in your environment vairables\n")
		os.Exit(2)
	}

	haspath := false
	appsrcpath := ""

	wgopath := path.SplitList(gopath)
	for _, wg := range wgopath {

		wg = path.Join(wg, "src")

		if strings.HasPrefix(strings.ToLower(curpath), strings.ToLower(wg)) {
			haspath = true
			appsrcpath = wg
			break
		}

		wg, _ = path.EvalSymlinks(wg)

		if strings.HasPrefix(strings.ToLower(curpath), strings.ToLower(wg)) {
			haspath = true
			appsrcpath = wg
			break
		}

	}

	if !haspath {
		log.Printf("[ERRO] Unable to create an application outside of $GOPATH%ssrc(%s%ssrc)\n", string(path.Separator), gopath, string(path.Separator))
		log.Printf("[HINT] Change your work directory by `cd ($GOPATH%ssrc)`\n", string(path.Separator))
		os.Exit(2)
	}

	apppath := path.Join(curpath, name)

	if isExist(apppath) {
		log.Printf("[ERRO] Path (%s) already exists\n", apppath)
		log.Printf("[WARN] Do you want to overwrite it? [yes|no]]")
		if !askForConfirmation() {
			os.Exit(2)
		}
	}
	pathToValente := path.Join(appsrcpath, "github.com", "trumae", "valente")
	pathToValenteData := path.Join(pathToValente, "data")
	pathToValenteDataPublic := path.Join(pathToValenteData, "public")
	pathToValenteDataForms := path.Join(pathToValenteData, "forms")

	log.Println("Creating application ...")

	os.MkdirAll(apppath, 0755)
	fmt.Println(apppath + string(path.Separator))

	copyDir(pathToValenteDataPublic, path.Join(apppath, "public"))
	copyDir(pathToValenteDataForms, path.Join(apppath, "forms"))

	packageForms := path.Join(apppath[len(appsrcpath)+1:], "forms")

	tmpl, err := template.New("forms").Parse(tplMainGo)
	if err != nil {
		panic(err)
	}

	buf := new(bytes.Buffer)
	err = tmpl.Execute(buf, packageForms)
	if err != nil {
		panic(err)
	}
	writetofile(path.Join(apppath, "main.go"), buf.String())

}

func main() {
	trumae := cli.Author{Name: "Trumae da Ilha", Email: "trumae@gmail.com"}
	app := cli.NewApp()
	app.Name = "valente"
	app.Version = "0.0.1"
	app.Authors = []cli.Author{trumae}
	app.Usage = "Tool for easy use of valente websocket micro-framework"

	app.Commands = []cli.Command{
		{
			Name:    "new",
			Aliases: []string{"n"},
			Usage:   "create a new project",
			Action: func(c *cli.Context) {
				appname := c.Args().First()
				log.Println("Creating app ", appname)
				createApp(appname)
			},
		},
		/*		{
					Name:    "complete",
					Aliases: []string{"c"},
					Usage:   "complete a task on the list",
					Action: func(c *cli.Context) {
						println("completed task: ", c.Args().First())
					},
				},
				{
					Name:    "template",
					Aliases: []string{"r"},
					Usage:   "options for task templates",
					Subcommands: []cli.Command{
						{
							Name:  "add",
							Usage: "add a new template",
							Action: func(c *cli.Context) {
								println("new task template: ", c.Args().First())
							},
						},
						{
							Name:  "remove",
							Usage: "remove an existing template",
							Action: func(c *cli.Context) {
								println("removed task template: ", c.Args().First())
							},
						},
					},
				},*/
	}

	app.Run(os.Args)
}

const tplMainGo = `package main

import (
   "log"
   "runtime"

   "github.com/labstack/echo"
   "github.com/labstack/echo/engine/standard"
   "github.com/labstack/echo/middleware"
   "github.com/trumae/valente"
	 "{{ . }}"

   "golang.org/x/net/websocket"
)

//App is a Web Application representation
type App struct {
    valente.App
}

//Initialize inits the App
func (app *App) Initialize() {
    log.Println("App Initialize")

    app.AddForm("login", forms.FormLogin{})
    app.AddForm("home", forms.FormHome{})

    app.GoTo("login", nil)
}

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())

    e := echo.New()

    e.Use(middleware.Logger())
    e.Use(middleware.Recover())
    e.Use(middleware.Static("public"))

    e.Get("/ws", standard.WrapHandler(websocket.Handler(func(ws *websocket.Conn) {
       app := App{}
       app.WS = ws
       app.Initialize()
       app.Run()
    })))

		log.Println("Server running")
    e.Run(standard.New(":8000"))
}

`
<|endoftext|>


<commit_before>package agent

import (
	"bytes"
	"encoding/json"
	"log"
	"time"

	mqtt "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
)

const (
	updateTopic = "$hardware/status/+"
	statusTopic = "$sphere/leds/status"
)

/*
 Just manages all the data going into out of this service.
*/
type Bus struct {
	conf   *Config
	agent  *Agent
	client *mqtt.MqttClient
	ticker *time.Ticker
}

type updateRequest struct {
	Topic      string
	Brightness int    `json:"brightness"`
	On         bool   `json:"on"`
	Color      string `json:"color"`
	Flash      bool   `json:"flash"`
}

type statusEvent struct {
	Status string `json:"status"`
}

type statsEvent struct {

	// memory related information
	Alloc      uint64 `json:"alloc"`
	HeapAlloc  uint64 `json:"heapAlloc"`
	TotalAlloc uint64 `json:"totalAlloc"`
}

func createBus(conf *Config, agent *Agent) *Bus {

	return &Bus{conf: conf, agent: agent}
}

func (b *Bus) listen() {
	logger.Infof("connecting to the bus")

	opts := mqtt.NewClientOptions().SetBroker(b.conf.LocalUrl).SetClientId("mqtt-bridgeify")

	// shut up
	opts.SetTraceLevel(mqtt.Off)

	b.client = mqtt.NewClient(opts)

	_, err := b.client.Start()
	if err != nil {
		log.Fatalf("error starting connection: %s", err)
	} else {
		logger.Infof("Connected as %s\n", b.conf.LocalUrl)
	}

	topicFilter, _ := mqtt.NewTopicFilter(updateTopic, 0)
	if _, err := b.client.StartSubscription(b.handleUpdate, topicFilter); err != nil {
		log.Fatalf("error starting subscription: %s", err)
	}

	b.setupBackgroundJob()

}

func (b *Bus) handleUpdate(client *mqtt.MqttClient, msg mqtt.Message) {
	logger.Debugf("handleUpdate")
	req := &updateRequest{}
	err := b.decodeRequest(&msg, req)
	if err != nil {
		logger.Errorf("Unable to decode connect request %s", err)
	}
	req.Topic = msg.Topic()
	b.agent.updateLeds(req)

}

func (b *Bus) setupBackgroundJob() {
	b.ticker = time.NewTicker(10 * time.Second)

	for {
		select {
		case <-b.ticker.C:
			// emit the status
			status := b.agent.getStatus()
			// log.Printf("[DEBUG] status %+v", status)
			b.client.PublishMessage(statusTopic, b.encodeRequest(status))
		}
	}

}

func (b *Bus) encodeRequest(data interface{}) *mqtt.Message {
	buf := bytes.NewBuffer(nil)
	json.NewEncoder(buf).Encode(data)
	return mqtt.NewMessage(buf.Bytes())
}

func (b *Bus) decodeRequest(msg *mqtt.Message, data interface{}) error {
	return json.NewDecoder(bytes.NewBuffer(msg.Payload())).Decode(data)
}
<commit_msg>mqtt API changes: SetBroker is now AddBroker, SetTraceLevel does not exist.<commit_after>package agent

import (
	"bytes"
	"encoding/json"
	"log"
	"time"

	mqtt "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
)

const (
	updateTopic = "$hardware/status/+"
	statusTopic = "$sphere/leds/status"
)

/*
 Just manages all the data going into out of this service.
*/
type Bus struct {
	conf   *Config
	agent  *Agent
	client *mqtt.MqttClient
	ticker *time.Ticker
}

type updateRequest struct {
	Topic      string
	Brightness int    `json:"brightness"`
	On         bool   `json:"on"`
	Color      string `json:"color"`
	Flash      bool   `json:"flash"`
}

type statusEvent struct {
	Status string `json:"status"`
}

type statsEvent struct {

	// memory related information
	Alloc      uint64 `json:"alloc"`
	HeapAlloc  uint64 `json:"heapAlloc"`
	TotalAlloc uint64 `json:"totalAlloc"`
}

func createBus(conf *Config, agent *Agent) *Bus {

	return &Bus{conf: conf, agent: agent}
}

func (b *Bus) listen() {
	logger.Infof("connecting to the bus")

	opts := mqtt.NewClientOptions().AddBroker(b.conf.LocalUrl).SetClientId("mqtt-bridgeify")

	// shut up
	b.client = mqtt.NewClient(opts)

	_, err := b.client.Start()
	if err != nil {
		log.Fatalf("error starting connection: %s", err)
	} else {
		logger.Infof("Connected as %s\n", b.conf.LocalUrl)
	}

	topicFilter, _ := mqtt.NewTopicFilter(updateTopic, 0)
	if _, err := b.client.StartSubscription(b.handleUpdate, topicFilter); err != nil {
		log.Fatalf("error starting subscription: %s", err)
	}

	b.setupBackgroundJob()

}

func (b *Bus) handleUpdate(client *mqtt.MqttClient, msg mqtt.Message) {
	logger.Debugf("handleUpdate")
	req := &updateRequest{}
	err := b.decodeRequest(&msg, req)
	if err != nil {
		logger.Errorf("Unable to decode connect request %s", err)
	}
	req.Topic = msg.Topic()
	b.agent.updateLeds(req)

}

func (b *Bus) setupBackgroundJob() {
	b.ticker = time.NewTicker(10 * time.Second)

	for {
		select {
		case <-b.ticker.C:
			// emit the status
			status := b.agent.getStatus()
			// log.Printf("[DEBUG] status %+v", status)
			b.client.PublishMessage(statusTopic, b.encodeRequest(status))
		}
	}

}

func (b *Bus) encodeRequest(data interface{}) *mqtt.Message {
	buf := bytes.NewBuffer(nil)
	json.NewEncoder(buf).Encode(data)
	return mqtt.NewMessage(buf.Bytes())
}

func (b *Bus) decodeRequest(msg *mqtt.Message, data interface{}) error {
	return json.NewDecoder(bytes.NewBuffer(msg.Payload())).Decode(data)
}
<|endoftext|>


<commit_before>package command

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

	"github.com/hashicorp/hcl2/hcl"
	"github.com/hashicorp/hcl2/hcl/hclsyntax"
	hcljson "github.com/hashicorp/hcl2/hcl/json"

	"github.com/hashicorp/terraform/backend"
	"github.com/hashicorp/terraform/configs"
	"github.com/hashicorp/terraform/terraform"
	"github.com/hashicorp/terraform/tfdiags"
)

// collectVariableValues inspects the various places that root module input variable
// values can come from and constructs a map ready to be passed to the
// backend as part of a backend.Operation.
//
// This method returns diagnostics relating to the collection of the values,
// but the values themselves may produce additional diagnostics when finally
// parsed.
func (m *Meta) collectVariableValues() (map[string]backend.UnparsedVariableValue, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	ret := map[string]backend.UnparsedVariableValue{}

	// First we'll deal with environment variables, since they have the lowest
	// precedence.
	{
		env := os.Environ()
		for _, raw := range env {
			if !strings.HasPrefix(raw, terraform.VarEnvPrefix) {
				continue
			}
			raw = raw[len(terraform.VarEnvPrefix):] // trim the prefix

			eq := strings.Index(raw, "=")
			if eq == -1 {
				// Seems invalid, so we'll ignore it.
				continue
			}

			name := raw[:eq]
			rawVal := raw[eq+1:]

			ret[name] = unparsedVariableValueString{
				str:        rawVal,
				name:       name,
				sourceType: terraform.ValueFromEnvVar,
			}
		}
	}

	// Next up we have some implicit files that are loaded automatically
	// if they are present. There's the original terraform.tfvars
	// (DefaultVarsFilename) along with the later-added search for all files
	// ending in .auto.tfvars.
	if _, err := os.Stat(DefaultVarsFilename); err == nil {
		moreDiags := m.addVarsFromFile(DefaultVarsFilename, terraform.ValueFromFile, ret)
		diags = diags.Append(moreDiags)
	}
	if infos, err := ioutil.ReadDir("."); err == nil {
		// "infos" is already sorted by name, so we just need to filter it here.
		for _, info := range infos {
			name := info.Name()
			if !isAutoVarFile(name) {
				continue
			}
			moreDiags := m.addVarsFromFile(name, terraform.ValueFromFile, ret)
			diags = diags.Append(moreDiags)
		}
	}

	// Finally we process values given explicitly on the command line, either
	// as individual literal settings or as additional files to read.
	for _, rawFlag := range m.variableArgs.AllItems() {
		switch rawFlag.Name {
		case "-var":
			// Value should be in the form "name=value", where value is a
			// raw string whose interpretation will depend on the variable's
			// parsing mode.
			raw := rawFlag.Value
			eq := strings.Index(raw, "=")
			if eq == -1 {
				diags = diags.Append(tfdiags.Sourceless(
					tfdiags.Error,
					"Invalid -var option",
					fmt.Sprintf("The given -var option %q is not correctly specified. Must be a variable name and value separated by an equals sign, like -var=\"key=value\".", raw),
				))
				continue
			}
			name := raw[:eq]
			rawVal := raw[eq+1:]
			ret[name] = unparsedVariableValueString{
				str:        rawVal,
				name:       name,
				sourceType: terraform.ValueFromCLIArg,
			}

		case "-var-file":
			moreDiags := m.addVarsFromFile(rawFlag.Value, terraform.ValueFromFile, ret)
			diags = diags.Append(moreDiags)

		default:
			// Should never happen; always a bug in the code that built up
			// the contents of m.variableArgs.
			diags = diags.Append(fmt.Errorf("unsupported variable option name %q (this is a bug in Terraform)", rawFlag.Name))
		}
	}

	return ret, diags
}

func (m *Meta) addVarsFromFile(filename string, sourceType terraform.ValueSourceType, to map[string]backend.UnparsedVariableValue) tfdiags.Diagnostics {
	var diags tfdiags.Diagnostics

	src, err := ioutil.ReadFile(filename)
	if err != nil {
		if os.IsNotExist(err) {
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				"Failed to read variables file",
				fmt.Sprintf("Given variables file %s does not exist.", filename),
			))
		} else {
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				"Failed to read variables file",
				fmt.Sprintf("Error while reading %s: %s.", filename, err),
			))
		}
		return diags
	}

	loader, err := m.initConfigLoader()
	if err != nil {
		diags = diags.Append(err)
		return diags
	}

	// Record the file source code for snippets in diagnostic messages.
	loader.Parser().ForceFileSource(filename, src)

	var f *hcl.File
	if strings.HasSuffix(filename, ".json") {
		var hclDiags hcl.Diagnostics
		f, hclDiags = hcljson.Parse(src, filename)
		diags = diags.Append(hclDiags)
		if f == nil || f.Body == nil {
			return diags
		}
	} else {
		var hclDiags hcl.Diagnostics
		f, hclDiags = hclsyntax.ParseConfig(src, filename, hcl.Pos{Line: 1, Column: 1})
		diags = diags.Append(hclDiags)
		if f == nil || f.Body == nil {
			return diags
		}
	}

	attrs, hclDiags := f.Body.JustAttributes()
	diags = diags.Append(hclDiags)

	for name, attr := range attrs {
		to[name] = unparsedVariableValueExpression{
			expr:       attr.Expr,
			sourceType: sourceType,
		}
	}
	return diags
}

// unparsedVariableValueLiteral is a backend.UnparsedVariableValue
// implementation that was actually already parsed (!). This is
// intended to deal with expressions inside "tfvars" files.
type unparsedVariableValueExpression struct {
	expr       hcl.Expression
	sourceType terraform.ValueSourceType
}

func (v unparsedVariableValueExpression) ParseVariableValue(mode configs.VariableParsingMode) (*terraform.InputValue, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	val, hclDiags := v.expr.Value(nil) // nil because no function calls or variable references are allowed here
	diags = diags.Append(hclDiags)

	rng := tfdiags.SourceRangeFromHCL(v.expr.Range())

	return &terraform.InputValue{
		Value:       val,
		SourceType:  v.sourceType,
		SourceRange: rng,
	}, diags
}

// unparsedVariableValueString is a backend.UnparsedVariableValue
// implementation that parses its value from a string. This can be used
// to deal with values given directly on the command line and via environment
// variables.
type unparsedVariableValueString struct {
	str        string
	name       string
	sourceType terraform.ValueSourceType
}

func (v unparsedVariableValueString) ParseVariableValue(mode configs.VariableParsingMode) (*terraform.InputValue, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics

	val, hclDiags := mode.Parse(v.name, v.str)
	diags = diags.Append(hclDiags)

	return &terraform.InputValue{
		Value:      val,
		SourceType: v.sourceType,
	}, diags
}
<commit_msg>command: Restore support for terraform.tfvars.json<commit_after>package command

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

	"github.com/hashicorp/hcl2/hcl"
	"github.com/hashicorp/hcl2/hcl/hclsyntax"
	hcljson "github.com/hashicorp/hcl2/hcl/json"

	"github.com/hashicorp/terraform/backend"
	"github.com/hashicorp/terraform/configs"
	"github.com/hashicorp/terraform/terraform"
	"github.com/hashicorp/terraform/tfdiags"
)

// collectVariableValues inspects the various places that root module input variable
// values can come from and constructs a map ready to be passed to the
// backend as part of a backend.Operation.
//
// This method returns diagnostics relating to the collection of the values,
// but the values themselves may produce additional diagnostics when finally
// parsed.
func (m *Meta) collectVariableValues() (map[string]backend.UnparsedVariableValue, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	ret := map[string]backend.UnparsedVariableValue{}

	// First we'll deal with environment variables, since they have the lowest
	// precedence.
	{
		env := os.Environ()
		for _, raw := range env {
			if !strings.HasPrefix(raw, terraform.VarEnvPrefix) {
				continue
			}
			raw = raw[len(terraform.VarEnvPrefix):] // trim the prefix

			eq := strings.Index(raw, "=")
			if eq == -1 {
				// Seems invalid, so we'll ignore it.
				continue
			}

			name := raw[:eq]
			rawVal := raw[eq+1:]

			ret[name] = unparsedVariableValueString{
				str:        rawVal,
				name:       name,
				sourceType: terraform.ValueFromEnvVar,
			}
		}
	}

	// Next up we have some implicit files that are loaded automatically
	// if they are present. There's the original terraform.tfvars
	// (DefaultVarsFilename) along with the later-added search for all files
	// ending in .auto.tfvars.
	if _, err := os.Stat(DefaultVarsFilename); err == nil {
		moreDiags := m.addVarsFromFile(DefaultVarsFilename, terraform.ValueFromFile, ret)
		diags = diags.Append(moreDiags)
	}
	const defaultVarsFilenameJSON = DefaultVarsFilename + ".json"
	if _, err := os.Stat(defaultVarsFilenameJSON); err == nil {
		moreDiags := m.addVarsFromFile(defaultVarsFilenameJSON, terraform.ValueFromFile, ret)
		diags = diags.Append(moreDiags)
	}
	if infos, err := ioutil.ReadDir("."); err == nil {
		// "infos" is already sorted by name, so we just need to filter it here.
		for _, info := range infos {
			name := info.Name()
			if !isAutoVarFile(name) {
				continue
			}
			moreDiags := m.addVarsFromFile(name, terraform.ValueFromFile, ret)
			diags = diags.Append(moreDiags)
		}
	}

	// Finally we process values given explicitly on the command line, either
	// as individual literal settings or as additional files to read.
	for _, rawFlag := range m.variableArgs.AllItems() {
		switch rawFlag.Name {
		case "-var":
			// Value should be in the form "name=value", where value is a
			// raw string whose interpretation will depend on the variable's
			// parsing mode.
			raw := rawFlag.Value
			eq := strings.Index(raw, "=")
			if eq == -1 {
				diags = diags.Append(tfdiags.Sourceless(
					tfdiags.Error,
					"Invalid -var option",
					fmt.Sprintf("The given -var option %q is not correctly specified. Must be a variable name and value separated by an equals sign, like -var=\"key=value\".", raw),
				))
				continue
			}
			name := raw[:eq]
			rawVal := raw[eq+1:]
			ret[name] = unparsedVariableValueString{
				str:        rawVal,
				name:       name,
				sourceType: terraform.ValueFromCLIArg,
			}

		case "-var-file":
			moreDiags := m.addVarsFromFile(rawFlag.Value, terraform.ValueFromFile, ret)
			diags = diags.Append(moreDiags)

		default:
			// Should never happen; always a bug in the code that built up
			// the contents of m.variableArgs.
			diags = diags.Append(fmt.Errorf("unsupported variable option name %q (this is a bug in Terraform)", rawFlag.Name))
		}
	}

	return ret, diags
}

func (m *Meta) addVarsFromFile(filename string, sourceType terraform.ValueSourceType, to map[string]backend.UnparsedVariableValue) tfdiags.Diagnostics {
	var diags tfdiags.Diagnostics

	src, err := ioutil.ReadFile(filename)
	if err != nil {
		if os.IsNotExist(err) {
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				"Failed to read variables file",
				fmt.Sprintf("Given variables file %s does not exist.", filename),
			))
		} else {
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				"Failed to read variables file",
				fmt.Sprintf("Error while reading %s: %s.", filename, err),
			))
		}
		return diags
	}

	loader, err := m.initConfigLoader()
	if err != nil {
		diags = diags.Append(err)
		return diags
	}

	// Record the file source code for snippets in diagnostic messages.
	loader.Parser().ForceFileSource(filename, src)

	var f *hcl.File
	if strings.HasSuffix(filename, ".json") {
		var hclDiags hcl.Diagnostics
		f, hclDiags = hcljson.Parse(src, filename)
		diags = diags.Append(hclDiags)
		if f == nil || f.Body == nil {
			return diags
		}
	} else {
		var hclDiags hcl.Diagnostics
		f, hclDiags = hclsyntax.ParseConfig(src, filename, hcl.Pos{Line: 1, Column: 1})
		diags = diags.Append(hclDiags)
		if f == nil || f.Body == nil {
			return diags
		}
	}

	attrs, hclDiags := f.Body.JustAttributes()
	diags = diags.Append(hclDiags)

	for name, attr := range attrs {
		to[name] = unparsedVariableValueExpression{
			expr:       attr.Expr,
			sourceType: sourceType,
		}
	}
	return diags
}

// unparsedVariableValueLiteral is a backend.UnparsedVariableValue
// implementation that was actually already parsed (!). This is
// intended to deal with expressions inside "tfvars" files.
type unparsedVariableValueExpression struct {
	expr       hcl.Expression
	sourceType terraform.ValueSourceType
}

func (v unparsedVariableValueExpression) ParseVariableValue(mode configs.VariableParsingMode) (*terraform.InputValue, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	val, hclDiags := v.expr.Value(nil) // nil because no function calls or variable references are allowed here
	diags = diags.Append(hclDiags)

	rng := tfdiags.SourceRangeFromHCL(v.expr.Range())

	return &terraform.InputValue{
		Value:       val,
		SourceType:  v.sourceType,
		SourceRange: rng,
	}, diags
}

// unparsedVariableValueString is a backend.UnparsedVariableValue
// implementation that parses its value from a string. This can be used
// to deal with values given directly on the command line and via environment
// variables.
type unparsedVariableValueString struct {
	str        string
	name       string
	sourceType terraform.ValueSourceType
}

func (v unparsedVariableValueString) ParseVariableValue(mode configs.VariableParsingMode) (*terraform.InputValue, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics

	val, hclDiags := mode.Parse(v.name, v.str)
	diags = diags.Append(hclDiags)

	return &terraform.InputValue{
		Value:      val,
		SourceType: v.sourceType,
	}, diags
}
<|endoftext|>


<commit_before>package hdfs

import (
	"os"
	"syscall"
)

const (
	fileNotFoundException      = "java.io.FileNotFoundException"
	permissionDeniedException  = "org.apache.hadoop.security.AccessControlException"
	pathIsNotEmptyDirException = "org.apache.hadoop.fs.PathIsNotEmptyDirectoryException"
)

// Error represents a remote java exception from an HDFS namenode or datanode.
type Error interface {
	// Method returns the RPC method that encountered an error.
	Method() string
	// Desc returns the long form of the error code (for example ERROR_CHECKSUM).
	Desc() string
	// Exception returns the java exception class name (for example
	// java.io.FileNotFoundException).
	Exception() string
	// Message returns the full error message, complete with java exception
	// traceback.
	Message() string
}

func interpretException(err error) error {
	var exception string
	if remoteErr, ok := err.(Error); ok {
		exception = remoteErr.Exception()
	}

	switch exception {
	case fileNotFoundException:
		return os.ErrNotExist
	case permissionDeniedException:
		return os.ErrPermission
	case pathIsNotEmptyDirException:
		return syscall.ENOTEMPTY
	default:
		return err
	}
}
<commit_msg>Add support for file already Exists exception<commit_after>package hdfs

import (
	"os"
	"syscall"
)

const (
	fileNotFoundException      = "java.io.FileNotFoundException"
	permissionDeniedException  = "org.apache.hadoop.security.AccessControlException"
	pathIsNotEmptyDirException = "org.apache.hadoop.fs.PathIsNotEmptyDirectoryException"
	FileAlreadyExistsException = "org.apache.hadoop.fs.FileAlreadyExistsException"
)

// Error represents a remote java exception from an HDFS namenode or datanode.
type Error interface {
	// Method returns the RPC method that encountered an error.
	Method() string
	// Desc returns the long form of the error code (for example ERROR_CHECKSUM).
	Desc() string
	// Exception returns the java exception class name (for example
	// java.io.FileNotFoundException).
	Exception() string
	// Message returns the full error message, complete with java exception
	// traceback.
	Message() string
}

func interpretException(err error) error {
	var exception string
	if remoteErr, ok := err.(Error); ok {
		exception = remoteErr.Exception()
	}

	switch exception {
	case fileNotFoundException:
		return os.ErrNotExist
	case permissionDeniedException:
		return os.ErrPermission
	case pathIsNotEmptyDirException:
		return syscall.ENOTEMPTY
	case FileAlreadyExistsException:
		return os.ErrExist
	default:
		return err
	}
}
<|endoftext|>


<commit_before>package glfw3

//#include "glfw/include/GLFW/glfw3.h"
//void glfwSetErrorCallbackCB();
import "C"

import (
	"fmt"
)

// ErrorCode corresponds to an error code.
type ErrorCode int

// Error codes.
const (
	NotInitialized     ErrorCode = C.GLFW_NOT_INITIALIZED     // GLFW has not been initialized.
	NoCurrentContext   ErrorCode = C.GLFW_NO_CURRENT_CONTEXT  // No context is current.
	InvalidEnum        ErrorCode = C.GLFW_INVALID_ENUM        // One of the enum parameters for the function was given an invalid enum.
	InvalidValue       ErrorCode = C.GLFW_INVALID_VALUE       // One of the parameters for the function was given an invalid value.
	OutOfMemory        ErrorCode = C.GLFW_OUT_OF_MEMORY       // A memory allocation failed.
	APIUnavailable     ErrorCode = C.GLFW_API_UNAVAILABLE     // GLFW could not find support for the requested client API on the system.
	VersionUnavailable ErrorCode = C.GLFW_VERSION_UNAVAILABLE // The requested client API version is not available.
	PlatformError      ErrorCode = C.GLFW_PLATFORM_ERROR      // A platform-specific error occurred that does not match any of the more specific categories.
	FormatUnavailable  ErrorCode = C.GLFW_FORMAT_UNAVAILABLE  // The clipboard did not contain data in the requested format.
)

// GlfwError holds error code and description.
type GLFWError struct {
	Code ErrorCode
	Desc string
}

// Note: There are many cryptic caveats to proper error handling here.
// See: https://github.com/go-gl/glfw3/pull/86

// Holds the value of the last error
var lastError = make(chan *GLFWError, 1)

//export goErrorCB
func goErrorCB(code C.int, desc *C.char) {
	flushErrors()
	err := &GLFWError{ErrorCode(code), C.GoString(desc)}
	select {
	case lastError <- err:
	default:
		fmt.Printf("GLFW: an uncaught error has occured: %d -> %s\n", err.Code, err.Desc)
		fmt.Println("GLFW: Please report this bug in the Go package immediately.")
	}
}

// Error prints the error code and description in a readable format.
func (e *GLFWError) Error() string {
	return fmt.Sprintf("Error %d: %s", e.Code, e.Desc)
}

// Set the glfw callback internally
func init() {
	C.glfwSetErrorCallbackCB()
}

// flushErrors is called by Terminate before it actually calls C.glfwTerminate,
// this ensures that any uncaught errors buffered in lastError are printed
// before the program exits.
func flushErrors() {
	select {
	case err := <-lastError:
		fmt.Printf("GLFW: an uncaught error has occured: %d -> %s\n", err.Code, err.Desc)
		fmt.Println("GLFW: Please report this bug in the Go package immediately.")
	default:
	}
}
<commit_msg>Fix typo "an uncaught.." -> "An uncaught..".<commit_after>package glfw3

//#include "glfw/include/GLFW/glfw3.h"
//void glfwSetErrorCallbackCB();
import "C"

import (
	"fmt"
)

// ErrorCode corresponds to an error code.
type ErrorCode int

// Error codes.
const (
	NotInitialized     ErrorCode = C.GLFW_NOT_INITIALIZED     // GLFW has not been initialized.
	NoCurrentContext   ErrorCode = C.GLFW_NO_CURRENT_CONTEXT  // No context is current.
	InvalidEnum        ErrorCode = C.GLFW_INVALID_ENUM        // One of the enum parameters for the function was given an invalid enum.
	InvalidValue       ErrorCode = C.GLFW_INVALID_VALUE       // One of the parameters for the function was given an invalid value.
	OutOfMemory        ErrorCode = C.GLFW_OUT_OF_MEMORY       // A memory allocation failed.
	APIUnavailable     ErrorCode = C.GLFW_API_UNAVAILABLE     // GLFW could not find support for the requested client API on the system.
	VersionUnavailable ErrorCode = C.GLFW_VERSION_UNAVAILABLE // The requested client API version is not available.
	PlatformError      ErrorCode = C.GLFW_PLATFORM_ERROR      // A platform-specific error occurred that does not match any of the more specific categories.
	FormatUnavailable  ErrorCode = C.GLFW_FORMAT_UNAVAILABLE  // The clipboard did not contain data in the requested format.
)

// GlfwError holds error code and description.
type GLFWError struct {
	Code ErrorCode
	Desc string
}

// Note: There are many cryptic caveats to proper error handling here.
// See: https://github.com/go-gl/glfw3/pull/86

// Holds the value of the last error
var lastError = make(chan *GLFWError, 1)

//export goErrorCB
func goErrorCB(code C.int, desc *C.char) {
	flushErrors()
	err := &GLFWError{ErrorCode(code), C.GoString(desc)}
	select {
	case lastError <- err:
	default:
		fmt.Printf("GLFW: An uncaught error has occured: %d -> %s\n", err.Code, err.Desc)
		fmt.Println("GLFW: Please report this bug in the Go package immediately.")
	}
}

// Error prints the error code and description in a readable format.
func (e *GLFWError) Error() string {
	return fmt.Sprintf("Error %d: %s", e.Code, e.Desc)
}

// Set the glfw callback internally
func init() {
	C.glfwSetErrorCallbackCB()
}

// flushErrors is called by Terminate before it actually calls C.glfwTerminate,
// this ensures that any uncaught errors buffered in lastError are printed
// before the program exits.
func flushErrors() {
	select {
	case err := <-lastError:
		fmt.Printf("GLFW: An uncaught error has occured: %d -> %s\n", err.Code, err.Desc)
		fmt.Println("GLFW: Please report this bug in the Go package immediately.")
	default:
	}
}
<|endoftext|>


<commit_before>package gcache

import (
	"strings"
)

const (
	// https://developers.google.com/drive/v3/web/handle-errors
	// 400
	reasonBadRequest            = "badRequest"
	reasonInvalidSharingRequest = "invalidSharingRequest"
	// 401
	reasonAuthError = "authError"
	// 403
	reasonDailyLimitExceeded          = "dailyLimitExceeded"
	reasonUserRateLimitExceeded       = "userRateLimitExceeded"
	reasonRateLimitExceeded           = "rateLimitExceeded"
	reasonSharingRateLimitExceeded    = "sharingRateLimitExceeded"
	reasonAppNotAuthorizedToFile      = "appNotAuthorizedToFile"
	reasonInsufficientFilePermissions = "insufficientFilePermissions"
	reasonDomainPolicy                = "domainPolicy"
	// 404
	reasonNotFound = "notFound"
	// 500
	reasonBackendError = "backendError"
)

var (
	errDeadlineExceeded      = []string{"Deadline exceeded"}
	errFileNotExportable     = []string{"fileNotExportable"}
	errInvalidSecurityTicket = []string{"invalid security ticket"}
	errServerError           = []string{
		"500 Internal Server Error",
		"502 Bad Gateway",
		"503 Service Unavailable",
		"504 Gateway Timeout",
	}
	errRateLimit = []string{
		reasonUserRateLimitExceeded,
		reasonRateLimitExceeded,
	}
)

// DriveFileDoesNotExistError is as HTTP response that is 40X HTTP status.
type DriveFileDoesNotExistError struct {
	message string
}

func (err DriveFileDoesNotExistError) Error() string {
	return err.message
}

// NewDriveFileDoesNotExistError returns a DriveFileDoesNotExistError.
func NewDriveFileDoesNotExistError() error {
	return &DriveFileDoesNotExistError{message: "drive: file does not exist"}
}

// IsInvalidSecurityTicket returns is whether it is "invalid security ticket" error or not.
func IsInvalidSecurityTicket(
	err error,
) bool {
	return containsErrorMessage(err, errInvalidSecurityTicket)
}

// IsDeadlineExceededError returns is whether it is "Deadline exceeded" error or not.
func IsDeadlineExceededError(
	err error,
) bool {
	return containsErrorMessage(err, errDeadlineExceeded)
}

// IsFileNotExportableError returns is whether it is "fileNotExportable" error or not.
func IsFileNotExportableError(
	err error,
) bool {
	return containsErrorMessage(err, errFileNotExportable)
}

// IsServerError returns is whether it is 50X server errors or not.
func IsServerError(
	err error,
) bool {
	return containsErrorMessage(err, errServerError)
}

// IsRateLimit returns is whether it is "userRateLimitExceeded" or "rateLimitExceeded" server errors or not.
func IsRateLimit(
	err error,
) bool {
	return containsErrorMessage(err, errRateLimit)
}

func containsErrorMessage(
	err error,
	messages []string,
) bool {
	if err == nil {
		return false
	}
	errorMessage := err.Error()
	for _, message := range messages {
		if strings.Contains(errorMessage, message) {
			return true
		}
	}
	return false
}
<commit_msg>add "context deadline exceeded" error<commit_after>package gcache

import (
	"strings"
)

const (
	// https://developers.google.com/drive/v3/web/handle-errors
	// 400
	reasonBadRequest            = "badRequest"
	reasonInvalidSharingRequest = "invalidSharingRequest"
	// 401
	reasonAuthError = "authError"
	// 403
	reasonDailyLimitExceeded          = "dailyLimitExceeded"
	reasonUserRateLimitExceeded       = "userRateLimitExceeded"
	reasonRateLimitExceeded           = "rateLimitExceeded"
	reasonSharingRateLimitExceeded    = "sharingRateLimitExceeded"
	reasonAppNotAuthorizedToFile      = "appNotAuthorizedToFile"
	reasonInsufficientFilePermissions = "insufficientFilePermissions"
	reasonDomainPolicy                = "domainPolicy"
	// 404
	reasonNotFound = "notFound"
	// 500
	reasonBackendError = "backendError"
)

var (
	errDeadlineExceeded = []string{
		"Deadline exceeded",
		"context deadline exceeded",
	}
	errFileNotExportable     = []string{"fileNotExportable"}
	errInvalidSecurityTicket = []string{"invalid security ticket"}
	errServerError           = []string{
		"500 Internal Server Error",
		"502 Bad Gateway",
		"503 Service Unavailable",
		"504 Gateway Timeout",
	}
	errRateLimit = []string{
		reasonUserRateLimitExceeded,
		reasonRateLimitExceeded,
	}
)

// DriveFileDoesNotExistError is as HTTP response that is 40X HTTP status.
type DriveFileDoesNotExistError struct {
	message string
}

func (err DriveFileDoesNotExistError) Error() string {
	return err.message
}

// NewDriveFileDoesNotExistError returns a DriveFileDoesNotExistError.
func NewDriveFileDoesNotExistError() error {
	return &DriveFileDoesNotExistError{message: "drive: file does not exist"}
}

// IsInvalidSecurityTicket returns is whether it is "invalid security ticket" error or not.
func IsInvalidSecurityTicket(
	err error,
) bool {
	return containsErrorMessage(err, errInvalidSecurityTicket)
}

// IsDeadlineExceededError returns is whether it is "Deadline exceeded" error or not.
func IsDeadlineExceededError(
	err error,
) bool {
	return containsErrorMessage(err, errDeadlineExceeded)
}

// IsFileNotExportableError returns is whether it is "fileNotExportable" error or not.
func IsFileNotExportableError(
	err error,
) bool {
	return containsErrorMessage(err, errFileNotExportable)
}

// IsServerError returns is whether it is 50X server errors or not.
func IsServerError(
	err error,
) bool {
	return containsErrorMessage(err, errServerError)
}

// IsRateLimit returns is whether it is "userRateLimitExceeded" or "rateLimitExceeded" server errors or not.
func IsRateLimit(
	err error,
) bool {
	return containsErrorMessage(err, errRateLimit)
}

func containsErrorMessage(
	err error,
	messages []string,
) bool {
	if err == nil {
		return false
	}
	errorMessage := err.Error()
	for _, message := range messages {
		if strings.Contains(errorMessage, message) {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package discordgo

import "fmt"

// EventHandler is an interface for Discord events.
type EventHandler interface {
	// Type returns the type of event this handler belongs to.
	Type() string

	// Handle is called whenever an event of Type() happens.
	// It is the recievers responsibility to type assert that the interface
	// is the expected struct.
	Handle(*Session, interface{})
}

// EventInterfaceProvider is an interface for providing empty interfaces for
// Discord events.
type EventInterfaceProvider interface {
	// Type is the type of event this handler belongs to.
	Type() string

	// New returns a new instance of the struct this event handler handles.
	// This is called once per event.
	// The struct is provided to all handlers of the same Type().
	New() interface{}
}

// interfaceEventType is the event handler type for interface{} events.
const interfaceEventType = "__INTERFACE__"

// interfaceEventHandler is an event handler for interface{} events.
type interfaceEventHandler func(*Session, interface{})

// Type returns the event type for interface{} events.
func (eh interfaceEventHandler) Type() string {
	return interfaceEventType
}

// Handle is the handler for an interface{} event.
func (eh interfaceEventHandler) Handle(s *Session, i interface{}) {
	eh(s, i)
}

var registeredInterfaceProviders = map[string]EventInterfaceProvider{}

// registerInterfaceProvider registers a provider so that DiscordGo can
// access it's New() method.
func registerInterfaceProvider(eh EventInterfaceProvider) error {
	if _, ok := registeredInterfaceProviders[eh.Type()]; ok {
		return fmt.Errorf("event %s already registered", eh.Type())
	}
	registeredInterfaceProviders[eh.Type()] = eh
	return nil
}

// eventHandlerInstance is a wrapper around an event handler, as functions
// cannot be compared directly.
type eventHandlerInstance struct {
	eventHandler EventHandler
}

// addEventHandler adds an event handler that will be fired anytime
// the Discord WSAPI matching eventHandler.Type() fires.
func (s *Session) addEventHandler(eventHandler EventHandler) func() {
	s.handlersMu.Lock()
	defer s.handlersMu.Unlock()

	if s.handlers == nil {
		s.handlers = map[string][]*eventHandlerInstance{}
	}

	ehi := &eventHandlerInstance{eventHandler}
	s.handlers[eventHandler.Type()] = append(s.handlers[eventHandler.Type()], ehi)

	return func() {
		s.removeEventHandlerInstance(eventHandler.Type(), ehi)
	}
}

// addEventHandler adds an event handler that will be fired the next time
// the Discord WSAPI matching eventHandler.Type() fires.
func (s *Session) addEventHandlerOnce(eventHandler EventHandler) func() {
	s.handlersMu.Lock()
	defer s.handlersMu.Unlock()

	if s.onceHandlers == nil {
		s.onceHandlers = map[string][]*eventHandlerInstance{}
	}

	ehi := &eventHandlerInstance{eventHandler}
	s.onceHandlers[eventHandler.Type()] = append(s.onceHandlers[eventHandler.Type()], ehi)

	return func() {
		s.removeEventHandlerInstance(eventHandler.Type(), ehi)
	}
}

// AddHandler allows you to add an event handler that will be fired anytime
// the Discord WSAPI event that matches the function fires.
// events.go contains all the Discord WSAPI events that can be fired.
// eg:
//     Session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
//     })
//
// or:
//     Session.AddHandler(func(s *discordgo.Session, m *discordgo.PresenceUpdate) {
//     })
// The return value of this method is a function, that when called will remove the
// event handler.
func (s *Session) AddHandler(handler interface{}) func() {
	eh := handlerForInterface(handler)

	if eh == nil {
		s.log(LogError, "Invalid handler type, handler will never be called")
		return func() {}
	}

	return s.addEventHandler(eh)
}

// AddHandlerOnce allows you to add an event handler that will be fired the next time
// the Discord WSAPI event that matches the function fires.
// See AddHandler for more details.
func (s *Session) AddHandlerOnce(handler interface{}) func() {
	eh := handlerForInterface(handler)

	if eh == nil {
		s.log(LogError, "Invalid handler type, handler will never be called")
		return func() {}
	}

	return s.addEventHandlerOnce(eh)
}

// removeEventHandler instance removes an event handler instance.
func (s *Session) removeEventHandlerInstance(t string, ehi *eventHandlerInstance) {
	s.handlersMu.Lock()
	defer s.handlersMu.Unlock()

	handlers := s.handlers[t]
	for i := range handlers {
		if handlers[i] == ehi {
			s.handlers[t] = append(handlers[:i], handlers[i+1:]...)
		}
	}

	onceHandlers := s.onceHandlers[t]
	for i := range onceHandlers {
		if onceHandlers[i] == ehi {
			s.onceHandlers[t] = append(onceHandlers[:i], handlers[i+1:]...)
		}
	}
}

// Handles calling permanent and once handlers for an event type.
func (s *Session) handle(t string, i interface{}) {
	for _, eh := range s.handlers[t] {
		go eh.eventHandler.Handle(s, i)
	}

	if len(s.onceHandlers[t]) > 0 {
		for _, eh := range s.onceHandlers[t] {
			go eh.eventHandler.Handle(s, i)
		}
		s.onceHandlers[t] = nil
	}
}

// Handles an event type by calling internal methods, firing handlers and firing the
// interface{} event.
func (s *Session) handleEvent(t string, i interface{}) {
	s.handlersMu.RLock()
	defer s.handlersMu.RUnlock()

	// All events are dispatched internally first.
	s.onInterface(i)

	// Then they are dispatched to anyone handling interface{} events.
	s.handle(interfaceEventType, i)

	// Finally they are dispatched to any typed handlers.
	s.handle(t, i)
}

// setGuildIds will set the GuildID on all the members of a guild.
// This is done as event data does not have it set.
func setGuildIds(g *Guild) {
	for _, c := range g.Channels {
		c.GuildID = g.ID
	}

	for _, m := range g.Members {
		m.GuildID = g.ID
	}

	for _, vs := range g.VoiceStates {
		vs.GuildID = g.ID
	}
}

// onInterface handles all internal events and routes them to the appropriate internal handler.
func (s *Session) onInterface(i interface{}) {
	switch t := i.(type) {
	case *Ready:
		for _, g := range t.Guilds {
			setGuildIds(g)
		}
		s.onReady(t)
	case *GuildCreate:
		setGuildIds(t.Guild)
	case *GuildUpdate:
		setGuildIds(t.Guild)
	case *Resumed:
		s.onResumed(t)
	case *VoiceServerUpdate:
		go s.onVoiceServerUpdate(t)
	case *VoiceStateUpdate:
		go s.onVoiceStateUpdate(t)
	}
	err := s.State.onInterface(s, i)
	if err != nil {
		s.log(LogError, "error dispatching internal event, %s", err)
	}
}

// onReady handles the ready event.
func (s *Session) onReady(r *Ready) {

	// Store the SessionID within the Session struct.
	s.sessionID = r.SessionID

	// Start the heartbeat to keep the connection alive.
	go s.heartbeat(s.wsConn, s.listening, r.HeartbeatInterval)
}

// onResumed handles the resumed event.
func (s *Session) onResumed(r *Resumed) {

	// Start the heartbeat to keep the connection alive.
	go s.heartbeat(s.wsConn, s.listening, r.HeartbeatInterval)
}
<commit_msg>Don't error if we're never going to use it.<commit_after>package discordgo

// EventHandler is an interface for Discord events.
type EventHandler interface {
	// Type returns the type of event this handler belongs to.
	Type() string

	// Handle is called whenever an event of Type() happens.
	// It is the recievers responsibility to type assert that the interface
	// is the expected struct.
	Handle(*Session, interface{})
}

// EventInterfaceProvider is an interface for providing empty interfaces for
// Discord events.
type EventInterfaceProvider interface {
	// Type is the type of event this handler belongs to.
	Type() string

	// New returns a new instance of the struct this event handler handles.
	// This is called once per event.
	// The struct is provided to all handlers of the same Type().
	New() interface{}
}

// interfaceEventType is the event handler type for interface{} events.
const interfaceEventType = "__INTERFACE__"

// interfaceEventHandler is an event handler for interface{} events.
type interfaceEventHandler func(*Session, interface{})

// Type returns the event type for interface{} events.
func (eh interfaceEventHandler) Type() string {
	return interfaceEventType
}

// Handle is the handler for an interface{} event.
func (eh interfaceEventHandler) Handle(s *Session, i interface{}) {
	eh(s, i)
}

var registeredInterfaceProviders = map[string]EventInterfaceProvider{}

// registerInterfaceProvider registers a provider so that DiscordGo can
// access it's New() method.
func registerInterfaceProvider(eh EventInterfaceProvider) {
	if _, ok := registeredInterfaceProviders[eh.Type()]; ok {
		return
		// XXX:
		// if we should error here, we need to do something with it.
		// fmt.Errorf("event %s already registered", eh.Type())
	}
	registeredInterfaceProviders[eh.Type()] = eh
	return
}

// eventHandlerInstance is a wrapper around an event handler, as functions
// cannot be compared directly.
type eventHandlerInstance struct {
	eventHandler EventHandler
}

// addEventHandler adds an event handler that will be fired anytime
// the Discord WSAPI matching eventHandler.Type() fires.
func (s *Session) addEventHandler(eventHandler EventHandler) func() {
	s.handlersMu.Lock()
	defer s.handlersMu.Unlock()

	if s.handlers == nil {
		s.handlers = map[string][]*eventHandlerInstance{}
	}

	ehi := &eventHandlerInstance{eventHandler}
	s.handlers[eventHandler.Type()] = append(s.handlers[eventHandler.Type()], ehi)

	return func() {
		s.removeEventHandlerInstance(eventHandler.Type(), ehi)
	}
}

// addEventHandler adds an event handler that will be fired the next time
// the Discord WSAPI matching eventHandler.Type() fires.
func (s *Session) addEventHandlerOnce(eventHandler EventHandler) func() {
	s.handlersMu.Lock()
	defer s.handlersMu.Unlock()

	if s.onceHandlers == nil {
		s.onceHandlers = map[string][]*eventHandlerInstance{}
	}

	ehi := &eventHandlerInstance{eventHandler}
	s.onceHandlers[eventHandler.Type()] = append(s.onceHandlers[eventHandler.Type()], ehi)

	return func() {
		s.removeEventHandlerInstance(eventHandler.Type(), ehi)
	}
}

// AddHandler allows you to add an event handler that will be fired anytime
// the Discord WSAPI event that matches the function fires.
// events.go contains all the Discord WSAPI events that can be fired.
// eg:
//     Session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
//     })
//
// or:
//     Session.AddHandler(func(s *discordgo.Session, m *discordgo.PresenceUpdate) {
//     })
// The return value of this method is a function, that when called will remove the
// event handler.
func (s *Session) AddHandler(handler interface{}) func() {
	eh := handlerForInterface(handler)

	if eh == nil {
		s.log(LogError, "Invalid handler type, handler will never be called")
		return func() {}
	}

	return s.addEventHandler(eh)
}

// AddHandlerOnce allows you to add an event handler that will be fired the next time
// the Discord WSAPI event that matches the function fires.
// See AddHandler for more details.
func (s *Session) AddHandlerOnce(handler interface{}) func() {
	eh := handlerForInterface(handler)

	if eh == nil {
		s.log(LogError, "Invalid handler type, handler will never be called")
		return func() {}
	}

	return s.addEventHandlerOnce(eh)
}

// removeEventHandler instance removes an event handler instance.
func (s *Session) removeEventHandlerInstance(t string, ehi *eventHandlerInstance) {
	s.handlersMu.Lock()
	defer s.handlersMu.Unlock()

	handlers := s.handlers[t]
	for i := range handlers {
		if handlers[i] == ehi {
			s.handlers[t] = append(handlers[:i], handlers[i+1:]...)
		}
	}

	onceHandlers := s.onceHandlers[t]
	for i := range onceHandlers {
		if onceHandlers[i] == ehi {
			s.onceHandlers[t] = append(onceHandlers[:i], handlers[i+1:]...)
		}
	}
}

// Handles calling permanent and once handlers for an event type.
func (s *Session) handle(t string, i interface{}) {
	for _, eh := range s.handlers[t] {
		go eh.eventHandler.Handle(s, i)
	}

	if len(s.onceHandlers[t]) > 0 {
		for _, eh := range s.onceHandlers[t] {
			go eh.eventHandler.Handle(s, i)
		}
		s.onceHandlers[t] = nil
	}
}

// Handles an event type by calling internal methods, firing handlers and firing the
// interface{} event.
func (s *Session) handleEvent(t string, i interface{}) {
	s.handlersMu.RLock()
	defer s.handlersMu.RUnlock()

	// All events are dispatched internally first.
	s.onInterface(i)

	// Then they are dispatched to anyone handling interface{} events.
	s.handle(interfaceEventType, i)

	// Finally they are dispatched to any typed handlers.
	s.handle(t, i)
}

// setGuildIds will set the GuildID on all the members of a guild.
// This is done as event data does not have it set.
func setGuildIds(g *Guild) {
	for _, c := range g.Channels {
		c.GuildID = g.ID
	}

	for _, m := range g.Members {
		m.GuildID = g.ID
	}

	for _, vs := range g.VoiceStates {
		vs.GuildID = g.ID
	}
}

// onInterface handles all internal events and routes them to the appropriate internal handler.
func (s *Session) onInterface(i interface{}) {
	switch t := i.(type) {
	case *Ready:
		for _, g := range t.Guilds {
			setGuildIds(g)
		}
		s.onReady(t)
	case *GuildCreate:
		setGuildIds(t.Guild)
	case *GuildUpdate:
		setGuildIds(t.Guild)
	case *Resumed:
		s.onResumed(t)
	case *VoiceServerUpdate:
		go s.onVoiceServerUpdate(t)
	case *VoiceStateUpdate:
		go s.onVoiceStateUpdate(t)
	}
	err := s.State.onInterface(s, i)
	if err != nil {
		s.log(LogError, "error dispatching internal event, %s", err)
	}
}

// onReady handles the ready event.
func (s *Session) onReady(r *Ready) {

	// Store the SessionID within the Session struct.
	s.sessionID = r.SessionID

	// Start the heartbeat to keep the connection alive.
	go s.heartbeat(s.wsConn, s.listening, r.HeartbeatInterval)
}

// onResumed handles the resumed event.
func (s *Session) onResumed(r *Resumed) {

	// Start the heartbeat to keep the connection alive.
	go s.heartbeat(s.wsConn, s.listening, r.HeartbeatInterval)
}
<|endoftext|>


<commit_before>// Licensed to The Moov Authors under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. The Moov Authors licenses this file to you 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 ach

import (
	"fmt"
	"testing"
)

func TestValidators__checkDigit(t *testing.T) {
	cases := map[string]int{
		// invalid
		"":         -1,
		"123456":   -1,
		"1a8ab":    -1,
		"0730002a": -1,
		"0730A002": -1,
		// valid
		"07300022": 8, // Wells Fargo - Iowa
		"10200007": 6, // Wells Fargo - Colorado
	}

	v := validator{}
	for rtn, check := range cases {
		answer := v.CalculateCheckDigit(rtn)
		if check != answer {
			t.Errorf("input=%s answer=%d expected=%d", rtn, answer, check)
		}
		if err := CheckRoutingNumber(fmt.Sprintf("%s%d", rtn, check)); err != nil && check >= 0 {
			t.Errorf("input=%s answer=%d expected=%d: %v", rtn, answer, check, err)
		}
	}
}

func TestValidators__isCreditCardYear(t *testing.T) {
	cases := map[string]bool{
		// invalid (or out of range)
		"10": false,
		"00": false,
		"51": false,
		"17": false,
		// valid
		"20": true,
		"19": true,
	}
	v := validator{}
	for yy, valid := range cases {
		err := v.isCreditCardYear(yy)
		if valid && err != nil {
			t.Errorf("yy=%s failed: %v", yy, err)
		}
		if !valid && err == nil {
			t.Errorf("yy=%s should have failed", yy)
		}
	}
}

func TestValidators__validateSimpleDate(t *testing.T) {
	cases := map[string]string{
		// invalid
		"":       "",
		"01":     "",
		"001520": "", // no 15th month
		"001240": "", // no 40th Day
		"190001": "", // no 0th month
		"190100": "", // no 0th day
		// valid
		"190101": "190101", // Jan 1st
		"201231": "201231", // Dec 31st
		"220731": "220731", // July 31st
		"350430": "350430", // April 30th
		"500229": "500229", // Feb 29th
	}

	v := validator{}
	for input, expected := range cases {
		answer := v.validateSimpleDate(input)
		if expected != answer {
			t.Errorf("input=%q got=%q expected=%q", input, answer, expected)
		}
	}
}

func TestValidators__validateSimpleTime(t *testing.T) {
	cases := map[string]string{
		// invalid
		"":       "",
		"01":     "",
		"012":    "",
		"123142": "",
		// valid
		"0000": "0000",
		"0100": "0100",
		"2359": "2359",
		"1201": "1201",
		"1238": "1238",
	}
	v := validator{}
	for input, expected := range cases {
		answer := v.validateSimpleTime(input)
		if expected != answer {
			t.Errorf("input=%q got=%q expected=%q", input, answer, expected)
		}
	}
}
<commit_msg>validators: ensure alpha routing number check digit is invalid<commit_after>// Licensed to The Moov Authors under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. The Moov Authors licenses this file to you 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 ach

import (
	"fmt"
	"testing"
)

func TestValidators__checkDigit(t *testing.T) {
	cases := map[string]int{
		// invalid
		"":          -1,
		"123456":    -1,
		"1a8ab":     -1,
		"0730002a":  -1,
		"0730A002":  -1,
		"YYYYYYYYY": -1, // users often mask ABA numbers
		// valid
		"07300022": 8, // Wells Fargo - Iowa
		"10200007": 6, // Wells Fargo - Colorado
	}

	v := validator{}
	for rtn, check := range cases {
		answer := v.CalculateCheckDigit(rtn)
		if check != answer {
			t.Errorf("input=%s answer=%d expected=%d", rtn, answer, check)
		}
		if err := CheckRoutingNumber(fmt.Sprintf("%s%d", rtn, check)); err != nil && check >= 0 {
			t.Errorf("input=%s answer=%d expected=%d: %v", rtn, answer, check, err)
		}
	}
}

func TestValidators__isCreditCardYear(t *testing.T) {
	cases := map[string]bool{
		// invalid (or out of range)
		"10": false,
		"00": false,
		"51": false,
		"17": false,
		// valid
		"20": true,
		"19": true,
	}
	v := validator{}
	for yy, valid := range cases {
		err := v.isCreditCardYear(yy)
		if valid && err != nil {
			t.Errorf("yy=%s failed: %v", yy, err)
		}
		if !valid && err == nil {
			t.Errorf("yy=%s should have failed", yy)
		}
	}
}

func TestValidators__validateSimpleDate(t *testing.T) {
	cases := map[string]string{
		// invalid
		"":       "",
		"01":     "",
		"001520": "", // no 15th month
		"001240": "", // no 40th Day
		"190001": "", // no 0th month
		"190100": "", // no 0th day
		// valid
		"190101": "190101", // Jan 1st
		"201231": "201231", // Dec 31st
		"220731": "220731", // July 31st
		"350430": "350430", // April 30th
		"500229": "500229", // Feb 29th
	}

	v := validator{}
	for input, expected := range cases {
		answer := v.validateSimpleDate(input)
		if expected != answer {
			t.Errorf("input=%q got=%q expected=%q", input, answer, expected)
		}
	}
}

func TestValidators__validateSimpleTime(t *testing.T) {
	cases := map[string]string{
		// invalid
		"":       "",
		"01":     "",
		"012":    "",
		"123142": "",
		// valid
		"0000": "0000",
		"0100": "0100",
		"2359": "2359",
		"1201": "1201",
		"1238": "1238",
	}
	v := validator{}
	for input, expected := range cases {
		answer := v.validateSimpleTime(input)
		if expected != answer {
			t.Errorf("input=%q got=%q expected=%q", input, answer, expected)
		}
	}
}
<|endoftext|>


<commit_before>package types

type TPoint struct {
	X, Y int32
}

type TRect struct {
	Left, Top, Right, Bottom int32
}

type TSize struct {
	Cx, Cy int32
}

type HWND = uintptr

type HBITMAP = uintptr

type HMENU = uintptr

type HICON = uintptr

type HDC = uintptr

type HFONT = uintptr

type HBRUSH = uintptr

type HPEN = uintptr

type HKEY = uintptr

type HMONITOR = uintptr

type HGDIOBJ = uintptr

type HMODULE = uintptr

type COLORREF = uint32

type DWORD = uint32

type HCURSOR = HICON

type HINST = uintptr

type LPCWSTR = uintptr

type HRGN = uintptr

type UINT = uint32

type LPARAM = uintptr

type WAPRAM = uintptr

type LRESULT = uintptr

type HResult = uintptr

type HPALETTE = uintptr

type HRSRC = uintptr

type HGLOBAL = uintptr

type TFNWndEnumProc = uintptr

type TXID = uint64

//----------------------------------------------------------------------------------------------------------------------
// -- TRect

func (r *TRect) PtInRect(P TPoint) bool {
	return P.X >= r.Left && P.X < r.Right && P.Y >= r.Top && P.Y < r.Bottom
}

func (r *TRect) Width() int32 {
	return r.Right - r.Left
}

func (r *TRect) SetWidth(val int32) {
	r.Right = r.Left + val
}

func (r *TRect) Height() int32 {
	return r.Bottom - r.Top
}

func (r *TRect) SetHeight(val int32) {
	r.Bottom = r.Top + val
}

func (r *TRect) IsEmpty() bool {
	return r.Right <= r.Left || r.Bottom <= r.Top
}

func (r *TRect) Empty() {
	r.Left = 0
	r.Top = 0
	r.Right = 0
	r.Bottom = 0
}

func (r *TRect) Size() TSize {
	s := TSize{r.Width(), r.Height()}
	return s
}

func (r *TRect) SetSize(w, h int32) {
	r.SetWidth(w)
	r.SetHeight(h)
}

func (r *TRect) Inflate(dx, dy int32) {
	r.Left += -dx
	r.Top += -dy
	r.Right += dx
	r.Bottom += dy
}

func (r *TRect) Contains(aR TRect) bool {
	return r.Left <= aR.Left && r.Right >= aR.Right && r.Top <= aR.Top && r.Bottom >= aR.Bottom
}

func (r *TRect) IntersectsWith(aR TRect) bool {
	return r.Left < aR.Right && r.Right > aR.Left && r.Top < aR.Bottom && r.Bottom > aR.Top
}

func (r *TRect) CenterPoint() (ret TPoint) {
	ret.X = (r.Right-r.Left)/2 + r.Left
	ret.Y = (r.Bottom-r.Top)/2 + r.Top
	return
}

func (r *TRect) Scale(val float64) {
	r.Left = int32(float64(r.Left) * val)
	r.Top = int32(float64(r.Top) * val)
	r.Right = int32(float64(r.Right) * val)
	r.Bottom = int32(float64(r.Bottom) * val)
}

func (r *TRect) Scale2(val int) {
	r.Scale(float64(val))
}

// -- TPoint

func (p *TPoint) IsZero() bool {
	return p.X == 0 && p.Y == 0
}

func (p *TPoint) Offset(dx, dy int32) {
	p.X += dx
	p.Y += dy
}

func (p *TPoint) Scale(val float64) {
	p.X = int32(float64(p.X) * val)
	p.Y = int32(float64(p.Y) * val)
}

func (p *TPoint) Scale2(val int) {
	p.Scale(float64(val))
}

// TMsg: Only Windows,  tagMSG
type TMsg struct {
	Hwnd    HWND
	Message uint32
	WParam  uintptr
	LParam  uintptr
	Time    uint32
	Pt      TPoint
}

// TCursorInfo
type TCursorInfo struct {
	CbSize      uint32
	Flags       uint32
	HCursor     HCURSOR
	PtScreenPos TPoint
}

// TWndClass
type TWndClass struct {
	Style         uint32
	LpfnWndProc   uintptr
	CbClsExtra    int32
	CbWndExtra    int32
	HInstance     uintptr
	HIcon         HICON
	HCursor       HCURSOR
	HbrBackground HBRUSH
	LpszMenuName  LPCWSTR
	LpszClassName LPCWSTR
}

// TGestureEventInfo
type TGestureEventInfo struct {
	GestureID     TGestureID
	Location      TPoint
	Flags         TInteractiveGestureFlags
	Angle         float64
	InertiaVector TSmallPoint
	//case Integer of
	//	0: (Distance: Integer);
	//	1: (TapLocation: TSmallPoint);
	//	end;
	TapLocation TSmallPoint
}
<commit_msg>types包添加ATOM和TAtom类型。<commit_after>package types

type TPoint struct {
	X, Y int32
}

type TRect struct {
	Left, Top, Right, Bottom int32
}

type TSize struct {
	Cx, Cy int32
}

type HWND = uintptr

type HBITMAP = uintptr

type HMENU = uintptr

type HICON = uintptr

type HDC = uintptr

type HFONT = uintptr

type HBRUSH = uintptr

type HPEN = uintptr

type HKEY = uintptr

type HMONITOR = uintptr

type HGDIOBJ = uintptr

type HMODULE = uintptr

type COLORREF = uint32

type DWORD = uint32

type HCURSOR = HICON

type HINST = uintptr

type LPCWSTR = uintptr

type HRGN = uintptr

type UINT = uint32

type LPARAM = uintptr

type WAPRAM = uintptr

type LRESULT = uintptr

type HResult = uintptr

type HPALETTE = uintptr

type HRSRC = uintptr

type HGLOBAL = uintptr

type TFNWndEnumProc = uintptr

type TXID = uint64

type ATOM = uint16

type TAtom = uint16

//----------------------------------------------------------------------------------------------------------------------
// -- TRect

func (r *TRect) PtInRect(P TPoint) bool {
	return P.X >= r.Left && P.X < r.Right && P.Y >= r.Top && P.Y < r.Bottom
}

func (r *TRect) Width() int32 {
	return r.Right - r.Left
}

func (r *TRect) SetWidth(val int32) {
	r.Right = r.Left + val
}

func (r *TRect) Height() int32 {
	return r.Bottom - r.Top
}

func (r *TRect) SetHeight(val int32) {
	r.Bottom = r.Top + val
}

func (r *TRect) IsEmpty() bool {
	return r.Right <= r.Left || r.Bottom <= r.Top
}

func (r *TRect) Empty() {
	r.Left = 0
	r.Top = 0
	r.Right = 0
	r.Bottom = 0
}

func (r *TRect) Size() TSize {
	s := TSize{r.Width(), r.Height()}
	return s
}

func (r *TRect) SetSize(w, h int32) {
	r.SetWidth(w)
	r.SetHeight(h)
}

func (r *TRect) Inflate(dx, dy int32) {
	r.Left += -dx
	r.Top += -dy
	r.Right += dx
	r.Bottom += dy
}

func (r *TRect) Contains(aR TRect) bool {
	return r.Left <= aR.Left && r.Right >= aR.Right && r.Top <= aR.Top && r.Bottom >= aR.Bottom
}

func (r *TRect) IntersectsWith(aR TRect) bool {
	return r.Left < aR.Right && r.Right > aR.Left && r.Top < aR.Bottom && r.Bottom > aR.Top
}

func (r *TRect) CenterPoint() (ret TPoint) {
	ret.X = (r.Right-r.Left)/2 + r.Left
	ret.Y = (r.Bottom-r.Top)/2 + r.Top
	return
}

func (r *TRect) Scale(val float64) {
	r.Left = int32(float64(r.Left) * val)
	r.Top = int32(float64(r.Top) * val)
	r.Right = int32(float64(r.Right) * val)
	r.Bottom = int32(float64(r.Bottom) * val)
}

func (r *TRect) Scale2(val int) {
	r.Scale(float64(val))
}

// -- TPoint

func (p *TPoint) IsZero() bool {
	return p.X == 0 && p.Y == 0
}

func (p *TPoint) Offset(dx, dy int32) {
	p.X += dx
	p.Y += dy
}

func (p *TPoint) Scale(val float64) {
	p.X = int32(float64(p.X) * val)
	p.Y = int32(float64(p.Y) * val)
}

func (p *TPoint) Scale2(val int) {
	p.Scale(float64(val))
}

// TMsg: Only Windows,  tagMSG
type TMsg struct {
	Hwnd    HWND
	Message uint32
	WParam  uintptr
	LParam  uintptr
	Time    uint32
	Pt      TPoint
}

// TCursorInfo
type TCursorInfo struct {
	CbSize      uint32
	Flags       uint32
	HCursor     HCURSOR
	PtScreenPos TPoint
}

// TWndClass
type TWndClass struct {
	Style         uint32
	LpfnWndProc   uintptr
	CbClsExtra    int32
	CbWndExtra    int32
	HInstance     uintptr
	HIcon         HICON
	HCursor       HCURSOR
	HbrBackground HBRUSH
	LpszMenuName  LPCWSTR
	LpszClassName LPCWSTR
}

// TGestureEventInfo
type TGestureEventInfo struct {
	GestureID     TGestureID
	Location      TPoint
	Flags         TInteractiveGestureFlags
	Angle         float64
	InertiaVector TSmallPoint
	//case Integer of
	//	0: (Distance: Integer);
	//	1: (TapLocation: TSmallPoint);
	//	end;
	TapLocation TSmallPoint
}
<|endoftext|>


<commit_before>package api_test

import (
	"archive/zip"
	"cf"
	. "cf/api"
	"cf/configuration"
	"cf/models"
	"cf/net"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"runtime"
	"path/filepath"
	"sort"
	testconfig "testhelpers/configuration"
	testnet "testhelpers/net"
)

var _ = Describe("BuildpackBitsRepository", func() {
	var (
		buildpacksDir string
		configRepo    configuration.Repository
		repo          CloudControllerBuildpackBitsRepository
		buildpack     models.Buildpack
	)

	BeforeEach(func() {
		gateway := net.NewCloudControllerGateway()
		pwd, _ := os.Getwd()

		buildpacksDir = filepath.Join(pwd, "../../fixtures/buildpacks")
		configRepo = testconfig.NewRepositoryWithDefaults()
		repo = NewCloudControllerBuildpackBitsRepository(configRepo, gateway, cf.ApplicationZipper{})
		buildpack = models.Buildpack{Name: "my-cool-buildpack", Guid: "my-cool-buildpack-guid"}
	})

	Describe("#UploadBuildpack", func() {
		It("fails to upload a buildpack with an invalid directory", func() {
			apiResponse := repo.UploadBuildpack(buildpack, "/foo/bar")
			Expect(apiResponse.IsNotSuccessful()).To(BeTrue())
			Expect(apiResponse.Message).To(ContainSubstring("Error opening buildpack file"))
		})

		It("uploads a valid buildpack directory", func() {
			buildpackPath := filepath.Join(buildpacksDir, "example-buildpack")

			os.Chmod(filepath.Join(buildpackPath, "bin/compile"), 0755)
			os.Chmod(filepath.Join(buildpackPath, "bin/detect"), 0755)
			err := os.Chmod(filepath.Join(buildpackPath, "bin/release"), 0755)
			Expect(err).NotTo(HaveOccurred())

			ts, handler := testnet.NewTLSServer([]testnet.TestRequest{
				uploadBuildpackRequest(buildpackPath),
			})
			defer ts.Close()
			configRepo.SetApiEndpoint(ts.URL)

			apiResponse := repo.UploadBuildpack(buildpack, buildpackPath)
			Expect(handler.AllRequestsCalled()).To(BeTrue())
			Expect(apiResponse.IsSuccessful()).To(BeTrue())
		})

		It("uploads a valid zipped buildpack", func() {
			buildpackPath := filepath.Join(buildpacksDir, "example-buildpack.zip")

			ts, handler := testnet.NewTLSServer([]testnet.TestRequest{
				uploadBuildpackRequest(buildpackPath),
			})
			defer ts.Close()

			configRepo.SetApiEndpoint(ts.URL)

			apiResponse := repo.UploadBuildpack(buildpack, buildpackPath)
			Expect(handler.AllRequestsCalled()).To(BeTrue())
			Expect(apiResponse.IsSuccessful()).To(BeTrue())
		})

		Describe("when the buildpack is wrapped in an extra top-level directory", func() {
			It("uploads a zip file containing only the actual buildpack", func() {
				buildpackPath := filepath.Join(buildpacksDir, "example-buildpack-in-dir.zip")

				ts, handler := testnet.NewTLSServer([]testnet.TestRequest{
					uploadBuildpackRequest(buildpackPath),
				})
				defer ts.Close()

				configRepo.SetApiEndpoint(ts.URL)

				apiResponse := repo.UploadBuildpack(buildpack, buildpackPath)
				Expect(handler.AllRequestsCalled()).To(BeTrue())
				Expect(apiResponse.IsSuccessful()).To(BeTrue())
			})
		})

		Describe("when given the URL of a buildpack", func() {
			var handler *testnet.TestHandler
			var apiServer *httptest.Server

			BeforeEach(func() {
				apiServer, handler = testnet.NewTLSServer([]testnet.TestRequest{
					uploadBuildpackRequest("example-buildpack.zip"),
				})
				configRepo.SetApiEndpoint(apiServer.URL)
			})

			AfterEach(func() {
				apiServer.Close()
			})

			var buildpackFileServerHandler = func(buildpackName string) http.HandlerFunc {
				return func(writer http.ResponseWriter, request *http.Request) {
					Expect(request.URL.Path).To(Equal("/place/example-buildpack.zip"))
					f, err := os.Open(filepath.Join(buildpacksDir, buildpackName))
					Expect(err).NotTo(HaveOccurred())
					io.Copy(writer, f)
				}
			}

			It("uploads the file over HTTP", func() {
				fileServer := httptest.NewServer(buildpackFileServerHandler("example-buildpack.zip"))
				defer fileServer.Close()

				apiResponse := repo.UploadBuildpack(buildpack, fileServer.URL+"/place/example-buildpack.zip")
				Expect(handler.AllRequestsCalled()).To(BeTrue())
				Expect(apiResponse.IsSuccessful()).To(BeTrue())
			})

			It("uploads the file over HTTPS", func() {
				fileServer := httptest.NewTLSServer(buildpackFileServerHandler("example-buildpack.zip"))
				defer fileServer.Close()

				apiResponse := repo.UploadBuildpack(buildpack, fileServer.URL+"/place/example-buildpack.zip")
				Expect(handler.AllRequestsCalled()).To(BeTrue())
				Expect(apiResponse.IsSuccessful()).To(BeTrue())
			})

			Describe("when the buildpack is wrapped in an extra top-level directory", func() {
				It("uploads a zip file containing only the actual buildpack", func() {
					fileServer := httptest.NewTLSServer(buildpackFileServerHandler("example-buildpack-in-dir.zip"))
					defer fileServer.Close()

					apiResponse := repo.UploadBuildpack(buildpack, fileServer.URL+"/place/example-buildpack.zip")
					Expect(handler.AllRequestsCalled()).To(BeTrue())
					Expect(apiResponse.IsSuccessful()).To(BeTrue())
				})
			})

			It("returns an unsuccessful response when the server cannot be reached", func() {
				apiResponse := repo.UploadBuildpack(buildpack, "https://domain.bad-domain:223453/no-place/example-buildpack.zip")
				Expect(handler.AllRequestsCalled()).To(BeFalse())
				Expect(apiResponse.IsSuccessful()).To(BeFalse())
			})
		})
	})
})

func uploadBuildpackRequest(filename string) testnet.TestRequest {
	return testnet.TestRequest{
		Method: "PUT",
		Path:   "/v2/buildpacks/my-cool-buildpack-guid/bits",
		Response: testnet.TestResponse{
			Status: http.StatusCreated,
			Body:   `{ "metadata":{ "guid": "my-job-guid" } }`,
		},
		Matcher: func(request *http.Request) {
			err := request.ParseMultipartForm(4096)
			defer request.MultipartForm.RemoveAll()
			Expect(err).NotTo(HaveOccurred())

			Expect(len(request.MultipartForm.Value)).To(Equal(0))
			Expect(len(request.MultipartForm.File)).To(Equal(1))

			files, ok := request.MultipartForm.File["buildpack"]
			Expect(ok).To(BeTrue(), "Buildpack file part not present")
			Expect(len(files)).To(Equal(1), "Wrong number of files")

			buildpackFile := files[0]
			Expect(buildpackFile.Filename).To(Equal(filepath.Base(filename)), "Wrong file name")

			file, err := buildpackFile.Open()
			Expect(err).NotTo(HaveOccurred())

			zipReader, err := zip.NewReader(file, 4096)
			Expect(err).NotTo(HaveOccurred())

			actualFileNames := []string{}
			actualFileContents := []string{}
			for _, f := range zipReader.File {
				actualFileNames = append(actualFileNames, f.Name)
				c, _ := f.Open()
				content, _ := ioutil.ReadAll(c)
				actualFileContents = append(actualFileContents, string(content))
			}
			sort.Strings(actualFileNames)

			Expect(actualFileNames).To(Equal([]string{
				"bin/compile",
				"bin/detect",
				"bin/release",
				"lib/helper",
			}))
			Expect(actualFileContents).To(Equal([]string{
				"the-compile-script\n",
				"the-detect-script\n",
				"the-release-script\n",
				"the-helper-script\n",
			}))

			if runtime.GOOS != "windows" {
				Expect(zipReader.File[0].Mode()).To(Equal(os.FileMode(0755)))
				Expect(zipReader.File[1].Mode()).To(Equal(os.FileMode(0755)))
				Expect(zipReader.File[2].Mode()).To(Equal(os.FileMode(0755)))
			}
		},
	}
}
<commit_msg>go fmt<commit_after>package api_test

import (
	"archive/zip"
	"cf"
	. "cf/api"
	"cf/configuration"
	"cf/models"
	"cf/net"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"runtime"
	"sort"
	testconfig "testhelpers/configuration"
	testnet "testhelpers/net"
)

var _ = Describe("BuildpackBitsRepository", func() {
	var (
		buildpacksDir string
		configRepo    configuration.Repository
		repo          CloudControllerBuildpackBitsRepository
		buildpack     models.Buildpack
	)

	BeforeEach(func() {
		gateway := net.NewCloudControllerGateway()
		pwd, _ := os.Getwd()

		buildpacksDir = filepath.Join(pwd, "../../fixtures/buildpacks")
		configRepo = testconfig.NewRepositoryWithDefaults()
		repo = NewCloudControllerBuildpackBitsRepository(configRepo, gateway, cf.ApplicationZipper{})
		buildpack = models.Buildpack{Name: "my-cool-buildpack", Guid: "my-cool-buildpack-guid"}
	})

	Describe("#UploadBuildpack", func() {
		It("fails to upload a buildpack with an invalid directory", func() {
			apiResponse := repo.UploadBuildpack(buildpack, "/foo/bar")
			Expect(apiResponse.IsNotSuccessful()).To(BeTrue())
			Expect(apiResponse.Message).To(ContainSubstring("Error opening buildpack file"))
		})

		It("uploads a valid buildpack directory", func() {
			buildpackPath := filepath.Join(buildpacksDir, "example-buildpack")

			os.Chmod(filepath.Join(buildpackPath, "bin/compile"), 0755)
			os.Chmod(filepath.Join(buildpackPath, "bin/detect"), 0755)
			err := os.Chmod(filepath.Join(buildpackPath, "bin/release"), 0755)
			Expect(err).NotTo(HaveOccurred())

			ts, handler := testnet.NewTLSServer([]testnet.TestRequest{
				uploadBuildpackRequest(buildpackPath),
			})
			defer ts.Close()
			configRepo.SetApiEndpoint(ts.URL)

			apiResponse := repo.UploadBuildpack(buildpack, buildpackPath)
			Expect(handler.AllRequestsCalled()).To(BeTrue())
			Expect(apiResponse.IsSuccessful()).To(BeTrue())
		})

		It("uploads a valid zipped buildpack", func() {
			buildpackPath := filepath.Join(buildpacksDir, "example-buildpack.zip")

			ts, handler := testnet.NewTLSServer([]testnet.TestRequest{
				uploadBuildpackRequest(buildpackPath),
			})
			defer ts.Close()

			configRepo.SetApiEndpoint(ts.URL)

			apiResponse := repo.UploadBuildpack(buildpack, buildpackPath)
			Expect(handler.AllRequestsCalled()).To(BeTrue())
			Expect(apiResponse.IsSuccessful()).To(BeTrue())
		})

		Describe("when the buildpack is wrapped in an extra top-level directory", func() {
			It("uploads a zip file containing only the actual buildpack", func() {
				buildpackPath := filepath.Join(buildpacksDir, "example-buildpack-in-dir.zip")

				ts, handler := testnet.NewTLSServer([]testnet.TestRequest{
					uploadBuildpackRequest(buildpackPath),
				})
				defer ts.Close()

				configRepo.SetApiEndpoint(ts.URL)

				apiResponse := repo.UploadBuildpack(buildpack, buildpackPath)
				Expect(handler.AllRequestsCalled()).To(BeTrue())
				Expect(apiResponse.IsSuccessful()).To(BeTrue())
			})
		})

		Describe("when given the URL of a buildpack", func() {
			var handler *testnet.TestHandler
			var apiServer *httptest.Server

			BeforeEach(func() {
				apiServer, handler = testnet.NewTLSServer([]testnet.TestRequest{
					uploadBuildpackRequest("example-buildpack.zip"),
				})
				configRepo.SetApiEndpoint(apiServer.URL)
			})

			AfterEach(func() {
				apiServer.Close()
			})

			var buildpackFileServerHandler = func(buildpackName string) http.HandlerFunc {
				return func(writer http.ResponseWriter, request *http.Request) {
					Expect(request.URL.Path).To(Equal("/place/example-buildpack.zip"))
					f, err := os.Open(filepath.Join(buildpacksDir, buildpackName))
					Expect(err).NotTo(HaveOccurred())
					io.Copy(writer, f)
				}
			}

			It("uploads the file over HTTP", func() {
				fileServer := httptest.NewServer(buildpackFileServerHandler("example-buildpack.zip"))
				defer fileServer.Close()

				apiResponse := repo.UploadBuildpack(buildpack, fileServer.URL+"/place/example-buildpack.zip")
				Expect(handler.AllRequestsCalled()).To(BeTrue())
				Expect(apiResponse.IsSuccessful()).To(BeTrue())
			})

			It("uploads the file over HTTPS", func() {
				fileServer := httptest.NewTLSServer(buildpackFileServerHandler("example-buildpack.zip"))
				defer fileServer.Close()

				apiResponse := repo.UploadBuildpack(buildpack, fileServer.URL+"/place/example-buildpack.zip")
				Expect(handler.AllRequestsCalled()).To(BeTrue())
				Expect(apiResponse.IsSuccessful()).To(BeTrue())
			})

			Describe("when the buildpack is wrapped in an extra top-level directory", func() {
				It("uploads a zip file containing only the actual buildpack", func() {
					fileServer := httptest.NewTLSServer(buildpackFileServerHandler("example-buildpack-in-dir.zip"))
					defer fileServer.Close()

					apiResponse := repo.UploadBuildpack(buildpack, fileServer.URL+"/place/example-buildpack.zip")
					Expect(handler.AllRequestsCalled()).To(BeTrue())
					Expect(apiResponse.IsSuccessful()).To(BeTrue())
				})
			})

			It("returns an unsuccessful response when the server cannot be reached", func() {
				apiResponse := repo.UploadBuildpack(buildpack, "https://domain.bad-domain:223453/no-place/example-buildpack.zip")
				Expect(handler.AllRequestsCalled()).To(BeFalse())
				Expect(apiResponse.IsSuccessful()).To(BeFalse())
			})
		})
	})
})

func uploadBuildpackRequest(filename string) testnet.TestRequest {
	return testnet.TestRequest{
		Method: "PUT",
		Path:   "/v2/buildpacks/my-cool-buildpack-guid/bits",
		Response: testnet.TestResponse{
			Status: http.StatusCreated,
			Body:   `{ "metadata":{ "guid": "my-job-guid" } }`,
		},
		Matcher: func(request *http.Request) {
			err := request.ParseMultipartForm(4096)
			defer request.MultipartForm.RemoveAll()
			Expect(err).NotTo(HaveOccurred())

			Expect(len(request.MultipartForm.Value)).To(Equal(0))
			Expect(len(request.MultipartForm.File)).To(Equal(1))

			files, ok := request.MultipartForm.File["buildpack"]
			Expect(ok).To(BeTrue(), "Buildpack file part not present")
			Expect(len(files)).To(Equal(1), "Wrong number of files")

			buildpackFile := files[0]
			Expect(buildpackFile.Filename).To(Equal(filepath.Base(filename)), "Wrong file name")

			file, err := buildpackFile.Open()
			Expect(err).NotTo(HaveOccurred())

			zipReader, err := zip.NewReader(file, 4096)
			Expect(err).NotTo(HaveOccurred())

			actualFileNames := []string{}
			actualFileContents := []string{}
			for _, f := range zipReader.File {
				actualFileNames = append(actualFileNames, f.Name)
				c, _ := f.Open()
				content, _ := ioutil.ReadAll(c)
				actualFileContents = append(actualFileContents, string(content))
			}
			sort.Strings(actualFileNames)

			Expect(actualFileNames).To(Equal([]string{
				"bin/compile",
				"bin/detect",
				"bin/release",
				"lib/helper",
			}))
			Expect(actualFileContents).To(Equal([]string{
				"the-compile-script\n",
				"the-detect-script\n",
				"the-release-script\n",
				"the-helper-script\n",
			}))

			if runtime.GOOS != "windows" {
				Expect(zipReader.File[0].Mode()).To(Equal(os.FileMode(0755)))
				Expect(zipReader.File[1].Mode()).To(Equal(os.FileMode(0755)))
				Expect(zipReader.File[2].Mode()).To(Equal(os.FileMode(0755)))
			}
		},
	}
}
<|endoftext|>


<commit_before>package action_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	. "github.com/maximilien/bosh-softlayer-cpi/action"

	boshlog "github.com/cloudfoundry/bosh-utils/logger"

	fakecmd "github.com/cloudfoundry/bosh-agent/platform/commands/fakes"
	fakesys "github.com/cloudfoundry/bosh-utils/system/fakes"

	fakeslclient "github.com/maximilien/softlayer-go/client/fakes"

	bslcdisk "github.com/maximilien/bosh-softlayer-cpi/softlayer/disk"
	bslcstem "github.com/maximilien/bosh-softlayer-cpi/softlayer/stemcell"
	bslcvm "github.com/maximilien/bosh-softlayer-cpi/softlayer/vm"
)

var _ = Describe("concreteFactory", func() {
	var (
		softLayerClient *fakeslclient.FakeSoftLayerClient
		fs              *fakesys.FakeFileSystem
		cmdRunner       *fakesys.FakeCmdRunner
		compressor      *fakecmd.FakeCompressor
		logger          boshlog.Logger

		options = ConcreteFactoryOptions{
			StemcellsDir: "/tmp/stemcells",
		}

		factory Factory
	)

	var (
		agentEnvServiceFactory bslcvm.AgentEnvServiceFactory

		stemcellFinder bslcstem.Finder
		vmFinder       bslcvm.Finder
	)

	BeforeEach(func() {
		softLayerClient = fakeslclient.NewFakeSoftLayerClient("fake-username", "fake-api-key")
		fs = fakesys.NewFakeFileSystem()
		cmdRunner = fakesys.NewFakeCmdRunner()
		compressor = fakecmd.NewFakeCompressor()
		logger = boshlog.NewLogger(boshlog.LevelNone)

		factory = NewConcreteFactory(
			softLayerClient,
			options,
			logger,
		)
	})

	BeforeEach(func() {
		agentEnvServiceFactory = bslcvm.NewSoftLayerAgentEnvServiceFactory(softLayerClient, logger)

		stemcellFinder = bslcstem.NewSoftLayerFinder(softLayerClient, logger)

		vmFinder = bslcvm.NewSoftLayerFinder(
			softLayerClient,
			agentEnvServiceFactory,
			logger,
		)
	})

	Context("Stemcell methods", func() {
		It("create_stemcell", func() {
			action, err := factory.Create("create_stemcell")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewCreateStemcell(stemcellFinder)))
		})

		It("delete_stemcell", func() {
			action, err := factory.Create("delete_stemcell")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewDeleteStemcell(stemcellFinder)))
		})
	})

	Context("VM methods", func() {
		It("create_vm", func() {
			vmCreator := bslcvm.NewSoftLayerCreator(
				softLayerClient,
				agentEnvServiceFactory,
				options.Agent,
				logger,
			)

			action, err := factory.Create("create_vm")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewCreateVM(stemcellFinder, vmCreator)))
		})

		It("delete_vm", func() {
			action, err := factory.Create("delete_vm")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewDeleteVM(vmFinder)))
		})

		It("has_vm", func() {
			action, err := factory.Create("has_vm")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewHasVM(vmFinder)))
		})

		It("reboot_vm", func() {
			action, err := factory.Create("reboot_vm")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewRebootVM(vmFinder)))
		})

		It("set_vm_metadata", func() {
			action, err := factory.Create("set_vm_metadata")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewSetVMMetadata(vmFinder)))
		})

		It("configure_networks", func() {
			action, err := factory.Create("configure_networks")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewConfigureNetworks(vmFinder)))
		})
	})

	Context("Disk methods", func() {
		var (
			vmFinder    bslcvm.Finder
			diskFinder  bslcdisk.Finder
			diskCreator bslcdisk.Creator
		)

		BeforeEach(func() {
			vmFinder = bslcvm.NewSoftLayerFinder(
				softLayerClient,
				agentEnvServiceFactory,
				logger,
			)
			diskFinder = bslcdisk.NewSoftLayerDiskFinder(
				softLayerClient,
				logger,
			)
			diskCreator = bslcdisk.NewSoftLayerDiskCreator(
				softLayerClient,
				logger,
			)
		})

		It("creates an iSCSI disk", func() {
			action, err := factory.Create("create_disk")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewCreateDisk(diskCreator)))
		})

		It("deletes the detached iSCSI disk", func() {
			action, err := factory.Create("delete_disk")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewDeleteDisk(diskFinder)))
		})

		It("attaches an iSCSI disk to a virtual guest", func() {
			action, err := factory.Create("attach_disk")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewAttachDisk(vmFinder, diskFinder)))
		})

		It("detaches the iSCSI disk from virtual guest", func() {
			action, err := factory.Create("detach_disk")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewDetachDisk(vmFinder, diskFinder)))
		})
	})

	Context("Unsupported methods", func() {
		It("returns error because CPI machine is not self-aware if action is current_vm_id", func() {
			action, err := factory.Create("current_vm_id")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})

		It("returns error because snapshotting is not implemented if action is snapshot_disk", func() {
			action, err := factory.Create("snapshot_disk")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})

		It("returns error because snapshotting is not implemented if action is delete_snapshot", func() {
			action, err := factory.Create("delete_snapshot")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})

		It("returns error since CPI should not keep state if action is get_disks", func() {
			action, err := factory.Create("get_disks")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})

		It("returns error because ping is not official CPI method if action is ping", func() {
			action, err := factory.Create("ping")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})
	})

	Context("Misc", func() {
		It("returns error if action cannot be created", func() {
			action, err := factory.Create("fake-unknown-action")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})
	})
})
<commit_msg>fixed dependencies for action test<commit_after>package action_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	. "github.com/maximilien/bosh-softlayer-cpi/action"

	boshlog "github.com/cloudfoundry/bosh-utils/logger"

	fakecmd "github.com/cloudfoundry/bosh-agent/internal/github.com/cloudfoundry/bosh-utils/fileutil/fakes"
	fakesys "github.com/cloudfoundry/bosh-utils/system/fakes"

	fakeslclient "github.com/maximilien/softlayer-go/client/fakes"

	bslcdisk "github.com/maximilien/bosh-softlayer-cpi/softlayer/disk"
	bslcstem "github.com/maximilien/bosh-softlayer-cpi/softlayer/stemcell"
	bslcvm "github.com/maximilien/bosh-softlayer-cpi/softlayer/vm"
)

var _ = Describe("concreteFactory", func() {
	var (
		softLayerClient *fakeslclient.FakeSoftLayerClient
		fs              *fakesys.FakeFileSystem
		cmdRunner       *fakesys.FakeCmdRunner
		compressor      *fakecmd.FakeCompressor
		logger          boshlog.Logger

		options = ConcreteFactoryOptions{
			StemcellsDir: "/tmp/stemcells",
		}

		factory Factory
	)

	var (
		agentEnvServiceFactory bslcvm.AgentEnvServiceFactory

		stemcellFinder bslcstem.Finder
		vmFinder       bslcvm.Finder
	)

	BeforeEach(func() {
		softLayerClient = fakeslclient.NewFakeSoftLayerClient("fake-username", "fake-api-key")
		fs = fakesys.NewFakeFileSystem()
		cmdRunner = fakesys.NewFakeCmdRunner()
		compressor = fakecmd.NewFakeCompressor()
		logger = boshlog.NewLogger(boshlog.LevelNone)

		factory = NewConcreteFactory(
			softLayerClient,
			options,
			logger,
		)
	})

	BeforeEach(func() {
		agentEnvServiceFactory = bslcvm.NewSoftLayerAgentEnvServiceFactory(softLayerClient, logger)

		stemcellFinder = bslcstem.NewSoftLayerFinder(softLayerClient, logger)

		vmFinder = bslcvm.NewSoftLayerFinder(
			softLayerClient,
			agentEnvServiceFactory,
			logger,
		)
	})

	Context("Stemcell methods", func() {
		It("create_stemcell", func() {
			action, err := factory.Create("create_stemcell")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewCreateStemcell(stemcellFinder)))
		})

		It("delete_stemcell", func() {
			action, err := factory.Create("delete_stemcell")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewDeleteStemcell(stemcellFinder)))
		})
	})

	Context("VM methods", func() {
		It("create_vm", func() {
			vmCreator := bslcvm.NewSoftLayerCreator(
				softLayerClient,
				agentEnvServiceFactory,
				options.Agent,
				logger,
			)

			action, err := factory.Create("create_vm")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewCreateVM(stemcellFinder, vmCreator)))
		})

		It("delete_vm", func() {
			action, err := factory.Create("delete_vm")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewDeleteVM(vmFinder)))
		})

		It("has_vm", func() {
			action, err := factory.Create("has_vm")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewHasVM(vmFinder)))
		})

		It("reboot_vm", func() {
			action, err := factory.Create("reboot_vm")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewRebootVM(vmFinder)))
		})

		It("set_vm_metadata", func() {
			action, err := factory.Create("set_vm_metadata")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewSetVMMetadata(vmFinder)))
		})

		It("configure_networks", func() {
			action, err := factory.Create("configure_networks")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewConfigureNetworks(vmFinder)))
		})
	})

	Context("Disk methods", func() {
		var (
			vmFinder    bslcvm.Finder
			diskFinder  bslcdisk.Finder
			diskCreator bslcdisk.Creator
		)

		BeforeEach(func() {
			vmFinder = bslcvm.NewSoftLayerFinder(
				softLayerClient,
				agentEnvServiceFactory,
				logger,
			)
			diskFinder = bslcdisk.NewSoftLayerDiskFinder(
				softLayerClient,
				logger,
			)
			diskCreator = bslcdisk.NewSoftLayerDiskCreator(
				softLayerClient,
				logger,
			)
		})

		It("creates an iSCSI disk", func() {
			action, err := factory.Create("create_disk")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewCreateDisk(diskCreator)))
		})

		It("deletes the detached iSCSI disk", func() {
			action, err := factory.Create("delete_disk")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewDeleteDisk(diskFinder)))
		})

		It("attaches an iSCSI disk to a virtual guest", func() {
			action, err := factory.Create("attach_disk")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewAttachDisk(vmFinder, diskFinder)))
		})

		It("detaches the iSCSI disk from virtual guest", func() {
			action, err := factory.Create("detach_disk")
			Expect(err).ToNot(HaveOccurred())
			Expect(action).To(Equal(NewDetachDisk(vmFinder, diskFinder)))
		})
	})

	Context("Unsupported methods", func() {
		It("returns error because CPI machine is not self-aware if action is current_vm_id", func() {
			action, err := factory.Create("current_vm_id")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})

		It("returns error because snapshotting is not implemented if action is snapshot_disk", func() {
			action, err := factory.Create("snapshot_disk")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})

		It("returns error because snapshotting is not implemented if action is delete_snapshot", func() {
			action, err := factory.Create("delete_snapshot")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})

		It("returns error since CPI should not keep state if action is get_disks", func() {
			action, err := factory.Create("get_disks")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})

		It("returns error because ping is not official CPI method if action is ping", func() {
			action, err := factory.Create("ping")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})
	})

	Context("Misc", func() {
		It("returns error if action cannot be created", func() {
			action, err := factory.Create("fake-unknown-action")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})
	})
})
<|endoftext|>