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 + -
显示快捷键?