/// <summary> /// Make sure isCompiling() == true as setCompilingTrue() was called /// Make sure all parameters are not null /// Make sure this method is thread-safety: it cannot be called at the same time /// </summary> /// <param name="cmd"></param> /// <param name="workingDir"></param> /// <returns></returns> public TCompileResult compile(string cmd, string workingDir) { int oldTick = SystemUtils.getCurrentTimeMs(); ICmdParser parser = CmdParserFactory.createCmdParser(cmd); List <string> inputFilePaths = null; string outputFilePath = null; TCompileResult result = null; if (!isAllowCompiling()) { result = new TCompileResult(false, 1, "error: Compiling is stopped!", 0, null); goto my_end; } try { parser.getInOutFilePath(workingDir, out inputFilePaths, out outputFilePath); } catch (Exception ex) { // Error result = new TCompileResult(false, 1, "error: " + ex.Message, 0, null); goto my_end; } if (inputFilePaths == null || inputFilePaths.Count == 0 || outputFilePath == null) { // Error result = new TCompileResult(false, 1, "error: Invalid command, input file is mandatory!", 0, null); goto my_end; } outputFilePath = PathUtils.combine(workingDir, outputFilePath); if (!isConnected()) { // Local goto my_end; } #region Distribute // Send the input files to server foreach (string inputFilePath in inputFilePaths) { string f = PathUtils.combine(workingDir, inputFilePath); string fNormal = PathUtils.normalizePath(f); if (!m_sentFiles.Contains(fNormal)) { if (sendFile(f)) { m_sentFiles.Add(fNormal); } else { // Local goto my_end; } } } // Send compile request to server string cmdToSend = parser.makeNetworkCmd(); Message msg = MessageCompileRequest.createMessage(cmdToSend); if (!m_messageStream.writeMessage(msg)) { goto my_end; } if (!isAllowCompiling()) { result = new TCompileResult(false, 1, "error: Compiling is stopped!", 0, null); goto my_end; } // Receive the compile result msg = m_messageStream.readMessage(); if (msg == null) { goto my_end; } if (!isAllowCompiling()) { result = new TCompileResult(false, 1, "error: Compiling is stopped!", 0, null); goto my_end; } // Parse and check the compile result MessageCompileResponse msgCompileRes = new MessageCompileResponse(msg); if (msgCompileRes.getWasExec() && msgCompileRes.getExitCode() != 0) { // Compile error // Nghia: TODO rem this for the hot fix //result = new TCompileResult(true, msgCompileRes.getExitCode(), msgCompileRes.getOutputText(), 0, m_host); goto my_end; } if (!msgCompileRes.getWasExec()) { goto my_end; } // Compile OK by server // Save the file to disk if (!IOUtils.writeFile_Bytes(outputFilePath, msgCompileRes.getOFileData(), msgCompileRes.getOFileOffset(), msgCompileRes.getOFileSize())) { // No need to compile local as this is a serious error result = new TCompileResult(true, 1, "error: Could not save the output file to disk", 0, m_host); goto my_end; } // Everything is OK result = new TCompileResult(true, 0, "Remotely compiled from " + m_host + "\n" + msgCompileRes.getOutputText(), 0, m_host); #endregion my_end: if (result == null) { // Local string specOutFilePath = parser.getLocalSpecificOutputFilePath(); string specCmd = parser.getLocalSpecificCommand(); string specWorkingDir = parser.getLocalSpecificWorkingDir(); if (specOutFilePath == null) { specOutFilePath = outputFilePath; } if (specCmd == null) { specCmd = cmd; } if (specWorkingDir == null) { specWorkingDir = workingDir; } specOutFilePath = PathUtils.combine(specWorkingDir, specOutFilePath); TProcessResult res = null; if (parser.needToLockLocal()) { lock (s_lock) { doLocal(specCmd, specWorkingDir, specOutFilePath, ref oldTick, ref res); } } else { doLocal(specCmd, specWorkingDir, specOutFilePath, ref oldTick, ref res); } result = new TCompileResult(res.wasExec, res.exitCode, "Locally compiled\n" + res.outputText, 0, null); if (result.wasExec && result.exitCode == 0 && specOutFilePath != outputFilePath) { File.Move(specOutFilePath, outputFilePath); } } result.spentTimeMs = SystemUtils.getCurrentTimeMs() - oldTick; setCompiling(false); return(result); }
private bool buildCommandFile(string[] args) { DateTime totalTimeBegin = DateTime.Now; string file = null; int jobs = s_kDefaultJobs; bool verbose = false; for (int i = 1; i < args.Length; i++) { if (args[i] == "-file") { if (i + 1 >= args.Length) { break; } file = args[i + 1]; i++; } else if (args[i] == "-jobs") { if (i + 1 >= args.Length) { break; } jobs = StringUtils.convertString2Int(args[i + 1]); i++; } else if (args[i] == "-verbose") { verbose = true; } } if (jobs <= 0 || jobs > s_kDefaultJobs) { jobs = s_kDefaultJobs; } if (file == null) { CConsole.writeError("error: The value for the option '-file' must be specified.\n"); printUsage(); return(false); } file = Path.GetFullPath(file); if (!File.Exists(file)) { CConsole.writeError("error: Could not found the file " + file + ".\n"); return(false); } lock (m_lock) { m_builder = new Builder(); } string workingDir = Path.GetDirectoryName(file); using (StreamReader reader = new StreamReader(file)) { string cmd; while ((cmd = reader.ReadLine()) != null) { cmd = cmd.Trim(); if (cmd.Length == 0 || cmd.StartsWith("//")) { continue; } string project = "Project"; if (cmd[0] == '*') { int index = cmd.IndexOf(' '); if (index == -1) { CConsole.writeError("error: Invalid compile command " + cmd + ".\n"); return(false); } project = cmd.Substring(1, index - 1); cmd = cmd.Substring(index + 1).Trim(); if (cmd.Length == 0) { continue; } } // Parse the cmd ICmdParser parser = CmdParserFactory.createCmdParser(cmd); string alias = parser.getAlias(); if (alias == null) { CConsole.writeError("error: Invalid command " + cmd + "\n"); return(false); } TCommand tCommand = new TCommand(cmd, cmd, workingDir, alias, ECommandType.eCompile, project); m_builder.addCommand(tCommand); } } bool result = m_builder.build(verbose, jobs); m_builder = null; CConsole.writeTime("Total time: " + (DateTime.Now - totalTimeBegin).ToString() + "\n\n"); return(result); }
private void handleMessageCompile(Message msg) { MessageCompileRequest msgCompile = null; try { msgCompile = new MessageCompileRequest(msg); } catch (Exception) { // Ignore return; } string cmd = msgCompile.getCmd(); ICmdParser parser = CmdParserFactory.createCmdParser(cmd); string outputFileName; cmd = parser.makeServerCmd(m_sessionFolderPath, out outputFileName, m_debugPrefixMap); string alias = parser.getAlias(); Message respondMessage = null; bool ok = false; if (alias != null && outputFileName != null) { // Compile CConsole.writeInfoLine(string.Format("{0} Recv a compile request: {1}", cur(), alias)); string outputFilePath = m_sessionFolderPath + outputFileName; string workingDir = parser.getLocalSpecificWorkingDir(); if (workingDir == null) { workingDir = m_sessionFolderPath; } TProcessResult pr = m_processCompile.execute(cmd, workingDir, outputFilePath); if (!pr.wasExec || pr.exitCode != 0) { CConsole.writeInfoLine( string.Format("{0} Compile error: wasExec=[{1}], exitCode=[{2}], cmd=[{3}], outputText=[{4}]", cur(), pr.wasExec, pr.exitCode, cmd, pr.outputText) ); respondMessage = MessageCompileResponse.createMessage(pr.wasExec, pr.exitCode, pr.outputText, null, 0); } else { ok = true; // Read the output file from disk byte[] buffer = IOUtils.readFile_Bytes(outputFilePath); int fileSize = buffer == null ? 0 : buffer.Length; respondMessage = MessageCompileResponse.createMessage( pr.wasExec, pr.exitCode, pr.outputText, buffer, fileSize); } } else { CConsole.writeInfoLine(string.Format("{0} Receive a compile request but it is a invalid command", cur())); respondMessage = MessageCompileResponse.createMessage(false, 0, "error: Invalid compile command!", null, 0); } CConsole.writeInfoLine(string.Format("{0} Send compile result: {1}, success = {2}", cur(), alias != null ? alias : "[no file]", ok)); m_messageStream.writeMessage(respondMessage); }