// BuildSource invokes the compiler starting at the given root source file path. func BuildSource(rootSourceFilePath string, debug bool, vcsDevelopmentDirectories ...string) bool { // Disable logging unless the debug flag is on. if !debug { log.SetOutput(ioutil.Discard) } // Build a scope graph for the project. This will conduct parsing and type graph // construction on our behalf. log.Println("Starting build") scopeResult := scopegraph.ParseAndBuildScopeGraph(rootSourceFilePath, vcsDevelopmentDirectories, CORE_LIBRARY) outputWarnings(scopeResult.Warnings) if !scopeResult.Status { outputErrors(scopeResult.Errors) return false } // Generate the program's source. filename := path.Base(rootSourceFilePath) + ".js" mapname := filename + ".map" log.Println("Generating ES5") generated, sourceMap, err := es5.GenerateES5(scopeResult.Graph, mapname, "") if err != nil { panic(err) } marshalledMap, err := sourceMap.Build().Marshal() if err != nil { panic(err) } generated += "\n//# sourceMappingURL=" + mapname // Write the source and its map. filepath := path.Join(path.Dir(rootSourceFilePath), filename) mappath := path.Join(path.Dir(rootSourceFilePath), mapname) log.Printf("Writing generated source to %s\n", filepath) ioutil.WriteFile(filepath, []byte(generated), 0644) ioutil.WriteFile(mappath, marshalledMap, 0644) log.Println("Work completed") return true }
// Build performs the build of the source, writing the result to the response writer. func (dt *developTransaction) Build(w http.ResponseWriter, r *http.Request) { // Build a scope graph for the project. This will conduct parsing and type graph // construction on our behalf. scopeResult := scopegraph.ParseAndBuildScopeGraph(dt.rootSourceFilePath, dt.vcsDevelopmentDirectories, builder.CORE_LIBRARY) if !scopeResult.Status { dt.sourceMap = sourcemap.NewSourceMap(dt.name+".develop.js", "source/") for _, warning := range scopeResult.Warnings { dt.emitWarning(w, warning) } for _, err := range scopeResult.Errors { dt.emitError(w, err) } dt.emitInfo(w, "Build failed") dt.closeGroup(w) } else { // Generate the program's source. generated, sourceMap, err := es5.GenerateES5(scopeResult.Graph, dt.name+".develop.js", "source/") if err != nil { panic(err) } dt.sourceMap = sourceMap fmt.Fprint(w, generated) dt.emitInfo(w, "Build completed successfully") dt.closeGroup(w) dt.offsetCount = len(strings.Split(string(generated), "\n")) for _, warning := range scopeResult.Warnings { dt.emitWarning(w, warning) } } fmt.Fprintf(w, "//# sourceMappingURL=/%s.develop.js.map\n", dt.name) }
// buildAndRunTests builds the source found at the given path and then runs its tests via the runner. func buildAndRunTests(filePath string, runner TestRunner) (bool, error) { log.Printf("Building %s...", filePath) filename := path.Base(filePath) scopeResult := scopegraph.ParseAndBuildScopeGraph(filePath, []string{}, builder.CORE_LIBRARY) if !scopeResult.Status { // TODO: better output return false, fmt.Errorf("Compilation errors for test %s: %v", filePath, scopeResult.Errors) } // Generate the source. generated, sourceMap, err := es5.GenerateES5(scopeResult.Graph, filename+".js", "") if err != nil { log.Fatal(err) } // Save the source (with an adjusted call), in a temporary directory. moduleName := filename[0 : len(filename)-len(parser.SERULIAN_FILE_EXTENSION)] adjusted := fmt.Sprintf(` %s window.Serulian.then(function(global) { global.%s.TEST().then(function(a) { }).catch(function(err) { throw err; }) }) //# sourceMappingURL=/%s.js.map `, generated, moduleName, filename) dir, err := ioutil.TempDir("", "testing") if err != nil { log.Fatal(err) } // Clean up once complete. defer os.RemoveAll(dir) // Write the source and map into the directory. marshalled, err := sourceMap.Build().Marshal() if err != nil { log.Fatal(err) } err = ioutil.WriteFile(path.Join(dir, filename+".js"), []byte(adjusted), 0777) if err != nil { log.Fatal(err) } err = ioutil.WriteFile(path.Join(dir, filename+".js.map"), marshalled, 0777) if err != nil { log.Fatal(err) } // Call the runner with the test file. return runner.Run(path.Join(dir, filename+".js")) }