代码拉取完成,页面将自动刷新
// This executable provides an HTTP server that watches for file system changes
// to .go files within the working directory (and all nested go packages).
// Navigating to the configured host and port in a web browser will display the
// latest results of running `go test` in each go package.
package main
import (
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
"time"
"github.com/smartystreets/goconvey/web/server/api"
"github.com/smartystreets/goconvey/web/server/contract"
"github.com/smartystreets/goconvey/web/server/executor"
"github.com/smartystreets/goconvey/web/server/messaging"
"github.com/smartystreets/goconvey/web/server/parser"
"github.com/smartystreets/goconvey/web/server/system"
"github.com/smartystreets/goconvey/web/server/watch"
)
func init() {
flags()
folders()
}
func flags() {
flag.IntVar(&port, "port", 8080, "The port at which to serve http.")
flag.StringVar(&host, "host", "127.0.0.1", "The host at which to serve http.")
flag.DurationVar(&nap, "poll", quarterSecond, "The interval to wait between polling the file system for changes.")
flag.IntVar(¶llelPackages, "packages", 10, "The number of packages to test in parallel. Higher == faster but more costly in terms of computing.")
flag.StringVar(&gobin, "gobin", "go", "The path to the 'go' binary (default: search on the PATH).")
flag.BoolVar(&cover, "cover", true, "Enable package-level coverage statistics. Requires Go 1.2+ and the go cover tool.")
flag.IntVar(&depth, "depth", -1, "The directory scanning depth. If -1, scan infinitely deep directory structures. 0: scan working directory. 1+: Scan into nested directories, limited to value.")
flag.StringVar(&timeout, "timeout", "0", "The test execution timeout if none is specified in the *.goconvey file (default is '0', which is the same as not providing this option).")
flag.StringVar(&watchedSuffixes, "watchedSuffixes", ".go", "A comma separated list of file suffixes to watch for modifications.")
flag.StringVar(&excludedDirs, "excludedDirs", "vendor,node_modules", "A comma separated list of directories that will be excluded from being watched.")
flag.StringVar(&workDir, "workDir", "", "set goconvey working directory (default current directory).")
flag.BoolVar(&autoLaunchBrowser, "launchBrowser", true, "toggle auto launching of browser.")
log.SetOutput(os.Stdout)
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
func folders() {
_, file, _, _ := runtime.Caller(0)
here := filepath.Dir(file)
static = filepath.Join(here, "/web/client")
reports = filepath.Join(static, "reports")
}
func main() {
flag.Parse()
log.Printf(initialConfiguration, host, port, nap, cover)
working := getWorkDir()
cover = coverageEnabled(cover, reports)
shell := system.NewShell(gobin, reports, cover, timeout)
watcherInput := make(chan messaging.WatcherCommand)
watcherOutput := make(chan messaging.Folders)
excludedDirItems := strings.Split(excludedDirs, `,`)
watcher := watch.NewWatcher(working, depth, nap, watcherInput, watcherOutput, watchedSuffixes, excludedDirItems)
parser := parser.NewParser(parser.ParsePackageResults)
tester := executor.NewConcurrentTester(shell)
tester.SetBatchSize(parallelPackages)
longpollChan := make(chan chan string)
executor := executor.NewExecutor(tester, parser, longpollChan)
server := api.NewHTTPServer(working, watcherInput, executor, longpollChan)
listener := createListener()
go runTestOnUpdates(watcherOutput, executor, server)
go watcher.Listen()
if autoLaunchBrowser {
go launchBrowser(listener.Addr().String())
}
serveHTTP(server, listener)
}
func browserCmd() (string, bool) {
browser := map[string]string{
"darwin": "open",
"linux": "xdg-open",
"windows": "start",
}
cmd, ok := browser[runtime.GOOS]
return cmd, ok
}
func launchBrowser(addr string) {
browser, ok := browserCmd()
if !ok {
log.Printf("Skipped launching browser for this OS: %s", runtime.GOOS)
return
}
log.Printf("Launching browser on %s", addr)
url := fmt.Sprintf("http://%s", addr)
cmd := exec.Command(browser, url)
output, err := cmd.CombinedOutput()
if err != nil {
log.Println(err)
}
log.Println(string(output))
}
func runTestOnUpdates(queue chan messaging.Folders, executor contract.Executor, server contract.Server) {
for update := range queue {
log.Println("Received request from watcher to execute tests...")
packages := extractPackages(update)
output := executor.ExecuteTests(packages)
root := extractRoot(update, packages)
server.ReceiveUpdate(root, output)
}
}
func extractPackages(folderList messaging.Folders) []*contract.Package {
packageList := []*contract.Package{}
for _, folder := range folderList {
hasImportCycle := testFilesImportTheirOwnPackage(folder.Path)
packageName := resolvePackageName(folder.Path)
packageList = append(
packageList,
contract.NewPackage(folder, packageName, hasImportCycle),
)
}
return packageList
}
func extractRoot(folderList messaging.Folders, packageList []*contract.Package) string {
path := packageList[0].Path
folder := folderList[path]
return folder.Root
}
func createListener() net.Listener {
l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", host, port))
if err != nil {
log.Println(err)
}
if l == nil {
os.Exit(1)
}
return l
}
func serveHTTP(server contract.Server, listener net.Listener) {
serveStaticResources()
serveAjaxMethods(server)
activateServer(listener)
}
func serveStaticResources() {
http.Handle("/", http.FileServer(http.Dir(static)))
}
func serveAjaxMethods(server contract.Server) {
http.HandleFunc("/watch", server.Watch)
http.HandleFunc("/ignore", server.Ignore)
http.HandleFunc("/reinstate", server.Reinstate)
http.HandleFunc("/latest", server.Results)
http.HandleFunc("/execute", server.Execute)
http.HandleFunc("/status", server.Status)
http.HandleFunc("/status/poll", server.LongPollStatus)
http.HandleFunc("/pause", server.TogglePause)
}
func activateServer(listener net.Listener) {
log.Printf("Serving HTTP at: http://%s\n", listener.Addr())
err := http.Serve(listener, nil)
if err != nil {
log.Println(err)
}
}
func coverageEnabled(cover bool, reports string) bool {
return (cover &&
goMinVersion(1, 2) &&
coverToolInstalled() &&
ensureReportDirectoryExists(reports))
}
func goMinVersion(wanted ...int) bool {
version := runtime.Version() // 'go1.2....'
s := regexp.MustCompile(`go([\d]+)\.([\d]+)\.?([\d]+)?`).FindAllStringSubmatch(version, 1)
if len(s) == 0 {
log.Printf("Cannot determine if newer than go1.2, disabling coverage.")
return false
}
for idx, str := range s[0][1:] {
if len(wanted) == idx {
break
}
if v, _ := strconv.Atoi(str); v < wanted[idx] {
log.Printf(pleaseUpgradeGoVersion, version)
return false
}
}
return true
}
func coverToolInstalled() bool {
working := getWorkDir()
command := system.NewCommand(working, "go", "tool", "cover").Execute()
installed := strings.Contains(command.Output, "Usage of 'go tool cover':")
if !installed {
log.Print(coverToolMissing)
return false
}
return true
}
func ensureReportDirectoryExists(reports string) bool {
result, err := exists(reports)
if err != nil {
log.Fatal(err)
}
if result {
return true
}
if err := os.Mkdir(reports, 0755); err == nil {
return true
}
log.Printf(reportDirectoryUnavailable, reports)
return false
}
func exists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
func getWorkDir() string {
working := ""
var err error
if workDir != "" {
working = workDir
} else {
working, err = os.Getwd()
if err != nil {
log.Fatal(err)
}
}
result, err := exists(working)
if err != nil {
log.Fatal(err)
}
if !result {
log.Fatalf("Path:%s does not exists", working)
}
return working
}
var (
port int
host string
gobin string
nap time.Duration
parallelPackages int
cover bool
depth int
timeout string
watchedSuffixes string
excludedDirs string
autoLaunchBrowser bool
static string
reports string
quarterSecond = time.Millisecond * 250
workDir string
)
const (
initialConfiguration = "Initial configuration: [host: %s] [port: %d] [poll: %v] [cover: %v]\n"
pleaseUpgradeGoVersion = "Go version is less that 1.2 (%s), please upgrade to the latest stable version to enable coverage reporting.\n"
coverToolMissing = "Go cover tool is not installed or not accessible: for Go < 1.5 run`go get golang.org/x/tools/cmd/cover`\n For >= Go 1.5 run `go install $GOROOT/src/cmd/cover`\n"
reportDirectoryUnavailable = "Could not find or create the coverage report directory (at: '%s'). You probably won't see any coverage statistics...\n"
separator = string(filepath.Separator)
endGoPath = separator + "src" + separator
)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。