// Find an unused port func getFreePort() (port int) { conn, err := net.Listen("tcp", ":0") if err != nil { glog.Fatal(err) } port = conn.Addr().(*net.TCPAddr).Port err = conn.Close() if err != nil { glog.Fatal(err) } return port }
// findSrcPaths uses the "go/build" package to find the source root for Revel // and the app. func findSrcPaths(importPath string) (revelSourcePath, appSourcePath string) { var ( gopaths = filepath.SplitList(build.Default.GOPATH) goroot = build.Default.GOROOT ) if len(gopaths) == 0 { glog.Fatal("GOPATH environment variable is not set. ", "Please refer to http://golang.org/doc/code.html to configure your Go environment.") } if ContainsString(gopaths, goroot) { glog.Fatalf("GOPATH (%s) must not include your GOROOT (%s). "+ "Please refer to http://golang.org/doc/code.html to configure your Go environment.", gopaths, goroot) } appPkg, err := build.Import(importPath, "", build.FindOnly) if err != nil { glog.Fatalln("Failed to import", importPath, "with error:", err) } revelPkg, err := build.Import(REVEL_IMPORT_PATH, "", build.FindOnly) if err != nil { glog.Fatalln("Failed to find Revel with error:", err) } return revelPkg.SrcRoot, appPkg.SrcRoot }
func Init() { // Read configuration. var found bool if Driver, found = revel.Config.String("db.driver"); !found { glog.Fatal("No db.driver found.") } if Spec, found = revel.Config.String("db.spec"); !found { glog.Fatal("No db.spec found.") } // Open a connection. var err error Db, err = sql.Open(Driver, Spec) if err != nil { glog.Fatal(err) } }
// Build the app: // 1. Generate the the main.go file. // 2. Run the appropriate "go build" command. // Requires that revel.Init has been called previously. // Returns the path to the built binary, and an error if there was a problem building it. func Build() (app *App, compileError *revel.Error) { start := time.Now() // First, clear the generated files (to avoid them messing with ProcessSource). cleanSource("tmp", "routes") sourceInfo, compileError := ProcessSource(revel.CodePaths) if compileError != nil { return nil, compileError } // Add the db.import to the import paths. if dbImportPath, found := revel.Config.String("db.import"); found { sourceInfo.InitImportPaths = append(sourceInfo.InitImportPaths, dbImportPath) } // Generate two source files. templateArgs := map[string]interface{}{ "Controllers": sourceInfo.ControllerSpecs(), "ValidationKeys": sourceInfo.ValidationKeys, "ImportPaths": calcImportAliases(sourceInfo), "TestSuites": sourceInfo.TestSuites(), } genSource("tmp", "main.go", MAIN, templateArgs) genSource("routes", "routes.go", ROUTES, templateArgs) // Read build config. buildTags := revel.Config.StringDefault("build.tags", "") // Build the user program (all code under app). // It relies on the user having "go" installed. goPath, err := exec.LookPath("go") if err != nil { glog.Fatalf("Go executable not found in PATH.") } pkg, err := build.Default.Import(revel.ImportPath, "", build.FindOnly) if err != nil { glog.Fatalln("Failure importing", revel.ImportPath) } binName := filepath.Join(pkg.BinDir, filepath.Base(revel.BasePath)) if runtime.GOOS == "windows" { binName += ".exe" } gotten := make(map[string]struct{}) for { buildCmd := exec.Command(goPath, "build", "-i", "-tags", buildTags, "-o", binName, path.Join(revel.ImportPath, "app", "tmp")) glog.V(1).Infoln("Exec:", buildCmd.Args) output, err := buildCmd.CombinedOutput() // If the build succeeded, we're done. if err == nil { glog.Infof("Build took %s", time.Since(start)) return NewApp(binName), nil } glog.Error(string(output)) // See if it was an import error that we can go get. matches := importErrorPattern.FindStringSubmatch(string(output)) if matches == nil { return nil, newCompileError(output) } // Ensure we haven't already tried to go get it. pkgName := matches[1] if _, alreadyTried := gotten[pkgName]; alreadyTried { return nil, newCompileError(output) } gotten[pkgName] = struct{}{} // Execute "go get <pkg>" getCmd := exec.Command(goPath, "get", pkgName) glog.V(1).Infoln("Exec:", getCmd.Args) getOutput, err := getCmd.CombinedOutput() if err != nil { glog.Error(string(getOutput)) return nil, newCompileError(output) } // Success getting the import, attempt to build again. } glog.Fatal("Not reachable") return nil, nil }