worker.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 698 行 · 第 1/2 页
SCALA
698 行
for (file <- files) { runInContext(file, kind, (logFile: File, outDir: File) => { if (!compileMgr.shouldFailCompile(file, kind, logFile)) { succeeded = false } else { // compare log file to check file val fileBase = basename(file.getName) val dir = file.getParentFile if (!existsCheckFile(dir, fileBase, kind)) { // diff is contents of logFile diff = file2String(logFile) } else diff = compareOutput(dir, fileBase, kind, logFile) if (!diff.equals("")) { NestUI.verbose("output differs from log file\n") succeeded = false } } }) } case "run" => for (file <- files) { runJvmTest(file, kind) } case "jvm" => for (file <- files) { runJvmTest(file, kind) } case "jvm5" => for (file <- files) { runJvmTest(file, kind) } case "res" => { for (file <- files) { // when option "--failed" is provided // execute test only if log file is present // (which means it failed before) //val (logFileOut, logFileErr) = createLogFiles(file, kind) val logFile = createLogFile(file, kind) if (!fileManager.failed || (logFile.exists && logFile.canRead)) { val swr = new StringWriter val wr = new PrintWriter(swr) succeeded = true; diff = ""; log = "" printInfoStart(file, wr) val fileBase: String = basename(file.getName) NestUI.verbose(this+" running test "+fileBase) val dir = file.getParentFile val outDir = createOutputDir(dir, fileBase, kind) if (!outDir.exists) outDir.mkdir() val resFile = new File(dir, fileBase + ".res") NestUI.verbose("outDir: "+outDir) NestUI.verbose("logFile: "+logFile) //NestUI.verbose("logFileErr: "+logFileErr) NestUI.verbose("resFile: "+resFile) // run compiler in resident mode // $SCALAC -d "$os_dstbase".obj -Xresident -sourcepath . "$@" try { val sourcedir = logFile.getParentFile.getCanonicalFile val sourcepath = sourcedir.getAbsolutePath+File.separator NestUI.verbose("sourcepath: "+sourcepath) val argString = "-d "+outDir.getCanonicalFile.getAbsolutePath+ " -Xresident"+ " -sourcepath "+sourcepath val argList = List.fromString(argString, ' ') // configure input/output files val logOut = new FileOutputStream(logFile) val logWriter = new PrintStream(logOut) val resReader = new BufferedReader(new FileReader(resFile)) val logConsoleWriter = new PrintWriter(new OutputStreamWriter(logOut)) // create compiler val settings = new Settings(error) settings.sourcepath.value = sourcepath settings.classpath.value = fileManager.CLASSPATH reporter = new ConsoleReporter(settings, Console.in, logConsoleWriter) val command = new CompilerCommand(argList, settings, error, false) object compiler extends Global(command.settings, reporter) // simulate resident compiler loop val prompt = "\nnsc> " val resCompile = (line: String) => { NestUI.verbose("compiling "+line) val cmdArgs = List.fromString(line, ' ') map { fs => new File(dir, fs).getAbsolutePath } NestUI.verbose("cmdArgs: "+cmdArgs) val sett = new Settings(error) sett.sourcepath.value = sourcepath val command = new CompilerCommand(cmdArgs, sett, error, true) (new compiler.Run) compile command.files } def loop(action: (String) => Unit) { logWriter.print(prompt) val line = resReader.readLine() if ((line ne null) && line.length() > 0) { action(line) loop(action) } } val oldStdOut = System.out val oldStdErr = System.err System.setOut(logWriter) System.setErr(logWriter) loop(resCompile) resReader.close() logWriter.flush() logWriter.close() System.setOut(oldStdOut) System.setErr(oldStdErr) val tempLogFile = new File(dir, ".temp.log") val logFileReader = new BufferedReader(new FileReader(logFile)) val tempLogFilePrinter = new PrintWriter(new FileWriter(tempLogFile)) val appender = new StreamAppender(logFileReader, tempLogFilePrinter) // function that removes a given string from another string def removeFrom(line: String, path: String): String = { // find `path` in `line` val index = line.indexOf(path) if (index != -1) { line.substring(0, index) + line.substring(index + path.length, line.length) } else line } appender.runAndMap({ s => val woPath = removeFrom(s, dir.getAbsolutePath/*.replace(File.separatorChar,'/')*/+File.separator) // now replace single '\' with '/' woPath.replace('\\', '/') }) logFileReader.close() tempLogFilePrinter.close() val tempLogFileReader = new BufferedReader(new FileReader(tempLogFile)) val logFilePrinter= new PrintWriter(new FileWriter(logFile), true) (new StreamAppender(tempLogFileReader, logFilePrinter)).run tempLogFileReader.close() logFilePrinter.close() tempLogFile.delete() diff = compareOutput(dir, fileBase, kind, logFile) if (!diff.equals("")) { NestUI.verbose("output differs from log file\n") succeeded = false } } catch { case e: Exception => e.printStackTrace() succeeded = false } // delete log file only if test was successful if (succeeded) logFile.toDelete = true if (!succeeded) { errors += 1 NestUI.verbose("incremented errors: "+errors) } printInfoEnd(succeeded, wr) wr.flush() swr.flush() NestUI.normal(swr.toString) if (!succeeded && fileManager.showDiff) NestUI.normal(diff) if (!succeeded && fileManager.showLog) showLog(logFile) } } } case "shootout" => { for (file <- files) { // when option "--failed" is provided // execute test only if log file is present // (which means it failed before) val logFile = createLogFile(file, kind) if (!fileManager.failed || (logFile.exists && logFile.canRead)) { val swr = new StringWriter val wr = new PrintWriter(swr) succeeded = true; diff = ""; log = "" printInfoStart(file, wr) val fileBase: String = basename(file.getName) NestUI.verbose(this+" running test "+fileBase) val dir = file.getParentFile val outDir = createOutputDir(dir, fileBase, kind) if (!outDir.exists) outDir.mkdir() // 2. define file {outDir}/test.scala that contains code to compile/run val testFile = new File(outDir, "test.scala") NestUI.verbose("outDir: "+outDir) NestUI.verbose("logFile: "+logFile) NestUI.verbose("testFile: "+testFile) // 3. cat {test}.scala.runner {test}.scala > testFile val runnerFile = new File(dir, fileBase+".scala.runner") val bodyFile = new File(dir, fileBase+".scala") val appender = StreamAppender.concat(new FileInputStream(runnerFile), new FileInputStream(bodyFile), new FileOutputStream(testFile)) appender.run() try { // *catch-all* // 4. compile testFile if (!compileMgr.shouldCompile(testFile, kind, logFile)) { NestUI.verbose("compilation of "+file+" failed\n") succeeded = false } else { NestUI.verbose("compilation of "+testFile+"succeeded") // -------- run test -------- //TODO: detect whether we have to use Runtime.exec val useRuntime = true if (useRuntime) execTest(outDir, logFile, fileBase) else execTestObjectRunner(file, outDir, logFile) NestUI.verbose(this+" finished running "+fileBase) } // successful compile } catch { // *catch-all* case e: Exception => NestUI.verbose("caught "+e) succeeded = false } diff = compareOutput(dir, fileBase, kind, logFile) if (!diff.equals("")) { NestUI.verbose("output differs from log file\n") succeeded = false } // delete log file only if test was successful if (succeeded) logFile.toDelete = true if (!succeeded) { errors += 1 NestUI.verbose("incremented errors: "+errors) } printInfoEnd(succeeded, wr) wr.flush() swr.flush() NestUI.normal(swr.toString) if (!succeeded && fileManager.showDiff) NestUI.normal(diff) if (!succeeded && fileManager.showLog) showLog(logFile) } } } case "script" => { for (file <- files) { // when option "--failed" is provided // execute test only if log file is present // (which means it failed before) val logFile = createLogFile(file, kind) if (!fileManager.failed || (logFile.exists && logFile.canRead)) { val swr = new StringWriter val wr = new PrintWriter(swr) succeeded = true; diff = ""; log = "" printInfoStart(file, wr) val fileBase: String = basename(file.getName) NestUI.verbose(this+" running test "+fileBase) // check whether there is an args file val argsFile = new File(file.getParentFile, fileBase+".args") NestUI.verbose("argsFile: "+argsFile) val argString = if (argsFile.exists) { val swriter = new StringWriter val app = StreamAppender(new BufferedReader(new FileReader(argsFile)), swriter) app.run() " "+swriter.toString } else "" try { val proc = Runtime.getRuntime.exec(file.getAbsolutePath+argString) val in = proc.getInputStream val err = proc.getErrorStream val writer = new PrintWriter(new FileWriter(logFile), true) val inApp = new StreamAppender(new BufferedReader(new InputStreamReader(in)), writer) val errApp = new StreamAppender(new BufferedReader(new InputStreamReader(err)), writer) val async = new Thread(errApp) async.start() inApp.run() async.join() writer.close() diff = compareOutput(file.getParentFile, fileBase, kind, logFile) if (!diff.equals("")) { NestUI.verbose("output differs from log file\n") succeeded = false } } catch { // *catch-all* case e: Exception => NestUI.verbose("caught "+e) succeeded = false } // delete log file only if test was successful if (succeeded) logFile.toDelete = true if (!succeeded) { errors += 1 NestUI.verbose("incremented errors: "+errors) } printInfoEnd(succeeded, wr) wr.flush() swr.flush() NestUI.normal(swr.toString) if (!succeeded && fileManager.showDiff) NestUI.normal(diff) if (!succeeded && fileManager.showLog) showLog(logFile) } } } } NestUI.verbose("finished testing "+kind+" with "+errors+" errors") NestUI.verbose("created "+compileMgr.numSeparateCompilers+" separate compilers") (files.length-errors, errors) } def showLog(logFile: File) { val logReader = new BufferedReader(new FileReader(logFile)) val strWriter = new StringWriter val logWriter = new PrintWriter(strWriter, true) val logAppender = new StreamAppender(logReader, logWriter) logAppender.run() logReader.close() val log = strWriter.toString NestUI.normal(log) }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?