<commit_before>// +build !partialPush

package isolated

import (
	"os/exec"
	"strings"

	"code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/ginkgo/extensions/table"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("help command", func() {
	DescribeTable("displays help for common commands",
		func(setup func() *exec.Cmd) {
			cmd := setup()
			session, err := Start(cmd, GinkgoWriter, GinkgoWriter)
			Expect(err).NotTo(HaveOccurred())

			Eventually(session).Should(Say("Cloud Foundry command line tool"))
			Eventually(session).Should(Say(`\[global options\] command \[arguments...\] \[command options\]`))
			Eventually(session).Should(Say("Before getting started:"))
			Eventually(session).Should(Say(`  config\s+login,l\s+target,t`))
			Eventually(session).Should(Say("Application lifecycle:"))
			Eventually(session).Should(Say(`  apps,a\s+run-task,rt\s+events`))
			Eventually(session).Should(Say(`  restage,rg\s+scale`))

			Eventually(session).Should(Say("Services integration:"))
			Eventually(session).Should(Say(`  marketplace,m\s+create-user-provided-service,cups`))
			Eventually(session).Should(Say(`  services,s\s+update-user-provided-service,uups`))

			Eventually(session).Should(Say("Route and domain management:"))
			Eventually(session).Should(Say(`  routes,r\s+delete-route\s+create-domain`))
			Eventually(session).Should(Say(`  domains\s+map-route`))

			Eventually(session).Should(Say("Space management:"))
			Eventually(session).Should(Say(`  spaces\s+create-space\s+set-space-role`))

			Eventually(session).Should(Say("Org management:"))
			Eventually(session).Should(Say(`  orgs,o\s+set-org-role`))

			Eventually(session).Should(Say("CLI plugin management:"))
			Eventually(session).Should(Say("  install-plugin    list-plugin-repos"))
			Eventually(session).Should(Say("Global options:"))
			Eventually(session).Should(Say("  --help, -h                         Show help"))
			Eventually(session).Should(Say("  -v                                 Print API request diagnostics to stdout"))

			Eventually(session).Should(Say(`Use 'cf help -a' to see all commands\.`))
			Eventually(session).Should(Exit(0))
		},

		Entry("when cf is run without providing a command or a flag", func() *exec.Cmd {
			return exec.Command("cf")
		}),

		Entry("when cf help is run", func() *exec.Cmd {
			return exec.Command("cf", "help")
		}),

		Entry("when cf is run with -h flag alone", func() *exec.Cmd {
			return exec.Command("cf", "-h")
		}),

		Entry("when cf is run with --help flag alone", func() *exec.Cmd {
			return exec.Command("cf", "--help")
		}),
	)

	DescribeTable("displays help for all commands",
		func(setup func() *exec.Cmd) {
			cmd := setup()
			session, err := Start(cmd, GinkgoWriter, GinkgoWriter)
			Expect(err).NotTo(HaveOccurred())

			Eventually(session).Should(Say("NAME:"))
			Eventually(session).Should(Say("USAGE:"))
			Eventually(session).Should(Say("VERSION:"))
			Eventually(session).Should(Say("GETTING STARTED:"))
			Eventually(session).Should(Say("ENVIRONMENT VARIABLES:"))
			Eventually(session).Should(Say(`CF_DIAL_TIMEOUT=5\s+Max wait time to establish a connection, including name resolution, in seconds`))
			Eventually(session).Should(Say("GLOBAL OPTIONS:"))
			Eventually(session).Should(Say(`APPS \(experimental\):`))
			Eventually(session).Should(Exit(0))
		},

		Entry("when cf help is run", func() *exec.Cmd {
			return exec.Command("cf", "help", "-a")
		}),

		Entry("when cf is run with -h -a flag", func() *exec.Cmd {
			return exec.Command("cf", "-h", "-a")
		}),

		Entry("when cf is run with --help -a flag", func() *exec.Cmd {
			return exec.Command("cf", "--help", "-a")
		}),
	)

	Describe("commands that appear in cf help -a", func() {
		It("includes run-task", func() {
			session := helpers.CF("help", "-a")
			Eventually(session).Should(Say(`run-task\s+Run a one-off task on an app`))
			Eventually(session).Should(Exit(0))
		})

		It("includes list-task", func() {
			session := helpers.CF("help", "-a")
			Eventually(session).Should(Say(`tasks\s+List tasks of an app`))
			Eventually(session).Should(Exit(0))
		})

		It("includes terminate-task", func() {
			session := helpers.CF("help", "-a")
			Eventually(session).Should(Say(`terminate-task\s+Terminate a running task of an app`))
			Eventually(session).Should(Exit(0))
		})
	})

	Context("displays the help text for a given command", func() {
		DescribeTable("displays the help",
			func(setup func() (*exec.Cmd, int)) {
				cmd, exitCode := setup()
				session, err := Start(cmd, GinkgoWriter, GinkgoWriter)
				Expect(err).NotTo(HaveOccurred())

				Eventually(session).Should(Say("NAME:"))
				Eventually(session).Should(Say("create-user-provided-service - Make a user-provided service instance available to CF apps"))
				Eventually(session).Should(Say(`cf create-user-provided-service SERVICE_INSTANCE \[-p CREDENTIALS\] \[-l SYSLOG_DRAIN_URL\] \[-r ROUTE_SERVICE_URL\]`))
				Eventually(session).Should(Say(`-l\s+URL to which logs for bound applications will be streamed`))
				Eventually(session).Should(Exit(exitCode))
			},

			Entry("when a command is called with the --help flag", func() (*exec.Cmd, int) {
				return exec.Command("cf", "create-user-provided-service", "--help"), 0
			}),

			Entry("when a command is called with the --help flag and command arguments", func() (*exec.Cmd, int) {
				return exec.Command("cf", "create-user-provided-service", "-l", "http://example.com", "--help"), 0
			}),

			Entry("when a command is called with the --help flag and command arguments prior to the command", func() (*exec.Cmd, int) {
				return exec.Command("cf", "-l", "create-user-provided-service", "--help"), 1
			}),

			Entry("when the help command is passed a command name", func() (*exec.Cmd, int) {
				return exec.Command("cf", "help", "create-user-provided-service"), 0
			}),

			Entry("when the --help flag is passed with a command name", func() (*exec.Cmd, int) {
				return exec.Command("cf", "--help", "create-user-provided-service"), 0
			}),

			Entry("when the -h flag is passed with a command name", func() (*exec.Cmd, int) {
				return exec.Command("cf", "-h", "create-user-provided-service"), 0
			}),

			Entry("when the help command is passed a command alias", func() (*exec.Cmd, int) {
				return exec.Command("cf", "help", "cups"), 0
			}),

			Entry("when the --help flag is passed with a command alias", func() (*exec.Cmd, int) {
				return exec.Command("cf", "--help", "cups"), 0
			}),

			Entry("when the --help flag is passed after a command alias", func() (*exec.Cmd, int) {
				return exec.Command("cf", "cups", "--help"), 0
			}),

			Entry("when an invalid flag is passed", func() (*exec.Cmd, int) {
				return exec.Command("cf", "create-user-provided-service", "--invalid-flag"), 1
			}),

			Entry("when missing required arguments", func() (*exec.Cmd, int) {
				return exec.Command("cf", "create-user-provided-service"), 1
			}),

			Entry("when missing arguments to flags", func() (*exec.Cmd, int) {
				return exec.Command("cf", "create-user-provided-service", "foo", "-l"), 1
			}),
		)

		When("the command uses timeout environment variables", func() {
			DescribeTable("shows the CF_STAGING_TIMEOUT and CF_STARTUP_TIMEOUT environment variables",
				func(setup func() (*exec.Cmd, int)) {
					cmd, exitCode := setup()
					session, err := Start(cmd, GinkgoWriter, GinkgoWriter)
					Expect(err).NotTo(HaveOccurred())

					Eventually(session).Should(Say(`
ENVIRONMENT:
   CF_STAGING_TIMEOUT=15        Max wait time for buildpack staging, in minutes
   CF_STARTUP_TIMEOUT=5         Max wait time for app instance startup, in minutes
`))
					Eventually(session).Should(Exit(exitCode))
				},

				Entry("cf push", func() (*exec.Cmd, int) {
					return exec.Command("cf", "h", "push"), 0
				}),

				Entry("cf start", func() (*exec.Cmd, int) {
					return exec.Command("cf", "h", "start"), 0
				}),

				Entry("cf restart", func() (*exec.Cmd, int) {
					return exec.Command("cf", "h", "restart"), 0
				}),

				Entry("cf restage", func() (*exec.Cmd, int) {
					return exec.Command("cf", "h", "restage"), 0
				}),

				Entry("cf copy-source", func() (*exec.Cmd, int) {
					return exec.Command("cf", "h", "copy-source"), 0
				}),
			)
		})
	})

	When("the command does not exist", func() {
		DescribeTable("help displays an error message",
			func(command func() *exec.Cmd) {
				session, err := Start(command(), GinkgoWriter, GinkgoWriter)
				Expect(err).NotTo(HaveOccurred())

				Eventually(session.Err).Should(Say("'rock' is not a registered command. See 'cf help -a'"))
				Eventually(session).Should(Exit(1))
			},

			Entry("passing the --help flag", func() *exec.Cmd {
				return exec.Command("cf", "--help", "rock")
			}),

			Entry("calling the help command directly", func() *exec.Cmd {
				return exec.Command("cf", "help", "rock")
			}),
		)

	})

	When("the option does not exist", func() {
		DescribeTable("help display an error message as well as help for common commands",

			func(command func() *exec.Cmd) {
				session, err := Start(command(), GinkgoWriter, GinkgoWriter)
				Expect(err).NotTo(HaveOccurred())

				Eventually(session).Should(Exit(1))
				Eventually(session).Should(Say("Before getting started:")) // common help
				Expect(strings.Count(string(session.Err.Contents()), "unknown flag")).To(Equal(1))
			},

			Entry("passing invalid option", func() *exec.Cmd {
				return exec.Command("cf", "-c")
			}),

			Entry("passing -a option", func() *exec.Cmd {
				return exec.Command("cf", "-a")
			}),
		)
	})
})
<commit_msg>separate environment help text checking into multiple lines<commit_after>package isolated

import (
	"os/exec"
	"strings"

	"code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/ginkgo/extensions/table"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("help command", func() {
	DescribeTable("displays help for common commands",
		func(setup func() *exec.Cmd) {
			cmd := setup()
			session, err := Start(cmd, GinkgoWriter, GinkgoWriter)
			Expect(err).NotTo(HaveOccurred())

			Eventually(session).Should(Say("Cloud Foundry command line tool"))
			Eventually(session).Should(Say(`\[global options\] command \[arguments...\] \[command options\]`))
			Eventually(session).Should(Say("Before getting started:"))
			Eventually(session).Should(Say(`  config\s+login,l\s+target,t`))
			Eventually(session).Should(Say("Application lifecycle:"))
			Eventually(session).Should(Say(`  apps,a\s+run-task,rt\s+events`))
			Eventually(session).Should(Say(`  restage,rg\s+scale`))

			Eventually(session).Should(Say("Services integration:"))
			Eventually(session).Should(Say(`  marketplace,m\s+create-user-provided-service,cups`))
			Eventually(session).Should(Say(`  services,s\s+update-user-provided-service,uups`))

			Eventually(session).Should(Say("Route and domain management:"))
			Eventually(session).Should(Say(`  routes,r\s+delete-route\s+create-domain`))
			Eventually(session).Should(Say(`  domains\s+map-route`))

			Eventually(session).Should(Say("Space management:"))
			Eventually(session).Should(Say(`  spaces\s+create-space\s+set-space-role`))

			Eventually(session).Should(Say("Org management:"))
			Eventually(session).Should(Say(`  orgs,o\s+set-org-role`))

			Eventually(session).Should(Say("CLI plugin management:"))
			Eventually(session).Should(Say("  install-plugin    list-plugin-repos"))
			Eventually(session).Should(Say("Global options:"))
			Eventually(session).Should(Say("  --help, -h                         Show help"))
			Eventually(session).Should(Say("  -v                                 Print API request diagnostics to stdout"))

			Eventually(session).Should(Say(`Use 'cf help -a' to see all commands\.`))
			Eventually(session).Should(Exit(0))
		},

		Entry("when cf is run without providing a command or a flag", func() *exec.Cmd {
			return exec.Command("cf")
		}),

		Entry("when cf help is run", func() *exec.Cmd {
			return exec.Command("cf", "help")
		}),

		Entry("when cf is run with -h flag alone", func() *exec.Cmd {
			return exec.Command("cf", "-h")
		}),

		Entry("when cf is run with --help flag alone", func() *exec.Cmd {
			return exec.Command("cf", "--help")
		}),
	)

	DescribeTable("displays help for all commands",
		func(setup func() *exec.Cmd) {
			cmd := setup()
			session, err := Start(cmd, GinkgoWriter, GinkgoWriter)
			Expect(err).NotTo(HaveOccurred())

			Eventually(session).Should(Say("NAME:"))
			Eventually(session).Should(Say("USAGE:"))
			Eventually(session).Should(Say("VERSION:"))
			Eventually(session).Should(Say("GETTING STARTED:"))
			Eventually(session).Should(Say("ENVIRONMENT VARIABLES:"))
			Eventually(session).Should(Say(`CF_DIAL_TIMEOUT=5\s+Max wait time to establish a connection, including name resolution, in seconds`))
			Eventually(session).Should(Say("GLOBAL OPTIONS:"))
			Eventually(session).Should(Say(`APPS \(experimental\):`))
			Eventually(session).Should(Exit(0))
		},

		Entry("when cf help is run", func() *exec.Cmd {
			return exec.Command("cf", "help", "-a")
		}),

		Entry("when cf is run with -h -a flag", func() *exec.Cmd {
			return exec.Command("cf", "-h", "-a")
		}),

		Entry("when cf is run with --help -a flag", func() *exec.Cmd {
			return exec.Command("cf", "--help", "-a")
		}),
	)

	Describe("commands that appear in cf help -a", func() {
		It("includes run-task", func() {
			session := helpers.CF("help", "-a")
			Eventually(session).Should(Say(`run-task\s+Run a one-off task on an app`))
			Eventually(session).Should(Exit(0))
		})

		It("includes list-task", func() {
			session := helpers.CF("help", "-a")
			Eventually(session).Should(Say(`tasks\s+List tasks of an app`))
			Eventually(session).Should(Exit(0))
		})

		It("includes terminate-task", func() {
			session := helpers.CF("help", "-a")
			Eventually(session).Should(Say(`terminate-task\s+Terminate a running task of an app`))
			Eventually(session).Should(Exit(0))
		})
	})

	Context("displays the help text for a given command", func() {
		DescribeTable("displays the help",
			func(setup func() (*exec.Cmd, int)) {
				cmd, exitCode := setup()
				session, err := Start(cmd, GinkgoWriter, GinkgoWriter)
				Expect(err).NotTo(HaveOccurred())

				Eventually(session).Should(Say("NAME:"))
				Eventually(session).Should(Say("create-user-provided-service - Make a user-provided service instance available to CF apps"))
				Eventually(session).Should(Say(`cf create-user-provided-service SERVICE_INSTANCE \[-p CREDENTIALS\] \[-l SYSLOG_DRAIN_URL\] \[-r ROUTE_SERVICE_URL\]`))
				Eventually(session).Should(Say(`-l\s+URL to which logs for bound applications will be streamed`))
				Eventually(session).Should(Exit(exitCode))
			},

			Entry("when a command is called with the --help flag", func() (*exec.Cmd, int) {
				return exec.Command("cf", "create-user-provided-service", "--help"), 0
			}),

			Entry("when a command is called with the --help flag and command arguments", func() (*exec.Cmd, int) {
				return exec.Command("cf", "create-user-provided-service", "-l", "http://example.com", "--help"), 0
			}),

			Entry("when a command is called with the --help flag and command arguments prior to the command", func() (*exec.Cmd, int) {
				return exec.Command("cf", "-l", "create-user-provided-service", "--help"), 1
			}),

			Entry("when the help command is passed a command name", func() (*exec.Cmd, int) {
				return exec.Command("cf", "help", "create-user-provided-service"), 0
			}),

			Entry("when the --help flag is passed with a command name", func() (*exec.Cmd, int) {
				return exec.Command("cf", "--help", "create-user-provided-service"), 0
			}),

			Entry("when the -h flag is passed with a command name", func() (*exec.Cmd, int) {
				return exec.Command("cf", "-h", "create-user-provided-service"), 0
			}),

			Entry("when the help command is passed a command alias", func() (*exec.Cmd, int) {
				return exec.Command("cf", "help", "cups"), 0
			}),

			Entry("when the --help flag is passed with a command alias", func() (*exec.Cmd, int) {
				return exec.Command("cf", "--help", "cups"), 0
			}),

			Entry("when the --help flag is passed after a command alias", func() (*exec.Cmd, int) {
				return exec.Command("cf", "cups", "--help"), 0
			}),

			Entry("when an invalid flag is passed", func() (*exec.Cmd, int) {
				return exec.Command("cf", "create-user-provided-service", "--invalid-flag"), 1
			}),

			Entry("when missing required arguments", func() (*exec.Cmd, int) {
				return exec.Command("cf", "create-user-provided-service"), 1
			}),

			Entry("when missing arguments to flags", func() (*exec.Cmd, int) {
				return exec.Command("cf", "create-user-provided-service", "foo", "-l"), 1
			}),
		)

		When("the command uses timeout environment variables", func() {
			DescribeTable("shows the CF_STAGING_TIMEOUT and CF_STARTUP_TIMEOUT environment variables",
				func(setup func() (*exec.Cmd, int)) {
					cmd, exitCode := setup()
					session, err := Start(cmd, GinkgoWriter, GinkgoWriter)
					Expect(err).NotTo(HaveOccurred())

					Eventually(session).Should(Say("ENVIRONMENT:"))
					Eventually(session).Should(Say("CF_STAGING_TIMEOUT=15\\s+Max wait time for buildpack staging, in minutes"))
					Eventually(session).Should(Say("CF_STARTUP_TIMEOUT=5\\s+Max wait time for app instance startup, in minutes"))
					Eventually(session).Should(Exit(exitCode))
				},

				Entry("cf push", func() (*exec.Cmd, int) {
					return exec.Command("cf", "h", "push"), 0
				}),

				Entry("cf start", func() (*exec.Cmd, int) {
					return exec.Command("cf", "h", "start"), 0
				}),

				Entry("cf restart", func() (*exec.Cmd, int) {
					return exec.Command("cf", "h", "restart"), 0
				}),

				Entry("cf restage", func() (*exec.Cmd, int) {
					return exec.Command("cf", "h", "restage"), 0
				}),

				Entry("cf copy-source", func() (*exec.Cmd, int) {
					return exec.Command("cf", "h", "copy-source"), 0
				}),
			)
		})
	})

	When("the command does not exist", func() {
		DescribeTable("help displays an error message",
			func(command func() *exec.Cmd) {
				session, err := Start(command(), GinkgoWriter, GinkgoWriter)
				Expect(err).NotTo(HaveOccurred())

				Eventually(session.Err).Should(Say("'rock' is not a registered command. See 'cf help -a'"))
				Eventually(session).Should(Exit(1))
			},

			Entry("passing the --help flag", func() *exec.Cmd {
				return exec.Command("cf", "--help", "rock")
			}),

			Entry("calling the help command directly", func() *exec.Cmd {
				return exec.Command("cf", "help", "rock")
			}),
		)

	})

	When("the option does not exist", func() {
		DescribeTable("help display an error message as well as help for common commands",

			func(command func() *exec.Cmd) {
				session, err := Start(command(), GinkgoWriter, GinkgoWriter)
				Expect(err).NotTo(HaveOccurred())

				Eventually(session).Should(Exit(1))
				Eventually(session).Should(Say("Before getting started:")) // common help
				Expect(strings.Count(string(session.Err.Contents()), "unknown flag")).To(Equal(1))
			},

			Entry("passing invalid option", func() *exec.Cmd {
				return exec.Command("cf", "-c")
			}),

			Entry("passing -a option", func() *exec.Cmd {
				return exec.Command("cf", "-a")
			}),
		)
	})
})
<|endoftext|>


<commit_before>// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.

// XML
package gxml

import (
    "github.com/clbanning/mxj"
)

// 将XML内容解析为map变量
func Decode(xmlbyte []byte) (map[string]interface{}, error) {
    return mxj.NewMapXml(xmlbyte)
}

// 将map变量解析为XML格式内容
func Encode(v map[string]interface{}, rootTag...string) ([]byte, error) {
    return mxj.Map(v).Xml(rootTag...)
}

func EncodeWithIndent(v map[string]interface{}, rootTag...string) ([]byte, error) {
    return mxj.Map(v).XmlIndent("", "\t", rootTag...)
}

// XML格式内容直接转换为JSON格式内容
func ToJson(xmlbyte []byte) ([]byte, error) {
    if mv, err := mxj.NewMapXml(xmlbyte); err == nil {
        return mv.Json()
    } else {
        return nil, err
    }
}<commit_msg>修复当xml中encoding字符集为非UTF-8字符集时报错的问题<commit_after>// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.

// XML
package gxml

import (
    "github.com/clbanning/mxj"
    "encoding/xml"
    "io"
)

// 将XML内容解析为map变量,入口参数使用的字符集必须为UTF-8的
func Decode(xmlbyte []byte) (map[string]interface{}, error) {
    //@author wenzi1
    //@date   2018-05-29
	//XML中的encoding如果非UTF-8时mxj包中会自动转换，但是自动转换时需要调用方提供转换的方法,这里提供一个空方法
	//所以如果涉及到字符集转换那么需要用户自行转为utf8时再调用该方法
    charsetReader := func(charset string, input io.Reader) (io.Reader, error) {
		return input, nil
	}
	mxj.CustomDecoder = &xml.Decoder{CharsetReader:charsetReader}
    return mxj.NewMapXml(xmlbyte)
}

// 将map变量解析为XML格式内容
func Encode(v map[string]interface{}, rootTag...string) ([]byte, error) {
    return mxj.Map(v).Xml(rootTag...)
}

func EncodeWithIndent(v map[string]interface{}, rootTag...string) ([]byte, error) {
    return mxj.Map(v).XmlIndent("", "\t", rootTag...)
}

// XML格式内容直接转换为JSON格式内容,入口参数使用的字符集必须为UTF-8的
func ToJson(xmlbyte []byte) ([]byte, error) {
    //@author wenzi1
    //@date   2018-05-29
	//XML中的encoding如果非UTF-8时mxj包中会自动转换，但是自动转换时需要调用方提供转换的方法,这里提供一个空方法
	//所以如果涉及到字符集转换那么需要用户自行转为utf8时再调用该方法
	charsetReader := func(charset string, input io.Reader) (io.Reader, error) {
		return input, nil
	}
	mxj.CustomDecoder = &xml.Decoder{CharsetReader:charsetReader}
    if mv, err := mxj.NewMapXml(xmlbyte); err == nil {
        return mv.Json()
    } else {
        return nil, err
    }
}<|endoftext|>


<commit_before>package beegoAssets

import (
	"html/template"

	"github.com/astaxie/beego"
)

func init() {
	err := logger.SetLogger("console", "")
	if err != nil {
		Error(err.Error())
	}
	err = beego.AddFuncMap("asset_js", getAssetHelper(AssetJavascript))
	if err != nil {
		Error(err.Error())
	}
	err = beego.AddFuncMap("asset_css", getAssetHelper(AssetStylesheet))
	if err != nil {
		Error(err.Error())
	}
	Config.extensions[AssetJavascript] = []string{".js"}
	Config.extensions[AssetStylesheet] = []string{".css"}

}
func getAssetHelper(Type assetsType) func(string) template.HTML {
	return func(asset_name string) template.HTML {
		asset, err := getAsset(asset_name, Type)
		if err != nil {
			logger.Error(err.Error())
			return ""
		}
		return asset.buildHTML()
	}
}
<commit_msg>fix leftover file<commit_after>package beegoAssets

import (
	"html/template"

	"github.com/beego/beego"
)

func init() {
	err := logger.SetLogger("console", "")
	if err != nil {
		Error(err.Error())
	}
	err = beego.AddFuncMap("asset_js", getAssetHelper(AssetJavascript))
	if err != nil {
		Error(err.Error())
	}
	err = beego.AddFuncMap("asset_css", getAssetHelper(AssetStylesheet))
	if err != nil {
		Error(err.Error())
	}
	Config.extensions[AssetJavascript] = []string{".js"}
	Config.extensions[AssetStylesheet] = []string{".css"}

}
func getAssetHelper(Type assetsType) func(string) template.HTML {
	return func(asset_name string) template.HTML {
		asset, err := getAsset(asset_name, Type)
		if err != nil {
			logger.Error(err.Error())
			return ""
		}
		return asset.buildHTML()
	}
}
<|endoftext|>


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

package generate

import "reflect"

// Return the string that should be used to refer to the supplied type within
// the given package.
//
// For example, a pointer to an io.Reader may be rendered as "*Reader" or
// "*io.Reader" depending on whether the package path is "io" or not.
func typeString(
	t reflect.Type,
	pkgPath string) (s string) {
	panic("TODO")
}
<commit_msg>Added a bad implementation.<commit_after>// Copyright 2015 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package generate

import "reflect"

// Return the string that should be used to refer to the supplied type within
// the given package.
//
// For example, a pointer to an io.Reader may be rendered as "*Reader" or
// "*io.Reader" depending on whether the package path is "io" or not.
func typeString(
	t reflect.Type,
	pkgPath string) (s string) {
	s = t.String()
	return
}
<|endoftext|>


<commit_before>package integration_test

import (
	"code.google.com/p/gogoprotobuf/proto"
	"fmt"
	"github.com/cloudfoundry/dropsonde/autowire"
	"github.com/cloudfoundry/dropsonde/autowire/metrics"
	"github.com/cloudfoundry/dropsonde/events"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"net"
	"net/http"
	"os"
	"sync"
)

// these tests need to be invoked individually from an external script,
// since environment variables need to be set/unset before starting the tests
var _ = Describe("Autowire End-to-End", func() {
	Context("with DROPSONDE_ORIGIN set", func() {
		var oldEnv string

		BeforeEach(func() {
			oldEnv = os.Getenv("DROPSONDE_ORIGIN")
			os.Setenv("DROPSONDE_ORIGIN", "test-origin")
			autowire.Initialize()
			metrics.Initialize()
		})

		AfterEach(func() {
			os.Setenv("DROPSONDE_ORIGIN", oldEnv)
		})

		It("emits HTTP client/server events and heartbeats", func() {
			udpListener, err := net.ListenPacket("udp4", ":42420")
			Expect(err).ToNot(HaveOccurred())
			defer udpListener.Close()
			udpDataChan := make(chan []byte, 16)

			receivedEvents := make(map[string]bool)
			lock := sync.RWMutex{}
			origin := os.Getenv("DROPSONDE_ORIGIN")

			go func() {
				defer close(udpDataChan)
				for {
					buffer := make([]byte, 1024)
					n, _, err := udpListener.ReadFrom(buffer)
					if err != nil {
						return
					}

					if n == 0 {
						panic("Received empty packet")
					}
					envelope := new(events.Envelope)
					err = proto.Unmarshal(buffer[0:n], envelope)
					if err != nil {
						panic(err)
					}

					var eventId = envelope.GetEventType().String()

					switch envelope.GetEventType() {
					case events.Envelope_HttpStart:
						eventId += envelope.GetHttpStart().GetPeerType().String()
					case events.Envelope_HttpStop:
						eventId += envelope.GetHttpStop().GetPeerType().String()
					case events.Envelope_Heartbeat:
					case events.Envelope_ValueMetric:
						eventId += envelope.GetValueMetric().GetName()
					case events.Envelope_CounterEvent:
						eventId += envelope.GetCounterEvent().GetName()
					default:
						panic("Unexpected message type")

					}

					if envelope.GetOrigin() != origin {
						panic("origin not as expected")
					}

					func() {
						lock.Lock()
						defer lock.Unlock()
						receivedEvents[eventId] = true
					}()
				}
			}()

			httpListener, err := net.Listen("tcp", "localhost:0")
			Expect(err).ToNot(HaveOccurred())
			defer httpListener.Close()
			httpHandler := autowire.InstrumentedHandler(FakeHandler{})
			go http.Serve(httpListener, httpHandler)

			_, err = http.Get("http://" + httpListener.Addr().String())
			Expect(err).ToNot(HaveOccurred())

			metrics.SendValue("TestMetric", 0, "")
			metrics.IncrementCounter("TestIncrementCounter")

			expectedEventTypes := []string{"HttpStartClient", "HttpStartServer", "HttpStopServer", "HttpStopClient", "ValueMetricnumCPUS", "ValueMetricTestMetric", "CounterEventTestIncrementCounter"}

			for _, eventType := range expectedEventTypes {
				Eventually(func() bool {
					lock.RLock()
					defer lock.RUnlock()
					_, ok := receivedEvents[eventType]
					return ok
				}).Should(BeTrue(), fmt.Sprintf("missing %s", eventType))
			}

			Eventually(func() bool {
				lock.RLock()
				defer lock.RUnlock()
				_, ok := receivedEvents["Heartbeat"]
				return ok
			}).Should(BeTrue())
		})
	})
})

type FakeHandler struct{}

func (fh FakeHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(rw, "Hello")
}

type FakeRoundTripper struct{}

func (frt FakeRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	return nil, nil
}
<commit_msg>Update autowire_end_to_end_test.go<commit_after>package integration_test

import (
	"code.google.com/p/gogoprotobuf/proto"
	"fmt"
	"github.com/cloudfoundry/dropsonde/autowire"
	"github.com/cloudfoundry/dropsonde/autowire/metrics"
	"github.com/cloudfoundry/dropsonde/events"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"net"
	"net/http"
	"os"
	"sync"
)

// these tests need to be invoked individually from an external script,
// since environment variables need to be set/unset before starting the tests
var _ = Describe("Autowire End-to-End", func() {
	Context("with DROPSONDE_ORIGIN set", func() {
		var oldEnv string

		BeforeEach(func() {
			oldEnv = os.Getenv("DROPSONDE_ORIGIN")
			os.Setenv("DROPSONDE_ORIGIN", "test-origin")
			autowire.Initialize()
			metrics.Initialize()
		})

		AfterEach(func() {
			os.Setenv("DROPSONDE_ORIGIN", oldEnv)
		})

		It("emits HTTP client/server events and heartbeats", func() {
			udpListener, err := net.ListenPacket("udp4", ":3457")
			Expect(err).ToNot(HaveOccurred())
			defer udpListener.Close()
			udpDataChan := make(chan []byte, 16)

			receivedEvents := make(map[string]bool)
			lock := sync.RWMutex{}
			origin := os.Getenv("DROPSONDE_ORIGIN")

			go func() {
				defer close(udpDataChan)
				for {
					buffer := make([]byte, 1024)
					n, _, err := udpListener.ReadFrom(buffer)
					if err != nil {
						return
					}

					if n == 0 {
						panic("Received empty packet")
					}
					envelope := new(events.Envelope)
					err = proto.Unmarshal(buffer[0:n], envelope)
					if err != nil {
						panic(err)
					}

					var eventId = envelope.GetEventType().String()

					switch envelope.GetEventType() {
					case events.Envelope_HttpStart:
						eventId += envelope.GetHttpStart().GetPeerType().String()
					case events.Envelope_HttpStop:
						eventId += envelope.GetHttpStop().GetPeerType().String()
					case events.Envelope_Heartbeat:
					case events.Envelope_ValueMetric:
						eventId += envelope.GetValueMetric().GetName()
					case events.Envelope_CounterEvent:
						eventId += envelope.GetCounterEvent().GetName()
					default:
						panic("Unexpected message type")

					}

					if envelope.GetOrigin() != origin {
						panic("origin not as expected")
					}

					func() {
						lock.Lock()
						defer lock.Unlock()
						receivedEvents[eventId] = true
					}()
				}
			}()

			httpListener, err := net.Listen("tcp", "localhost:0")
			Expect(err).ToNot(HaveOccurred())
			defer httpListener.Close()
			httpHandler := autowire.InstrumentedHandler(FakeHandler{})
			go http.Serve(httpListener, httpHandler)

			_, err = http.Get("http://" + httpListener.Addr().String())
			Expect(err).ToNot(HaveOccurred())

			metrics.SendValue("TestMetric", 0, "")
			metrics.IncrementCounter("TestIncrementCounter")

			expectedEventTypes := []string{"HttpStartClient", "HttpStartServer", "HttpStopServer", "HttpStopClient", "ValueMetricnumCPUS", "ValueMetricTestMetric", "CounterEventTestIncrementCounter"}

			for _, eventType := range expectedEventTypes {
				Eventually(func() bool {
					lock.RLock()
					defer lock.RUnlock()
					_, ok := receivedEvents[eventType]
					return ok
				}).Should(BeTrue(), fmt.Sprintf("missing %s", eventType))
			}

			Eventually(func() bool {
				lock.RLock()
				defer lock.RUnlock()
				_, ok := receivedEvents["Heartbeat"]
				return ok
			}).Should(BeTrue())
		})
	})
})

type FakeHandler struct{}

func (fh FakeHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(rw, "Hello")
}

type FakeRoundTripper struct{}

func (frt FakeRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	return nil, nil
}
<|endoftext|>


<commit_before>// Copyright 2020 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

package logstream_test

import (
	"context"
	"os"
	"path/filepath"
	"sync"
	"testing"

	"github.com/google/mtail/internal/logline"
	"github.com/google/mtail/internal/tailer/logstream"
	"github.com/google/mtail/internal/testutil"
	"github.com/google/mtail/internal/waker"
	"golang.org/x/sys/unix"
)

func TestPipeStreamReadCompletedBecauseClosed(t *testing.T) {
	var wg sync.WaitGroup

	tmpDir := testutil.TestTempDir(t)

	name := filepath.Join(tmpDir, "fifo")
	testutil.FatalIfErr(t, unix.Mkfifo(name, 0666))

	lines := make(chan *logline.LogLine, 1)
	ctx, cancel := context.WithCancel(context.Background())
	waker := waker.NewTestAlways()

	// In this and the following test, open RDWR so as to not block this thread
	// from proceeding.  If we open the logstream first, there is a race before
	// the write end opens that can sometimes lead to the logstream reading an
	// EOF (because the write end is not yet open) and the test fails.
	f, err := os.OpenFile(name, os.O_RDWR, os.ModeNamedPipe)
	testutil.FatalIfErr(t, err)

	ps, err := logstream.New(ctx, &wg, waker, name, lines, false)
	testutil.FatalIfErr(t, err)

	testutil.WriteString(t, f, "1\n")

	// Pipes need to be closed to signal to the pipeStream to finish up.
	testutil.FatalIfErr(t, f.Close())

	ps.Stop() // no-op for pipes
	wg.Wait()
	close(lines)

	received := testutil.LinesReceived(lines)
	expected := []*logline.LogLine{
		{context.TODO(), name, "1"},
	}
	testutil.ExpectNoDiff(t, expected, received, testutil.IgnoreFields(logline.LogLine{}, "Context"))

	cancel()

	if !ps.IsComplete() {
		t.Errorf("expecting pipestream to be complete because fifo closed")
	}
}

func TestPipeStreamReadCompletedBecauseCancel(t *testing.T) {
	var wg sync.WaitGroup

	tmpDir := testutil.TestTempDir(t)

	name := filepath.Join(tmpDir, "fifo")
	testutil.FatalIfErr(t, unix.Mkfifo(name, 0666))

	lines := make(chan *logline.LogLine, 1)
	ctx, cancel := context.WithCancel(context.Background())
	waker := waker.NewTestAlways()

	f, err := os.OpenFile(name, os.O_RDWR, os.ModeNamedPipe)
	testutil.FatalIfErr(t, err)

	ps, err := logstream.New(ctx, &wg, waker, name, lines, false)
	testutil.FatalIfErr(t, err)

	testutil.WriteString(t, f, "1\n")

	cancel()
	wg.Wait()
	close(lines)

	received := testutil.LinesReceived(lines)
	expected := []*logline.LogLine{
		{context.TODO(), name, "1"},
	}
	testutil.ExpectNoDiff(t, expected, received, testutil.IgnoreFields(logline.LogLine{}, "Context"))

	if !ps.IsComplete() {
		t.Errorf("expecting pipestream to be complete because cancelled")
	}
}
<commit_msg>Synchronise the pipestream test to avoid a race on cancel.<commit_after>// Copyright 2020 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

package logstream_test

import (
	"context"
	"os"
	"path/filepath"
	"sync"
	"testing"

	"github.com/google/mtail/internal/logline"
	"github.com/google/mtail/internal/tailer/logstream"
	"github.com/google/mtail/internal/testutil"
	"github.com/google/mtail/internal/waker"
	"golang.org/x/sys/unix"
)

func TestPipeStreamReadCompletedBecauseClosed(t *testing.T) {
	var wg sync.WaitGroup

	tmpDir := testutil.TestTempDir(t)

	name := filepath.Join(tmpDir, "fifo")
	testutil.FatalIfErr(t, unix.Mkfifo(name, 0666))

	lines := make(chan *logline.LogLine, 1)
	ctx, cancel := context.WithCancel(context.Background())
	waker := waker.NewTestAlways()

	// In this and the following test, open RDWR so as to not block this thread
	// from proceeding.  If we open the logstream first, there is a race before
	// the write end opens that can sometimes lead to the logstream reading an
	// EOF (because the write end is not yet open) and the test fails.
	f, err := os.OpenFile(name, os.O_RDWR, os.ModeNamedPipe)
	testutil.FatalIfErr(t, err)

	ps, err := logstream.New(ctx, &wg, waker, name, lines, false)
	testutil.FatalIfErr(t, err)

	testutil.WriteString(t, f, "1\n")

	// Pipes need to be closed to signal to the pipeStream to finish up.
	testutil.FatalIfErr(t, f.Close())

	ps.Stop() // no-op for pipes
	wg.Wait()
	close(lines)

	received := testutil.LinesReceived(lines)
	expected := []*logline.LogLine{
		{context.TODO(), name, "1"},
	}
	testutil.ExpectNoDiff(t, expected, received, testutil.IgnoreFields(logline.LogLine{}, "Context"))

	cancel()

	if !ps.IsComplete() {
		t.Errorf("expecting pipestream to be complete because fifo closed")
	}
}

func TestPipeStreamReadCompletedBecauseCancel(t *testing.T) {
	var wg sync.WaitGroup

	tmpDir := testutil.TestTempDir(t)

	name := filepath.Join(tmpDir, "fifo")
	testutil.FatalIfErr(t, unix.Mkfifo(name, 0666))

	lines := make(chan *logline.LogLine, 1)
	ctx, cancel := context.WithCancel(context.Background())
	waker, awaken := waker.NewTest(ctx, 1)

	f, err := os.OpenFile(name, os.O_RDWR, os.ModeNamedPipe)
	testutil.FatalIfErr(t, err)

	ps, err := logstream.New(ctx, &wg, waker, name, lines, false)
	testutil.FatalIfErr(t, err)

	testutil.WriteString(t, f, "1\n")

	// Avoid a race with cancellation if we can synchronise with waker.Wake()
	awaken(0)

	cancel() // Cancellation here should cause the stream to shut down.

	wg.Wait()
	close(lines)

	received := testutil.LinesReceived(lines)
	expected := []*logline.LogLine{
		{context.TODO(), name, "1"},
	}
	testutil.ExpectNoDiff(t, expected, received, testutil.IgnoreFields(logline.LogLine{}, "Context"))

	if !ps.IsComplete() {
		t.Errorf("expecting pipestream to be complete because cancelled")
	}
}
<|endoftext|>


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

package ssa

import "cmd/compile/internal/types"

// zcse does an initial pass of common-subexpression elimination on the
// function for values with zero arguments to allow the more expensive cse
// to begin with a reduced number of values. Values are just relinked,
// nothing is deleted. A subsequent deadcode pass is required to actually
// remove duplicate expressions.
func zcse(f *Func) {
	vals := make(map[vkey]*Value)

	for _, b := range f.Blocks {
		for i := 0; i < len(b.Values); {
			v := b.Values[i]
			next := true
			if opcodeTable[v.Op].argLen == 0 {
				key := vkey{v.Op, keyFor(v), v.Aux, v.Type}
				if vals[key] == nil {
					vals[key] = v
					if b != f.Entry {
						// Move v to the entry block so it will dominate every block
						// where we might use it. This prevents the need for any dominator
						// calculations in this pass.
						v.Block = f.Entry
						f.Entry.Values = append(f.Entry.Values, v)
						last := len(b.Values) - 1
						b.Values[i] = b.Values[last]
						b.Values[last] = nil
						b.Values = b.Values[:last]

						// process b.Values[i] again
						next = false
					}
				}
			}
			if next {
				i++
			}
		}
	}

	for _, b := range f.Blocks {
		for _, v := range b.Values {
			for i, a := range v.Args {
				if opcodeTable[a.Op].argLen == 0 {
					key := vkey{a.Op, keyFor(a), a.Aux, a.Type}
					if rv, ok := vals[key]; ok {
						v.SetArg(i, rv)
					}
				}
			}
		}
	}
}

// vkey is a type used to uniquely identify a zero arg value.
type vkey struct {
	op Op
	ai int64       // aux int
	ax interface{} // aux
	t  *types.Type // type
}

// keyFor returns the AuxInt portion of a  key structure uniquely identifying a
// zero arg value for the supported ops.
func keyFor(v *Value) int64 {
	switch v.Op {
	case OpConst64, OpConst64F, OpConst32F:
		return v.AuxInt
	case OpConst32:
		return int64(int32(v.AuxInt))
	case OpConst16:
		return int64(int16(v.AuxInt))
	case OpConst8, OpConstBool:
		return int64(int8(v.AuxInt))
	default:
		return v.AuxInt
	}
}
<commit_msg>cmd/compile: simplify zcse<commit_after>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ssa

import "cmd/compile/internal/types"

// zcse does an initial pass of common-subexpression elimination on the
// function for values with zero arguments to allow the more expensive cse
// to begin with a reduced number of values. Values are just relinked,
// nothing is deleted. A subsequent deadcode pass is required to actually
// remove duplicate expressions.
func zcse(f *Func) {
	vals := make(map[vkey]*Value)

	for _, b := range f.Blocks {
		for i := 0; i < len(b.Values); i++ {
			v := b.Values[i]
			if opcodeTable[v.Op].argLen == 0 {
				key := vkey{v.Op, keyFor(v), v.Aux, v.Type}
				if vals[key] == nil {
					vals[key] = v
					if b != f.Entry {
						// Move v to the entry block so it will dominate every block
						// where we might use it. This prevents the need for any dominator
						// calculations in this pass.
						v.Block = f.Entry
						f.Entry.Values = append(f.Entry.Values, v)
						last := len(b.Values) - 1
						b.Values[i] = b.Values[last]
						b.Values[last] = nil
						b.Values = b.Values[:last]

						i-- // process b.Values[i] again
					}
				}
			}
		}
	}

	for _, b := range f.Blocks {
		for _, v := range b.Values {
			for i, a := range v.Args {
				if opcodeTable[a.Op].argLen == 0 {
					key := vkey{a.Op, keyFor(a), a.Aux, a.Type}
					if rv, ok := vals[key]; ok {
						v.SetArg(i, rv)
					}
				}
			}
		}
	}
}

// vkey is a type used to uniquely identify a zero arg value.
type vkey struct {
	op Op
	ai int64       // aux int
	ax interface{} // aux
	t  *types.Type // type
}

// keyFor returns the AuxInt portion of a  key structure uniquely identifying a
// zero arg value for the supported ops.
func keyFor(v *Value) int64 {
	switch v.Op {
	case OpConst64, OpConst64F, OpConst32F:
		return v.AuxInt
	case OpConst32:
		return int64(int32(v.AuxInt))
	case OpConst16:
		return int64(int16(v.AuxInt))
	case OpConst8, OpConstBool:
		return int64(int8(v.AuxInt))
	default:
		return v.AuxInt
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net"
	"time"

	"github.com/conformal/btcwire"
)

type Peer struct {
	client          *Client
	conn            net.Conn
	nonce           uint64 // Nonce we're sending to the peer
	pver            uint32 // Negotiated ProtocolVersion
	Address         string
	UserAgent       string
	ProtocolVersion int32
	ConnectTimeout  time.Duration // For the connect phase (can be overridden)
}

func NewPeer(client *Client, address string) *Peer {
	p := Peer{
		client:         client,
		pver:           client.pver,
		Address:        address,
		ConnectTimeout: time.Duration(20 * time.Second),
	}
	return &p
}

func (p *Peer) Connect() error {
	if p.conn != nil {
		return fmt.Errorf("Peer already connected, can't connect again.")
	}
	conn, err := net.DialTimeout("tcp", p.Address, p.ConnectTimeout)
	if err != nil {
		return err
	}

	p.conn = conn
	return nil
}

func (p *Peer) Disconnect() {
	p.conn.Close()
	logger.Debugf("[%s] Closed.", p.Address)
}

func (p *Peer) Handshake() error {
	if p.conn == nil {
		return fmt.Errorf("Peer is not connected, can't handshake.")
	}

	logger.Debugf("[%s] Starting handshake.", p.Address)

	nonce, err := btcwire.RandomUint64()
	if err != nil {
		return err
	}
	p.nonce = nonce

	msgVersion, err := btcwire.NewMsgVersionFromConn(p.conn, p.nonce, p.client.userAgent, 0)
	msgVersion.DisableRelayTx = true
	if err := p.WriteMessage(msgVersion); err != nil {
		return err
	}

	// Read the response version.
	msg, _, err := p.ReadMessage()
	if err != nil {
		return err
	}
	vmsg, ok := msg.(*btcwire.MsgVersion)
	if !ok {
		return fmt.Errorf("Did not receive version message: %T", vmsg)
	}

	p.ProtocolVersion = vmsg.ProtocolVersion
	p.UserAgent = vmsg.UserAgent

	// Negotiate protocol version.
	if uint32(vmsg.ProtocolVersion) < p.pver {
		p.pver = uint32(vmsg.ProtocolVersion)
	}
	logger.Debugf("[%s] -> Version: %s", p.Address, vmsg.UserAgent)

	// Normally we'd check if vmsg.Nonce == p.nonce but the crawler does not
	// accept external connections so we skip it.

	// Send verack.
	if err := p.WriteMessage(btcwire.NewMsgVerAck()); err != nil {
		return err
	}

	return nil
}

func (p *Peer) WriteMessage(msg btcwire.Message) error {
	return btcwire.WriteMessage(p.conn, msg, p.pver, p.client.btcnet)
}

func (p *Peer) ReadMessage() (btcwire.Message, []byte, error) {
	return btcwire.ReadMessage(p.conn, p.pver, p.client.btcnet)
}
<commit_msg>Update btcwire<commit_after>package main

import (
	"fmt"
	"net"
	"time"

	"github.com/conformal/btcwire"
)

type Peer struct {
	client          *Client
	conn            net.Conn
	nonce           uint64 // Nonce we're sending to the peer
	pver            uint32 // Negotiated ProtocolVersion
	Address         string
	UserAgent       string
	ProtocolVersion int32
	ConnectTimeout  time.Duration // For the connect phase (can be overridden)
}

func NewPeer(client *Client, address string) *Peer {
	p := Peer{
		client:         client,
		pver:           client.pver,
		Address:        address,
		ConnectTimeout: time.Duration(20 * time.Second),
	}
	return &p
}

func (p *Peer) Connect() error {
	if p.conn != nil {
		return fmt.Errorf("Peer already connected, can't connect again.")
	}
	conn, err := net.DialTimeout("tcp", p.Address, p.ConnectTimeout)
	if err != nil {
		return err
	}

	p.conn = conn
	return nil
}

func (p *Peer) Disconnect() {
	p.conn.Close()
	logger.Debugf("[%s] Closed.", p.Address)
}

func (p *Peer) Handshake() error {
	if p.conn == nil {
		return fmt.Errorf("Peer is not connected, can't handshake.")
	}

	logger.Debugf("[%s] Starting handshake.", p.Address)

	nonce, err := btcwire.RandomUint64()
	if err != nil {
		return err
	}
	p.nonce = nonce

	msgVersion, err := btcwire.NewMsgVersionFromConn(p.conn, p.nonce, 0)
	msgVersion.UserAgent = p.client.userAgent
	msgVersion.DisableRelayTx = true
	if err := p.WriteMessage(msgVersion); err != nil {
		return err
	}

	// Read the response version.
	msg, _, err := p.ReadMessage()
	if err != nil {
		return err
	}
	vmsg, ok := msg.(*btcwire.MsgVersion)
	if !ok {
		return fmt.Errorf("Did not receive version message: %T", vmsg)
	}

	p.ProtocolVersion = vmsg.ProtocolVersion
	p.UserAgent = vmsg.UserAgent

	// Negotiate protocol version.
	if uint32(vmsg.ProtocolVersion) < p.pver {
		p.pver = uint32(vmsg.ProtocolVersion)
	}
	logger.Debugf("[%s] -> Version: %s", p.Address, vmsg.UserAgent)

	// Normally we'd check if vmsg.Nonce == p.nonce but the crawler does not
	// accept external connections so we skip it.

	// Send verack.
	if err := p.WriteMessage(btcwire.NewMsgVerAck()); err != nil {
		return err
	}

	return nil
}

func (p *Peer) WriteMessage(msg btcwire.Message) error {
	return btcwire.WriteMessage(p.conn, msg, p.pver, p.client.btcnet)
}

func (p *Peer) ReadMessage() (btcwire.Message, []byte, error) {
	return btcwire.ReadMessage(p.conn, p.pver, p.client.btcnet)
}
<|endoftext|>


<commit_before>// This tests WatchdogReader

package swift

import (
	"io/ioutil"
	"testing"
	"time"
)

// Uses testReader from timeout_reader_test.go

func TestWatchdogReaderNoTimeout(t *testing.T) {
	test := newTestReader(3, 10*time.Millisecond)
	timer := time.NewTimer(100 * time.Millisecond)
	fired := false
	go func() {
		select {
		case <-timer.C:
			fired = true
		}
	}()
	wr := newWatchdogReader(test, 100*time.Millisecond, timer)
	b, err := ioutil.ReadAll(wr)
	if err != nil || string(b) != "AAA" {
		t.Fatalf("Bad read %s %s", err, b)
	}
	if fired {
		t.Fatal("Timer should not have fired")
	}
}

func TestWatchdogReaderTimeout(t *testing.T) {
	test := newTestReader(3, 10*time.Millisecond)
	timer := time.NewTimer(5 * time.Millisecond)
	fired := false
	go func() {
		select {
		case <-timer.C:
			fired = true
		}
	}()
	wr := newWatchdogReader(test, 5*time.Millisecond, timer)
	b, err := ioutil.ReadAll(wr)
	if err != nil || string(b) != "AAA" {
		t.Fatalf("Bad read %s %s", err, b)
	}
	if !fired {
		t.Fatal("Timer should have fired")
	}
}
<commit_msg>Make tests fail for Go 1.0<commit_after>// This tests WatchdogReader

package swift

import (
	"io/ioutil"
	"testing"
	"time"
)

// Uses testReader from timeout_reader_test.go

func testWatchdogReaderTimeout(t *testing.T, initialTimeout, watchdogTimeout time.Duration, expectedTimeout bool) {
	test := newTestReader(3, 10*time.Millisecond)
	timer := time.NewTimer(initialTimeout)
	fired := false
	started := make(chan bool)
	go func() {
		started <- true
		select {
		case <-timer.C:
			fired = true
		}
	}()
	<-started
	wr := newWatchdogReader(test, watchdogTimeout, timer)
	b, err := ioutil.ReadAll(wr)
	if err != nil || string(b) != "AAA" {
		t.Fatalf("Bad read %s %s", err, b)
	}
	if expectedTimeout {
		if !fired {
			t.Fatal("Timer should have fired")
		}
	} else {
		if fired {
			t.Fatal("Timer should not have fired")
		}
	}
}

func TestWatchdogReaderNoTimeout(t *testing.T) {
	testWatchdogReaderTimeout(t, 100*time.Millisecond, 100*time.Millisecond, false)
}

func TestWatchdogReaderTimeout(t *testing.T) {
	testWatchdogReaderTimeout(t, 5*time.Millisecond, 5*time.Millisecond, true)
}

func TestWatchdogReaderNoTimeoutShortInitial(t *testing.T) {
	testWatchdogReaderTimeout(t, 5*time.Millisecond, 100*time.Millisecond, false)
}

func TestWatchdogReaderTimeoutLongInitial(t *testing.T) {
	testWatchdogReaderTimeout(t, 100*time.Millisecond, 5*time.Millisecond, true)
}
<|endoftext|>


<commit_before>package pget

import (
	"os"
	"runtime"
	"strings"

	"github.com/asaskevich/govalidator"
	"github.com/pkg/errors"
)

const (
	version = "0.0.4"
	msg     = "Pget v" + version + ", parallel file download client\n"
)

// Pget structs
type Pget struct {
	Trace bool
	Utils
	TargetDir  string
	Procs      int
	URLs       []string
	TargetURLs []string
	args       []string
	timeout    int
	useragent  string
}

type ignore struct {
	err error
}

type cause interface {
	Cause() error
}

// New for pget package
func New() *Pget {
	return &Pget{
		Trace:   false,
		Utils:   &Data{},
		Procs:   runtime.NumCPU(), // default
		timeout: 10,
	}
}

// ErrTop get important message from wrapped error message
func (pget Pget) ErrTop(err error) error {
	for e := err; e != nil; {
		switch e.(type) {
		case ignore:
			return nil
		case cause:
			e = e.(cause).Cause()
		default:
			return e
		}
	}

	return nil
}

// Run execute methods in pget package
func (pget *Pget) Run() error {
	if err := pget.Ready(); err != nil {
		return pget.ErrTop(err)
	}

	if err := pget.Checking(); err != nil {
		return errors.Wrap(err, "failed to check header")
	}

	if err := pget.Download(); err != nil {
		return err
	}

	if err := pget.Utils.BindwithFiles(pget.Procs); err != nil {
		return err
	}

	return nil
}

// Ready method define the variables required to Download.
func (pget *Pget) Ready() error {
	if procs := os.Getenv("GOMAXPROCS"); procs == "" {
		runtime.GOMAXPROCS(pget.Procs)
	}

	var opts Options
	if err := pget.parseOptions(&opts, os.Args[1:]); err != nil {
		return errors.Wrap(err, "failed to parse command line args")
	}

	if opts.Trace {
		pget.Trace = opts.Trace
	}

	if opts.Procs > 2 {
		pget.Procs = opts.Procs
	}

	if opts.Timeout > 0 {
		pget.timeout = opts.Timeout
	}

	if err := pget.parseURLs(); err != nil {
		return errors.Wrap(err, "failed to parse of url")
	}

	if opts.UserAgent != "" {
		pget.useragent = opts.UserAgent
	}

	if opts.TargetDir != "" {
		info, err := os.Stat(opts.TargetDir)
		if err != nil {
			if !os.IsNotExist(err) {
				return errors.Wrap(err, "target dir is invalid")
			}

			if err := os.MkdirAll(opts.TargetDir, 0755); err != nil {
				return errors.Wrapf(err, "failed to create diretory at %s", opts.TargetDir)
			}

		} else if !info.IsDir() {
			return errors.New("target dir is not a valid directory")
		}
	}
	opts.TargetDir = strings.TrimSuffix(opts.TargetDir, "/")
	pget.TargetDir = opts.TargetDir

	return nil
}

func (pget Pget) makeIgnoreErr() ignore {
	return ignore{
		err: errors.New("this is ignore message"),
	}
}

// Error for options: version, usage
func (i ignore) Error() string {
	return i.err.Error()
}

func (i ignore) Cause() error {
	return i.err
}

func (pget *Pget) parseOptions(opts *Options, argv []string) error {

	if len(argv) == 0 {
		os.Stdout.Write(opts.usage())
		return pget.makeIgnoreErr()
	}

	o, err := opts.parse(argv)
	if err != nil {
		return errors.Wrap(err, "failed to parse command line options")
	}

	if opts.Help {
		os.Stdout.Write(opts.usage())
		return pget.makeIgnoreErr()
	}

	if opts.Version {
		os.Stdout.Write([]byte(msg))
		return pget.makeIgnoreErr()
	}

	if opts.Update {
		result, err := opts.isupdate()
		if err != nil {
			return errors.Wrap(err, "failed to parse command line options")
		}

		os.Stdout.Write(result)
		return pget.makeIgnoreErr()
	}

	pget.args = o

	return nil
}

func (pget *Pget) parseURLs() error {

	// find url in args
	for _, argv := range pget.args {
		if govalidator.IsURL(argv) {
			pget.URLs = append(pget.URLs, argv)
		}
	}

	if len(pget.URLs) < 1 {
		return errors.New("urls not found in the arguments passed")
	}

	return nil
}
<commit_msg>supported input from stdin<commit_after>package pget

import (
	"bufio"
	"os"
	"runtime"
	"strings"

	"github.com/asaskevich/govalidator"
	"github.com/pkg/errors"
)

const (
	version = "0.0.4"
	msg     = "Pget v" + version + ", parallel file download client\n"
)

// Pget structs
type Pget struct {
	Trace bool
	Utils
	TargetDir  string
	Procs      int
	URLs       []string
	TargetURLs []string
	args       []string
	timeout    int
	useragent  string
}

type ignore struct {
	err error
}

type cause interface {
	Cause() error
}

// New for pget package
func New() *Pget {
	return &Pget{
		Trace:   false,
		Utils:   &Data{},
		Procs:   runtime.NumCPU(), // default
		timeout: 10,
	}
}

// ErrTop get important message from wrapped error message
func (pget Pget) ErrTop(err error) error {
	for e := err; e != nil; {
		switch e.(type) {
		case ignore:
			return nil
		case cause:
			e = e.(cause).Cause()
		default:
			return e
		}
	}

	return nil
}

// Run execute methods in pget package
func (pget *Pget) Run() error {
	if err := pget.Ready(); err != nil {
		return pget.ErrTop(err)
	}

	if err := pget.Checking(); err != nil {
		return errors.Wrap(err, "failed to check header")
	}

	if err := pget.Download(); err != nil {
		return err
	}

	if err := pget.Utils.BindwithFiles(pget.Procs); err != nil {
		return err
	}

	return nil
}

// Ready method define the variables required to Download.
func (pget *Pget) Ready() error {
	if procs := os.Getenv("GOMAXPROCS"); procs == "" {
		runtime.GOMAXPROCS(pget.Procs)
	}

	var opts Options
	if err := pget.parseOptions(&opts, os.Args[1:]); err != nil {
		return errors.Wrap(err, "failed to parse command line args")
	}

	if opts.Trace {
		pget.Trace = opts.Trace
	}

	if opts.Procs > 2 {
		pget.Procs = opts.Procs
	}

	if opts.Timeout > 0 {
		pget.timeout = opts.Timeout
	}

	if err := pget.parseURLs(); err != nil {
		return errors.Wrap(err, "failed to parse of url")
	}

	if opts.UserAgent != "" {
		pget.useragent = opts.UserAgent
	}

	if opts.TargetDir != "" {
		info, err := os.Stat(opts.TargetDir)
		if err != nil {
			if !os.IsNotExist(err) {
				return errors.Wrap(err, "target dir is invalid")
			}

			if err := os.MkdirAll(opts.TargetDir, 0755); err != nil {
				return errors.Wrapf(err, "failed to create diretory at %s", opts.TargetDir)
			}

		} else if !info.IsDir() {
			return errors.New("target dir is not a valid directory")
		}
	}
	opts.TargetDir = strings.TrimSuffix(opts.TargetDir, "/")
	pget.TargetDir = opts.TargetDir

	return nil
}

func (pget Pget) makeIgnoreErr() ignore {
	return ignore{
		err: errors.New("this is ignore message"),
	}
}

// Error for options: version, usage
func (i ignore) Error() string {
	return i.err.Error()
}

func (i ignore) Cause() error {
	return i.err
}

func (pget *Pget) parseOptions(opts *Options, argv []string) error {

	if len(argv) == 0 {
		os.Stdout.Write(opts.usage())
		return pget.makeIgnoreErr()
	}

	o, err := opts.parse(argv)
	if err != nil {
		return errors.Wrap(err, "failed to parse command line options")
	}

	if opts.Help {
		os.Stdout.Write(opts.usage())
		return pget.makeIgnoreErr()
	}

	if opts.Version {
		os.Stdout.Write([]byte(msg))
		return pget.makeIgnoreErr()
	}

	if opts.Update {
		result, err := opts.isupdate()
		if err != nil {
			return errors.Wrap(err, "failed to parse command line options")
		}

		os.Stdout.Write(result)
		return pget.makeIgnoreErr()
	}

	pget.args = o

	return nil
}

func (pget *Pget) parseURLs() error {

	// find url in args
	for _, argv := range pget.args {
		if govalidator.IsURL(argv) {
			pget.URLs = append(pget.URLs, argv)
		}
	}

	if len(pget.URLs) < 1 {
		scanner := bufio.NewScanner(os.Stdin)
		for scanner.Scan() {
			scan := scanner.Text()
			urls := strings.Split(scan, " ")
			for _, url := range urls {
				if govalidator.IsURL(url) {
					pget.URLs = append(pget.URLs, url)
				}
			}
		}

		if err := scanner.Err(); err != nil {
			return errors.Wrap(err, "failed to parse url from stdin")
		}

		if len(pget.URLs) < 1 {
			return errors.New("urls not found in the arguments passed")
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
)

type RuneIter struct {
	runes []rune
	cur   int
	size  int
}

type IterError struct {
	error string
}

func (e *IterError) Error() string {
	return fmt.Sprintf("%s\n", e.error)
}

func NewRuneIter(s string) RuneIter {
	runes := make([]rune, 0)
	for _,r := range s {
		runes = append(runes, r)
	}
	return RuneIter{runes, 0, len(runes)}
}

func (r *RuneIter) Peek() (rune, error) {
	if r.cur + 1 > r.size {
		return 'a', &IterError{"No more elements"}
	}
	return r.runes[r.cur + 1], nil
}

func (r *RuneIter) Next() (rune, error) {
	if r.cur + 1 > r.size {
		return 'a', &IterError{"No more elements"}
	}
	n := r.runes[r.cur]
	r.cur += 1
	return n, nil
}

var cFile = flag.String("c", "", "output file")

var cHead = `
#include <stdio.h>

int
main() {
  char array[1000];
  char *ptr = array;

`

var cTail = `
  return 0;
}
`

var indent = `  `

func addIndent(indentLevel int, s string) string {
    var indented string
    for i := 0; i < indentLevel; i++ {
        indented += indent
    }
    indented += s
    return indented
}

func makeCSource(bfSource string) string {
    cSource := cHead
    indentLevel := 1

	rIter := NewRuneIter(bfSource)

    for {
		rune,err := rIter.Next()
		if err != nil {
			break
		}
		var addC string
		switch rune {
		case '>':
			addC = "++ptr;\n"
		case '<':
			addC = "--ptr;\n"
		case '+':
			addC = "++*ptr;\n"
		case '-':
			addC = "--*ptr;\n"
		case '.':
			addC = "putchar(*ptr);\n"
		case ',':
			addC = "*ptr = getchar();\n"
		case '[':
			addC = "while (*ptr) {\n"
			indentLevel += 1
		case ']':
			addC = "}\n"
			indentLevel -= 1
		default:
			continue
		}

        toAdd := addIndent(indentLevel, addC)
        cSource += toAdd
    }
    cSource += cTail
    return cSource
}

func main() {
	flag.Parse()
	if *cFile == "" {
		panic("No c destination")
	}
	if len(flag.Args()) != 1 {
		panic("No bf source")
	}
	bfFile := (flag.Args())[0]

	bfSource, err := ioutil.ReadFile(bfFile)
	if err != nil {
		panic(err)
	}
    bfString := string(bfSource)

    cSource := makeCSource(bfString)

    outBytes := []byte(cSource)
    err = ioutil.WriteFile(*cFile, outBytes, 0644)
	if err != nil {
		panic(err)
	}
}
<commit_msg>Condense consecutive calls into (+|-)=<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"strconv"
)

type RuneIter struct {
	runes []rune
	cur   int
	size  int
}

type IterError struct {
	error string
}

func (e *IterError) Error() string {
	return fmt.Sprintf("%s\n", e.error)
}

func NewRuneIter(s string) RuneIter {
	runes := make([]rune, 0)
	for _,r := range s {
		runes = append(runes, r)
	}
	return RuneIter{runes, 0, len(runes)}
}

func (r *RuneIter) Peek() (rune, error) {
	if r.cur + 1 > r.size - 1 {
		return 'a', &IterError{"No more elements"}
	}
	return r.runes[r.cur], nil
}

func (r *RuneIter) Next() (rune, error) {
	if r.cur + 1 > r.size - 1{
		return 'a', &IterError{"No more elements"}
	}
	n := r.runes[r.cur]
	r.cur += 1
	return n, nil
}

var cFile = flag.String("c", "", "output file")

var cHead = `
#include <stdio.h>

int
main() {
  char array[1000];
  char *ptr = array;

`

var cTail = `
  return 0;
}
`

var indent = `  `

func addIndent(indentLevel int, s string) string {
    var indented string
    for i := 0; i < indentLevel; i++ {
        indented += indent
    }
    indented += s
    return indented
}

func makeCSource(bfSource string) string {
    cSource := cHead
    indentLevel := 1

	rIter := NewRuneIter(bfSource)

    for {
		rune,err := rIter.Next()
		if err != nil {
			break
		}
		var addC string
		switch rune {
		case '>':
			num := 1
            for {
                peeked, err := rIter.Peek()
                if err != nil {
                    break // End of the bf.
                }
                if peeked == '>' {
                    num += 1
                } else {
                    break // No match on next character.
                }
                _, _ = rIter.Next() // This won't fail if peek was fine.
            }

            if num == 1 {
                addC = "++ptr;\n"
            } else {
                addC = "ptr += " + strconv.Itoa(num) + ";\n"
            }

		case '<':

			num := 1
            for {
                peeked, err := rIter.Peek()
                if err != nil {
                    break // End of the bf.
                }
                if peeked == '<' {
                    num += 1
                } else {
                    break // No match on next character.
                }
                _, _ = rIter.Next() // This won't fail if peek was fine.
            }

            if num == 1 {
                addC = "--ptr;\n"
            } else {
                addC = "ptr -= " + strconv.Itoa(num) + ";\n"
            }

		case '+':
			num := 1
			for {
				peeked, err := rIter.Peek()
				if err != nil {
					break // End of the bf.
				}
				if peeked == '+' {
					num += 1
				} else {
					break // No match on next character.
				}
				_, _ = rIter.Next() // This won't fail if peek was fine.
			}

			if num == 1 {
				addC = "++*ptr;\n"
			} else {
				addC = "*ptr += " + strconv.Itoa(num) + ";\n"
			}

		case '-':
			num := 1
            for {
                peeked, err := rIter.Peek()
                if err != nil {
                    break // End of the bf.
                }
                if peeked == '-' {
                    num += 1
                } else {
                    break // No match on next character.
                }
                _, _ = rIter.Next() // This won't fail if peek was fine.
            }

            if num == 1 {
                addC = "--*ptr;\n"
            } else {
                addC = "*ptr -= " + strconv.Itoa(num) + ";\n"
            }

		case '.':
			addC = "putchar(*ptr);\n"
		case ',':
			addC = "*ptr = getchar();\n"
		case '[':
			addC = "while (*ptr) {\n"
			indentLevel += 1
		case ']':
			addC = "}\n"
			indentLevel -= 1
		default:
			continue
		}

        toAdd := addIndent(indentLevel, addC)
        cSource += toAdd
    }
    cSource += cTail
    return cSource
}

func main() {
	flag.Parse()
	if *cFile == "" {
		panic("No c destination")
	}
	if len(flag.Args()) != 1 {
		panic("No bf source")
	}
	bfFile := (flag.Args())[0]

	bfSource, err := ioutil.ReadFile(bfFile)
	if err != nil {
		panic(err)
	}
    bfString := string(bfSource)

    cSource := makeCSource(bfString)

    outBytes := []byte(cSource)
    err = ioutil.WriteFile(*cFile, outBytes, 0644)
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package impl

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

	"tools/git"
	"veyron/lib/cmdline"
)

var (
	draft     bool
	reviewers string
	ccs       string
)

// init carries out the package initialization.
func init() {
	cmdReview.Flags.BoolVar(&draft, "d", false, "Send draft change list.")
	cmdReview.Flags.StringVar(&reviewers, "r", "", "Comma-seperated list of emails or LDAPs to request review.")
	cmdReview.Flags.StringVar(&ccs, "cc", "", "Comma-seperated list of emails or LDAPs to cc.")
}

// Root returns a command that represents the root of the review tool.
func Root() *cmdline.Command {
	return &cmdline.Command{
		Name:  "veyron",
		Short: "Command-line tool for interacting with the Veyron Gerrit server",
		Long: `
The veyron tool facilitates interaction with the Veyron Gerrit server.
In particular, it can be used to export changes from a local branch
to the Gerrit server.
`,
		Children: []*cmdline.Command{cmdReview},
	}
}

// cmdReview represent the 'review' command of the review tool.
var cmdReview = &cmdline.Command{
	Run:   runReview,
	Name:  "review",
	Short: "Send changes from a local branch to Gerrit for review",
	Long: `
Squashes all commits of a local branch into a single commit and
submits that commit to Gerrit as a single change list.  You can run
it multiple times to send more patch sets to the change list.
`,
}

var errOperationFailed = errors.New("operation failed")

type EmptyChangeError string

func (s EmptyChangeError) Error() string {
	return fmt.Sprintf("No commits on branch %s.", string(s))
}

type NoChangeIdError string

func (s NoChangeIdError) Error() string {
	return fmt.Sprintf("No Change-Id in commit %s.", string(s))
}

// runReview is a wrapper that sets up and runs a review instance.
func runReview(cmd *cmdline.Command, args []string) error {
	branch, err := git.CurrentBranchName()
	if err != nil {
		fmt.Errorf("git.CurrentBranchName() failed: %v", err)
		return errOperationFailed
	}
	edit, repo := true, ""
	r := NewReview(draft, edit, branch, repo, reviewers, ccs)
	return r.run()
}

// review holds the state of a review.
type review struct {
	// branch is the name of the git branch from which the review is created.
	branch string
	// ccs is the list of LDAPs or emails to cc on the review.
	ccs string
	// draft indicates whether to create a draft review.
	draft bool
	// edit indicates whether to edit the review message.
	edit bool
	// repo is the name of the gerrit repository.
	repo string
	// reviewBranch is the name of the temporary git branch used to send the review.
	reviewBranch string
	// reviewers is the list of LDAPs or emails to request a review from.
	reviewers string
}

// NewReview is the review factory.
func NewReview(draft, edit bool, branch, repo, reviewers, ccs string) *review {
	reviewBranch := branch + "-REVIEW"
	return &review{
		branch:       branch,
		ccs:          ccs,
		draft:        draft,
		edit:         edit,
		repo:         repo,
		reviewBranch: reviewBranch,
		reviewers:    reviewers,
	}
}

var conflictMessage = `
######################################################################
Your branch and the project master branch contain conflicting changes.
Please run 'git pull origin master', resolve all conflicts, and then
run 'git veyron review' again.
######################################################################
`

var noCommitsMessage = `
######################################################################
Your branch has no new changes. Please make some changes and commit
them before running 'git veyron review' again.
######################################################################
`

var noChangeIdMessage = `
######################################################################
Missing Change-Id.  Please run ./scripts/setup/repo/init.sh and then
run 'git veyron review' again.
######################################################################
`

var defaultMessageHeader = `
PLEASE EDIT THIS MESSAGE!

# You are about to submit the following commits for review:
#
`

// Change-Ids start with 'I' and are followed by 40 characters of hex.
var reChangeId *regexp.Regexp = regexp.MustCompile("Change-Id: I[0123456789abcdefABCDEF]{40}")

// defaultCommitMessage creates the default commit message from the list of
// commits on the branch.
func (r *review) defaultCommitMessage() (string, error) {
	commitMessages, err := git.CommitMessages(r.branch, r.reviewBranch)
	if err != nil {
		return "", fmt.Errorf("git.CommitMessages(%v, %v) failed: %v", r.branch, r.reviewBranch, err)
	}
	// Strip "Change-Id: ..." from the commit messages.
	strippedMessages := reChangeId.ReplaceAllLiteralString(commitMessages, "")
	// Add comment markers (#) to every line.
	commentedMessages := "# " + strings.Replace(strippedMessages, "\n", "\n# ", -1)
	message := defaultMessageHeader + commentedMessages
	return message, nil
}

// createReviewBranch creates a clean review branch from master and
// squashes the commits into one, with the supplied message.
func (r *review) createReviewBranch(message string) error {
	fmt.Println("### Creating a temporary review branch. ###")
	if err := git.Fetch(); err != nil {
		return fmt.Errorf("git.Fetch() failed: %v", err)
	}
	_ = git.ForceDeleteBranch(r.reviewBranch)
	upstream := "origin/master"
	if err := git.CreateBranchWithUpstream(r.reviewBranch, upstream); err != nil {
		return fmt.Errorf("git.CreateBranch(%v, %v) failed: %v", r.reviewBranch, upstream, err)
	}
	{
		hasDiff, err := git.BranchesDiffer(r.branch, r.reviewBranch)
		if err != nil {
			return fmt.Errorf("git.BranchesDiffer(%v, %v) failed: %v", r.branch, r.reviewBranch, err)
		}
		if !hasDiff {
			fmt.Printf("%s", noCommitsMessage)
			return EmptyChangeError(r.branch)
		}
	}
	// If message is empty, replace it with the default.
	if len(message) == 0 {
		var err error
		message, err = r.defaultCommitMessage()
		if err != nil {
			return fmt.Errorf("defaultCommitMessage() failed: %v", err)
		}
	}
	fmt.Printf("### Squashing commits into the review branch. ###\n")
	s := git.NewSquasher(r.edit)
	if err := s.Squash(r.branch, r.reviewBranch, message); err != nil {
		fmt.Printf("%s", conflictMessage)
		return fmt.Errorf("git.SquashInto(%v,%v,%v) failed: %v", r.branch, r.reviewBranch, message, err)
	}
	return nil
}

// ensureChangeId makes sure that the last commit contains a Change-Id, and
// returns an error if it does not.
func (r *review) ensureChangeId() error {
	latestCommitMessage, err := git.LatestCommitMessage()
	if err != nil {
		return fmt.Errorf("git.LatestCommitMessage() failed: %v", err)
	}
	changeId := reChangeId.FindString(latestCommitMessage)
	if changeId == "" {
		fmt.Printf("%s", noChangeIdMessage)
		return NoChangeIdError(latestCommitMessage)
	}
	return nil
}

// cleanup cleans up after the review.
func (r *review) cleanup(stash bool) {
	fmt.Println("### Cleaning up. ###")
	if err := git.CheckoutBranch(r.branch); err != nil {
		fmt.Println("git.CheckoutBranch(%v) failed: %v", r.branch, err)
	}
	_ = git.ForceDeleteBranch(r.reviewBranch)
	if stash {
		if err := git.StashPop(); err != nil {
			fmt.Println("git.StashPop() failed: %v", err)
		}
	}
}

// run implements the end-to-end functionality of the review command.
func (r *review) run() error {
	fmt.Printf("Branch name: %s\n", r.branch)
	if r.branch == "master" {
		fmt.Errorf("Cannot do a review from the 'master' branch.")
		return errOperationFailed
	}
	filename, err := getCommitMessageFilename()
	if err != nil {
		return err
	}
	stash, err := stashUncommittedChanges()
	if err != nil {
		return err
	}
	wd, err := os.Getwd()
	if err != nil {
		return err
	}
	defer os.Chdir(wd)
	topLevel, err := git.TopLevel()
	if err != nil {
		return err
	}
	os.Chdir(topLevel)
	defer r.cleanup(stash)
	if err := r.createReviewBranch(readFile(filename)); err != nil {
		return err
	}
	if err := r.updateReviewMessage(filename); err != nil {
		return err
	}
	if err := r.send(); err != nil {
		return err
	}
	fmt.Println("### Success. ###")
	return nil
}

// send sends the current branch out for review.
func (r *review) send() error {
	if err := r.ensureChangeId(); err != nil {
		return err
	}
	fmt.Println("### Sending review to Gerrit. ###")
	if err := git.GerritReview(r.repo, r.draft, r.reviewers, r.ccs); err != nil {
		fmt.Printf("%s", conflictMessage)
		return fmt.Errorf("git.GerritReview(%v, %v, %v, %v) failed: %v",
			r.repo, r.draft, r.reviewers, r.ccs, err)
	}
	return nil
}

// updateReviewMessage writes the commit message to the specified
// file. It then adds that file to the original branch, and makes sure
// it is not on the review branch.
func (r *review) updateReviewMessage(filename string) error {
	fmt.Printf("### Updating review commit message. ###\n")
	if err := git.CheckoutBranch(r.reviewBranch); err != nil {
		return fmt.Errorf("git.CheckoutBranch(%v) failed: %v", r.reviewBranch, err)
	}
	newMessage, err := git.LatestCommitMessage()
	if err != nil {
		return fmt.Errorf("git.LatestCommitMessage() failed: %v", err)
	}
	if err := git.CheckoutBranch(r.branch); err != nil {
		return fmt.Errorf("git.CheckoutBranch(%v) failed: %v", r.branch, err)
	}
	if err := writeFile(filename, newMessage); err != nil {
		return fmt.Errorf("writeFile(%v, %v) failed: %v", filename, newMessage, err)
	}
	if err := git.CommitFile(filename, "Update gerrit commit message."); err != nil {
		return fmt.Errorf("git.CommitFile(%v) failed: %v", filename, err)
	}
	// Delete the commit message from review branch.
	if err := git.CheckoutBranch(r.reviewBranch); err != nil {
		return fmt.Errorf("git.CheckoutBranch(%v) failed: %v", r.reviewBranch, err)
	}
	if fileExists(filename) {
		if err := git.Remove(filename); err != nil {
			return fmt.Errorf("git.Remove(%v) failed: %v", filename, err)
		}
		if err := git.CommitAmend(newMessage); err != nil {
			return fmt.Errorf("git.CommitAmend(%v) failed: %v", newMessage, err)
		}
	}
	return nil
}

// fileExists returns true iff the file exists.
func fileExists(filename string) bool {
	if _, err := os.Stat(filename); err == nil {
		return true
	}
	return false
}

// getCommitMessageFilename returns the name of the file that will get
// used for the Gerrit commit message.
func getCommitMessageFilename() (string, error) {
	topLevel, err := git.TopLevel()
	if err != nil {
		return "", fmt.Errorf("git.TopLevel() failed: %v", err)
	}
	return filepath.Join(topLevel, ".gerrit_commit_message"), nil
}

// readFile returns the data in a file as a string. Returns empty
// string if the file does not exist.
func readFile(filename string) string {
	if fileExists(filename) {
		contents, _ := ioutil.ReadFile(filename)
		return string(contents)
	}
	return ""
}

// stashUncommittedChanges stashes any work in progress and returns a
// flag that indicates whether anything has been stashed.
func stashUncommittedChanges() (bool, error) {
	oldSize, err := git.StashSize()
	if err != nil {
		return false, fmt.Errorf("git.StashSize() failed: %v", err)
	}
	if err := git.Stash(); err != nil {
		return false, fmt.Errorf("git.Stash() failed: %v", err)
	}
	newSize, err := git.StashSize()
	if err != nil {
		return false, fmt.Errorf("git.StashSize() failed: %v", err)
	}
	return newSize > oldSize, nil
}

// writeFile writes the message string to the file.
func writeFile(filename, message string) error {
	return ioutil.WriteFile(filename, []byte(message), 0644)
}

// writeFileExecutable writes the message string to the file and makes it executable.
func writeFileExecutable(filename, message string) error {
	return ioutil.WriteFile(filename, []byte(message), 0777)
}
<commit_msg>go/src/tools/git-veyron/impl:  Add "git veyron version" command.<commit_after>package impl

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

	"tools/git"
	"veyron/lib/cmdline"
)

var (
	draft     bool
	reviewers string
	ccs       string
)

// init carries out the package initialization.
func init() {
	cmdReview.Flags.BoolVar(&draft, "d", false, "Send draft change list.")
	cmdReview.Flags.StringVar(&reviewers, "r", "", "Comma-seperated list of emails or LDAPs to request review.")
	cmdReview.Flags.StringVar(&ccs, "cc", "", "Comma-seperated list of emails or LDAPs to cc.")
}

// Root returns a command that represents the root of the review tool.
func Root() *cmdline.Command {
	return &cmdline.Command{
		Name:  "veyron",
		Short: "Command-line tool for interacting with the Veyron Gerrit server.",
		Long: `
The veyron tool facilitates interaction with the Veyron Gerrit server.
In particular, it can be used to export changes from a local branch
to the Gerrit server.
`,
		Children: []*cmdline.Command{cmdReview, cmdVersion},
	}
}

// cmdVersion represent the 'version' command of the review tool.
var cmdVersion = &cmdline.Command{
	Run:   runVersion,
	Name:  "version",
	Short: "Print version.",
	Long:  "Print version and commit hash used to build git veyron tool.",
}

const version string = "1.0.0"

// commitId should be over-written during build:
// go build -ldflags "-X tools/git-veyron/impl.commitId <commitId>" tools/git-veyron
var commitId string = "test-build"

func runVersion(cmd *cmdline.Command, args []string) error {
	fmt.Printf("%v (%v)\n", version, commitId)
	return nil
}

// cmdReview represent the 'review' command of the review tool.
var cmdReview = &cmdline.Command{
	Run:   runReview,
	Name:  "review",
	Short: "Send changes from a local branch to Gerrit for review.",
	Long: `
Squashes all commits of a local branch into a single commit and
submits that commit to Gerrit as a single change list.  You can run
it multiple times to send more patch sets to the change list.
`,
}

var errOperationFailed = errors.New("operation failed")

type EmptyChangeError string

func (s EmptyChangeError) Error() string {
	return fmt.Sprintf("No commits on branch %s.", string(s))
}

type NoChangeIdError string

func (s NoChangeIdError) Error() string {
	return fmt.Sprintf("No Change-Id in commit %s.", string(s))
}

// runReview is a wrapper that sets up and runs a review instance.
func runReview(cmd *cmdline.Command, args []string) error {
	branch, err := git.CurrentBranchName()
	if err != nil {
		fmt.Errorf("git.CurrentBranchName() failed: %v", err)
		return errOperationFailed
	}
	edit, repo := true, ""
	r := NewReview(draft, edit, branch, repo, reviewers, ccs)
	return r.run()
}

// review holds the state of a review.
type review struct {
	// branch is the name of the git branch from which the review is created.
	branch string
	// ccs is the list of LDAPs or emails to cc on the review.
	ccs string
	// draft indicates whether to create a draft review.
	draft bool
	// edit indicates whether to edit the review message.
	edit bool
	// repo is the name of the gerrit repository.
	repo string
	// reviewBranch is the name of the temporary git branch used to send the review.
	reviewBranch string
	// reviewers is the list of LDAPs or emails to request a review from.
	reviewers string
}

// NewReview is the review factory.
func NewReview(draft, edit bool, branch, repo, reviewers, ccs string) *review {
	reviewBranch := branch + "-REVIEW"
	return &review{
		branch:       branch,
		ccs:          ccs,
		draft:        draft,
		edit:         edit,
		repo:         repo,
		reviewBranch: reviewBranch,
		reviewers:    reviewers,
	}
}

var conflictMessage = `
######################################################################
Your branch and the project master branch contain conflicting changes.
Please run 'git pull origin master', resolve all conflicts, and then
run 'git veyron review' again.
######################################################################
`

var noCommitsMessage = `
######################################################################
Your branch has no new changes. Please make some changes and commit
them before running 'git veyron review' again.
######################################################################
`

var noChangeIdMessage = `
######################################################################
Missing Change-Id.  Please run ./scripts/setup/repo/init.sh and then
run 'git veyron review' again.
######################################################################
`

var defaultMessageHeader = `
PLEASE EDIT THIS MESSAGE!

# You are about to submit the following commits for review:
#
`

// Change-Ids start with 'I' and are followed by 40 characters of hex.
var reChangeId *regexp.Regexp = regexp.MustCompile("Change-Id: I[0123456789abcdefABCDEF]{40}")

// defaultCommitMessage creates the default commit message from the list of
// commits on the branch.
func (r *review) defaultCommitMessage() (string, error) {
	commitMessages, err := git.CommitMessages(r.branch, r.reviewBranch)
	if err != nil {
		return "", fmt.Errorf("git.CommitMessages(%v, %v) failed: %v", r.branch, r.reviewBranch, err)
	}
	// Strip "Change-Id: ..." from the commit messages.
	strippedMessages := reChangeId.ReplaceAllLiteralString(commitMessages, "")
	// Add comment markers (#) to every line.
	commentedMessages := "# " + strings.Replace(strippedMessages, "\n", "\n# ", -1)
	message := defaultMessageHeader + commentedMessages
	return message, nil
}

// createReviewBranch creates a clean review branch from master and
// squashes the commits into one, with the supplied message.
func (r *review) createReviewBranch(message string) error {
	fmt.Println("### Creating a temporary review branch. ###")
	if err := git.Fetch(); err != nil {
		return fmt.Errorf("git.Fetch() failed: %v", err)
	}
	_ = git.ForceDeleteBranch(r.reviewBranch)
	upstream := "origin/master"
	if err := git.CreateBranchWithUpstream(r.reviewBranch, upstream); err != nil {
		return fmt.Errorf("git.CreateBranch(%v, %v) failed: %v", r.reviewBranch, upstream, err)
	}
	{
		hasDiff, err := git.BranchesDiffer(r.branch, r.reviewBranch)
		if err != nil {
			return fmt.Errorf("git.BranchesDiffer(%v, %v) failed: %v", r.branch, r.reviewBranch, err)
		}
		if !hasDiff {
			fmt.Printf("%s", noCommitsMessage)
			return EmptyChangeError(r.branch)
		}
	}
	// If message is empty, replace it with the default.
	if len(message) == 0 {
		var err error
		message, err = r.defaultCommitMessage()
		if err != nil {
			return fmt.Errorf("defaultCommitMessage() failed: %v", err)
		}
	}
	fmt.Printf("### Squashing commits into the review branch. ###\n")
	s := git.NewSquasher(r.edit)
	if err := s.Squash(r.branch, r.reviewBranch, message); err != nil {
		fmt.Printf("%s", conflictMessage)
		return fmt.Errorf("git.SquashInto(%v,%v,%v) failed: %v", r.branch, r.reviewBranch, message, err)
	}
	return nil
}

// ensureChangeId makes sure that the last commit contains a Change-Id, and
// returns an error if it does not.
func (r *review) ensureChangeId() error {
	latestCommitMessage, err := git.LatestCommitMessage()
	if err != nil {
		return fmt.Errorf("git.LatestCommitMessage() failed: %v", err)
	}
	changeId := reChangeId.FindString(latestCommitMessage)
	if changeId == "" {
		fmt.Printf("%s", noChangeIdMessage)
		return NoChangeIdError(latestCommitMessage)
	}
	return nil
}

// cleanup cleans up after the review.
func (r *review) cleanup(stash bool) {
	fmt.Println("### Cleaning up. ###")
	if err := git.CheckoutBranch(r.branch); err != nil {
		fmt.Println("git.CheckoutBranch(%v) failed: %v", r.branch, err)
	}
	_ = git.ForceDeleteBranch(r.reviewBranch)
	if stash {
		if err := git.StashPop(); err != nil {
			fmt.Println("git.StashPop() failed: %v", err)
		}
	}
}

// run implements the end-to-end functionality of the review command.
func (r *review) run() error {
	fmt.Printf("Branch name: %s\n", r.branch)
	if r.branch == "master" {
		fmt.Errorf("Cannot do a review from the 'master' branch.")
		return errOperationFailed
	}
	filename, err := getCommitMessageFilename()
	if err != nil {
		return err
	}
	stash, err := stashUncommittedChanges()
	if err != nil {
		return err
	}
	wd, err := os.Getwd()
	if err != nil {
		return err
	}
	defer os.Chdir(wd)
	topLevel, err := git.TopLevel()
	if err != nil {
		return err
	}
	os.Chdir(topLevel)
	defer r.cleanup(stash)
	if err := r.createReviewBranch(readFile(filename)); err != nil {
		return err
	}
	if err := r.updateReviewMessage(filename); err != nil {
		return err
	}
	if err := r.send(); err != nil {
		return err
	}
	fmt.Println("### Success. ###")
	return nil
}

// send sends the current branch out for review.
func (r *review) send() error {
	if err := r.ensureChangeId(); err != nil {
		return err
	}
	fmt.Println("### Sending review to Gerrit. ###")
	if err := git.GerritReview(r.repo, r.draft, r.reviewers, r.ccs); err != nil {
		return fmt.Errorf("git.GerritReview(%v, %v, %v, %v) failed: %v",
			r.repo, r.draft, r.reviewers, r.ccs, err)
	}
	return nil
}

// updateReviewMessage writes the commit message to the specified
// file. It then adds that file to the original branch, and makes sure
// it is not on the review branch.
func (r *review) updateReviewMessage(filename string) error {
	fmt.Printf("### Updating review commit message. ###\n")
	if err := git.CheckoutBranch(r.reviewBranch); err != nil {
		return fmt.Errorf("git.CheckoutBranch(%v) failed: %v", r.reviewBranch, err)
	}
	newMessage, err := git.LatestCommitMessage()
	if err != nil {
		return fmt.Errorf("git.LatestCommitMessage() failed: %v", err)
	}
	if err := git.CheckoutBranch(r.branch); err != nil {
		return fmt.Errorf("git.CheckoutBranch(%v) failed: %v", r.branch, err)
	}
	if err := writeFile(filename, newMessage); err != nil {
		return fmt.Errorf("writeFile(%v, %v) failed: %v", filename, newMessage, err)
	}
	if err := git.CommitFile(filename, "Update gerrit commit message."); err != nil {
		return fmt.Errorf("git.CommitFile(%v) failed: %v", filename, err)
	}
	// Delete the commit message from review branch.
	if err := git.CheckoutBranch(r.reviewBranch); err != nil {
		return fmt.Errorf("git.CheckoutBranch(%v) failed: %v", r.reviewBranch, err)
	}
	if fileExists(filename) {
		if err := git.Remove(filename); err != nil {
			return fmt.Errorf("git.Remove(%v) failed: %v", filename, err)
		}
		if err := git.CommitAmend(newMessage); err != nil {
			return fmt.Errorf("git.CommitAmend(%v) failed: %v", newMessage, err)
		}
	}
	return nil
}

// fileExists returns true iff the file exists.
func fileExists(filename string) bool {
	if _, err := os.Stat(filename); err == nil {
		return true
	}
	return false
}

// getCommitMessageFilename returns the name of the file that will get
// used for the Gerrit commit message.
func getCommitMessageFilename() (string, error) {
	topLevel, err := git.TopLevel()
	if err != nil {
		return "", fmt.Errorf("git.TopLevel() failed: %v", err)
	}
	return filepath.Join(topLevel, ".gerrit_commit_message"), nil
}

// readFile returns the data in a file as a string. Returns empty
// string if the file does not exist.
func readFile(filename string) string {
	if fileExists(filename) {
		contents, _ := ioutil.ReadFile(filename)
		return string(contents)
	}
	return ""
}

// stashUncommittedChanges stashes any work in progress and returns a
// flag that indicates whether anything has been stashed.
func stashUncommittedChanges() (bool, error) {
	oldSize, err := git.StashSize()
	if err != nil {
		return false, fmt.Errorf("git.StashSize() failed: %v", err)
	}
	if err := git.Stash(); err != nil {
		return false, fmt.Errorf("git.Stash() failed: %v", err)
	}
	newSize, err := git.StashSize()
	if err != nil {
		return false, fmt.Errorf("git.StashSize() failed: %v", err)
	}
	return newSize > oldSize, nil
}

// writeFile writes the message string to the file.
func writeFile(filename, message string) error {
	return ioutil.WriteFile(filename, []byte(message), 0644)
}

// writeFileExecutable writes the message string to the file and makes it executable.
func writeFileExecutable(filename, message string) error {
	return ioutil.WriteFile(filename, []byte(message), 0777)
}
<|endoftext|>


<commit_before>package postcommit

import (
	"github.com/libgit2/git2go"

	"github.com/rgeorgiev583/gonflator/translator"
)

func TranslateRepoHead(target Translator, path string) (translatedRdiff <-chan Delta, err error) {
	if path == "" {
		path = "."
	}
	gitRepo, err := git2go.OpenRepository(path)
	if err != nil {
		return
	}
	repo := GitRepository(gitRepo)

	head, err := repo.Head()
	if err != nil {
		return
	}

	commit, err := head.Peel(ObjectCommit)
	if err != nil {
		return
	}

	tree, err := commit.Tree()
	if err != nil {
		return
	}

	parentTree := commit.Parent(0).Tree()
	if err != nil {
		return
	}

	diff, err := repo.DiffTreeToTree(parentTree, tree, nil)
	if err != nil {
		return
	}

	diff := repo.GetRdiff(repo.GetDiffDeltas(diff))

	if target != nil {
		return target.TranslateRdiff(diff)
	} else {
		return diff
	}
}
<commit_msg>added the PostCommitHook interface for implementing post-commit hooks<commit_after>package postcommit

import (
	"github.com/libgit2/git2go"

	"github.com/rgeorgiev583/gonflator/translator"
)

type PostCommitHook interface {
	TranslateRepoHead(target Translator, path string) (translatedRdiff <-chan Delta, err error)
}

func TranslateRepoHead(target Translator, path string) (translatedRdiff <-chan Delta, err error) {
	if path == "" {
		path = "."
	}
	gitRepo, err := git2go.OpenRepository(path)
	if err != nil {
		return
	}
	repo := GitRepository(gitRepo)

	head, err := repo.Head()
	if err != nil {
		return
	}

	commit, err := head.Peel(ObjectCommit)
	if err != nil {
		return
	}

	tree, err := commit.Tree()
	if err != nil {
		return
	}

	parentTree := commit.Parent(0).Tree()
	if err != nil {
		return
	}

	diff, err := repo.DiffTreeToTree(parentTree, tree, nil)
	if err != nil {
		return
	}

	diff := repo.GetRdiff(repo.GetDiffDeltas(diff))

	if target != nil {
		return target.TranslateRdiff(diff)
	} else {
		return diff
	}
}
<|endoftext|>


<commit_before>package cellnet

type EventPipe interface {
	AddQueue() EventQueue

	Start()

	Stop(int)

	Wait() int
}

type evPipe struct {
	exitSignal chan int

	dataChan chan *dataTask
}

func (self *evPipe) AddQueue() EventQueue {

	q := newEventQueue()

	go func(q *evQueue) {

		for v := range q.queue {
			self.dataChan <- &dataTask{q: q, e: v}
		}

	}(q)

	return q
}

type dataTask struct {
	q *evQueue
	e interface{}
}

func (self *evPipe) Start() {

	go func() {

		for v := range self.dataChan {
			v.q.CallData(v.e)
		}

	}()

}

func (self *evPipe) Stop(result int) {
	self.exitSignal <- result
}

func (self *evPipe) Wait() int {
	return <-self.exitSignal
}

func NewEventPipe() EventPipe {
	return &evPipe{
		exitSignal: make(chan int),
		dataChan:   make(chan *dataTask),
	}
}
<commit_msg>增加: 崩溃防御<commit_after>package cellnet

import (
	"runtime/debug"
)

type EventPipe interface {
	AddQueue() EventQueue

	Start()

	Stop(int)

	Wait() int

	// 开启捕获错误, 错误不会崩溃
	EnableCaputrePanic(enable bool)
}

type lineralTask struct {
	q *evQueue
	e interface{}
}

type lineraPipe struct {
	exitSignal chan int

	dataChan chan *lineralTask

	capturePanic bool
}

func (self *lineraPipe) AddQueue() EventQueue {

	q := newEventQueue()

	go func(q *evQueue) {
		for v := range q.queue {
			self.dataChan <- &lineralTask{q: q, e: v}
		}
	}(q)

	return q
}

func (self *lineraPipe) EnableCaputrePanic(enable bool) {
	self.capturePanic = enable
}

func (self *lineraPipe) Start() {

	go func() {
		for v := range self.dataChan {
			self.protectedCall(v.q, v.e)
		}
	}()
}
func (self *lineraPipe) protectedCall(q *evQueue, data interface{}) {
	if self.capturePanic {
		defer func() {

			if err := recover(); err != nil {
				log.Fatalln(err)
				debug.PrintStack()
			}

		}()
	}

	q.CallData(data)
}

func (self *lineraPipe) Stop(result int) {
	self.exitSignal <- result
}

func (self *lineraPipe) Wait() int {
	return <-self.exitSignal
}

func NewEventPipe() EventPipe {
	return &lineraPipe{
		exitSignal: make(chan int),
		dataChan:   make(chan *lineralTask),
	}
}
<|endoftext|>