/// <summary> /// Called when a process has finished /// </summary> private void OnExecutionEnd(ProExecution lastExecution) { if (_lock.TryEnterWriteLock(500)) { try { _processesRunning--; } finally { _lock.ExitWriteLock(); } } }
/// <summary> /// Called when a process has finished UNsuccessfully /// </summary> private void OnExecutionFailed(ProExecution obj) { if (_lock.TryEnterWriteLock(500)) { try { // we kill all the processes we don't want to do anything more... KillProcesses(); } finally { _lock.ExitWriteLock(); } } }
/// <summary> /// Called when a process has finished successfully /// </summary> private void OnExecutionOk(ProExecution obj) { if (_lock.TryEnterWriteLock(500)) { try { NumberOfProcessesEndedOk++; EndOfCompilation(obj); } finally { _lock.ExitWriteLock(); } } }
/// <summary> /// Called after the execution of run/compile/check/prolint, clear the current operation from the file /// </summary> public static void OnSingleExecutionEnd(ProExecution lastExec) { try { var treatedFile = lastExec.ListToCompile.First(); CurrentOperation currentOperation; if (!Enum.TryParse(lastExec.ExecutionType.ToString(), true, out currentOperation)) { currentOperation = CurrentOperation.Run; } // Clear flag or we can't do any other actions on this file FilesInfo.GetFileInfo(treatedFile.InputPath).CurrentOperation &= ~currentOperation; var isCurrentFile = treatedFile.InputPath.EqualsCi(Plug.CurrentFilePath); if (isCurrentFile) { FilesInfo.UpdateFileStatus(); } } catch (Exception e) { ErrorHandler.ShowErrors(e, "Error in OnExecutionEnd"); } }
/// <summary> /// This method is executed when the overall compilation is over and allows to do more treatments /// </summary> private void EndOfCompilation(ProExecution obj) { // only do stuff we have reached the last running process if (_processesRunning > 0 || _hasBeenKilled) { return; } // everything ended ok, we do postprocess actions if (NumberOfProcesses == NumberOfProcessesEndedOk) { // we need to transfer all the files... (keep only distinct target files) foreach (var compilationProcess in _listOfCompilationProcesses) { TransferedFiles.AddRange(compilationProcess.ProExecutionObject.CreateListOfFilesToDeploy()); } TransferedFiles = obj.ProEnv.Deployer.DeployFiles(TransferedFiles, f => _deployPercentage = f); // Read all the log files stores the errors foreach (var compilationProcess in _listOfCompilationProcesses) { var errorList = compilationProcess.ProExecutionObject.LoadErrorLog(); foreach (var keyValue in errorList) { ErrorsList.AddRange(keyValue.Value); } } DeploymentDone = true; } ExecutionTime = GetElapsedTime(); if (OnCompilationEnd != null) { OnCompilationEnd(); } }
/// <summary> /// Called after the execution of run/compile/check/prolint, clear the current operation from the file /// </summary> public static void OnSingleExecutionEnd(ProExecution lastExec) { try { var exec = (ProExecutionHandleCompilation)lastExec; var treatedFile = exec.Files.First(); CurrentOperation currentOperation; if (!Enum.TryParse(exec.ExecutionType.ToString(), true, out currentOperation)) { currentOperation = CurrentOperation.Run; } // Clear flag or we can't do any other actions on this file OpenedFilesInfo.GetOpenedFileInfo(treatedFile.SourcePath).CurrentOperation &= ~currentOperation; var isCurrentFile = treatedFile.SourcePath.EqualsCi(Npp.CurrentFileInfo.Path); if (isCurrentFile) { OpenedFilesInfo.UpdateFileStatus(); } OpenedFilesInfo.CurrentOpenedFileInfo.ProgressExecution = null; } catch (Exception e) { ErrorHandler.ShowErrors(e, "Error in OnExecutionEnd"); } }
/// <summary> /// Called after the execution of run/compile/check/prolint /// </summary> public static void OnSingleExecutionOk(ProExecution lastExec) { try { var treatedFile = lastExec.ListToCompile.First(); CurrentOperation currentOperation; if (!Enum.TryParse(lastExec.ExecutionType.ToString(), true, out currentOperation)) currentOperation = CurrentOperation.Run; var isCurrentFile = treatedFile.InputPath.EqualsCi(Plug.CurrentFilePath); var otherFilesInError = false; int nbWarnings = 0; int nbErrors = 0; // Read log info var errorList = lastExec.LoadErrorLog(); if (!errorList.Any()) { // the compiler messages are empty var fileInfo = new FileInfo(lastExec.LogPath); if (fileInfo.Length > 0) { // the .log is not empty, maybe something went wrong in the runner, display errors UserCommunication.Notify( "Something went wrong while " + currentOperation.GetAttribute<CurrentOperationAttr>().ActionText + " the following file:<br>" + treatedFile.InputPath.ToHtmlLink() + "<br>The progress compiler didn't return any errors but the log isn't empty, here is the content :" + Utils.ReadAndFormatLogToHtml(lastExec.LogPath), MessageImg.MsgError, "Critical error", "Action failed"); return; } } else { // count number of warnings/errors, loop through files > loop through errors in each file foreach (var keyValue in errorList) { foreach (var fileError in keyValue.Value) { if (fileError.Level <= ErrorLevel.StrongWarning) nbWarnings++; else nbErrors++; } otherFilesInError = otherFilesInError || !treatedFile.InputPath.EqualsCi(keyValue.Key); } } // Prepare the notification content var notifTitle = currentOperation.GetAttribute<CurrentOperationAttr>().Name; var notifImg = (nbErrors > 0) ? MessageImg.MsgError : ((nbWarnings > 0) ? MessageImg.MsgWarning : MessageImg.MsgOk); var notifTimeOut = (nbErrors > 0) ? 0 : ((nbWarnings > 0) ? 10 : 5); var notifSubtitle = lastExec.ExecutionType == ExecutionType.Prolint ? (nbErrors + nbWarnings) + " problem" + ((nbErrors + nbWarnings) > 1 ? "s" : "") + " detected" : (nbErrors > 0) ? nbErrors + " error" + (nbErrors > 1 ? "s" : "") + " found" : ((nbWarnings > 0) ? nbWarnings + " warning" + (nbWarnings > 1 ? "s" : "") + " found" : "Syntax correct"); // build the error list var errorsList = new List<FileError>(); foreach (var keyValue in errorList) { errorsList.AddRange(keyValue.Value); } // when compiling, transfering .r/.lst to compilation dir var listTransferFiles = new List<FileToDeploy>(); if (lastExec.ExecutionType == ExecutionType.Compile) { listTransferFiles = lastExec.CreateListOfFilesToDeploy(); listTransferFiles = lastExec.ProEnv.Deployer.DeployFiles(listTransferFiles); } // Notify the user, or not if (Config.Instance.CompileAlwaysShowNotification || !isCurrentFile || !Npp.GetFocus() || otherFilesInError) UserCommunication.NotifyUnique(treatedFile.InputPath, "Was " + currentOperation.GetAttribute<CurrentOperationAttr>().ActionText + " :<br>" + ProCompilation.FormatCompilationResult(treatedFile.InputPath, errorsList, listTransferFiles), notifImg, notifTitle, notifSubtitle, null, notifTimeOut); } catch (Exception e) { ErrorHandler.ShowErrors(e, "Error in OnExecutionOk"); } }
/// <summary> /// Called after the execution of run/compile/check/prolint, clear the current operation from the file /// </summary> public static void OnSingleExecutionEnd(ProExecution lastExec) { try { var treatedFile = lastExec.ListToCompile.First(); CurrentOperation currentOperation; if (!Enum.TryParse(lastExec.ExecutionType.ToString(), true, out currentOperation)) currentOperation = CurrentOperation.Run; // Clear flag or we can't do any other actions on this file FilesInfo.GetFileInfo(treatedFile.InputPath).CurrentOperation &= ~currentOperation; var isCurrentFile = treatedFile.InputPath.EqualsCi(Plug.CurrentFilePath); if (isCurrentFile) FilesInfo.UpdateFileStatus(); } catch (Exception e) { ErrorHandler.ShowErrors(e, "Error in OnExecutionEnd"); } }
/// <summary> /// Called to run/compile/check/prolint the current program /// </summary> public static void StartProgressExec(ExecutionType executionType, Action <ProExecutionHandleCompilation> execSetter = null) { CurrentOperation currentOperation; if (!Enum.TryParse(executionType.ToString(), true, out currentOperation)) { currentOperation = CurrentOperation.Run; } // process already running? if (OpenedFilesInfo.CurrentOpenedFileInfo.CurrentOperation >= CurrentOperation.Prolint) { UserCommunication.NotifyUnique("KillExistingProcess", "This file is already being compiled, run or lint-ed.<br>Please wait the end of the previous action,<br>or click the link below to interrupt the previous action :<br><a href='#'>Click to kill the associated prowin process</a>", MessageImg.MsgRip, currentOperation.GetAttribute <CurrentOperationAttr>().Name, "Already being compiled/run", args => { KillCurrentProcess(); StartProgressExec(executionType); args.Handled = true; }, 5); return; } if (!Npp.CurrentFileInfo.IsProgress) { UserCommunication.Notify("Can only compile and run progress files!", MessageImg.MsgWarning, "Invalid file type", "Progress files only", 10); return; } if (string.IsNullOrEmpty(Npp.CurrentFileInfo.Path) || !File.Exists(Npp.CurrentFileInfo.Path)) { UserCommunication.Notify("Couldn't find the following file :<br>" + Npp.CurrentFileInfo.Path, MessageImg.MsgError, "Execution error", "File not found", 10); return; } if (!Npp.CurrentFileInfo.IsCompilable) { UserCommunication.Notify("Sorry, the file extension " + Path.GetExtension(Npp.CurrentFileInfo.Path).Quoter() + " isn't a valid extension for this action!<br><i>You can change the list of valid extensions in the settings window</i>", MessageImg.MsgWarning, "Invalid file extension", "Not an executable", 10); return; } // when running a procedure, check that a .r is not hiding the program, if that's the case we warn the user if (executionType == ExecutionType.Run && !_dontWarnAboutRCode) { if (File.Exists(Path.ChangeExtension(Npp.CurrentFileInfo.Path, ".r"))) { UserCommunication.NotifyUnique("rcodehide", "Friendly warning, an <b>r-code</b> <i>(i.e. *.r file)</i> is hiding the current program<br>If you modified it since the last compilation you might not have the expected behavior...<br><br><i>" + "stop".ToHtmlLink("Click here to not show this message again for this session") + "</i>", MessageImg.MsgWarning, "Progress execution", "An Rcode hides the program", args => { _dontWarnAboutRCode = true; UserCommunication.CloseUniqueNotif("rcodehide"); }, 5); } } // update function prototypes ProGenerateCode.Factory.UpdateFunctionPrototypesIfNeeded(true); // launch the compile process for the current file OpenedFilesInfo.CurrentOpenedFileInfo.ProgressExecution = (ProExecutionHandleCompilation)ProExecution.Factory(executionType); OpenedFilesInfo.CurrentOpenedFileInfo.ProgressExecution.Files = new List <FileToCompile> { new FileToCompile(Npp.CurrentFileInfo.Path) }; OpenedFilesInfo.CurrentOpenedFileInfo.ProgressExecution.OnExecutionEnd += OnSingleExecutionEnd; if (execSetter != null) { execSetter(OpenedFilesInfo.CurrentOpenedFileInfo.ProgressExecution); OpenedFilesInfo.CurrentOpenedFileInfo.ProgressExecution.OnCompilationOk += OnGenerateDebugFileOk; } else { OpenedFilesInfo.CurrentOpenedFileInfo.ProgressExecution.OnCompilationOk += OnSingleExecutionOk; } if (!OpenedFilesInfo.CurrentOpenedFileInfo.ProgressExecution.Start()) { return; } // change file object current operation, set flag OpenedFilesInfo.CurrentOpenedFileInfo.CurrentOperation |= currentOperation; OpenedFilesInfo.UpdateFileStatus(); // clear current errors (updates the current file info) OpenedFilesInfo.ClearAllErrors(Npp.CurrentFileInfo.Path, true); }
/// <summary> /// This method is executed when the overall compilation is over and allows to do more treatments /// </summary> private void EndOfCompilation(ProExecution obj) { // only do stuff we have reached the last running process if (_processesRunning > 0 || _hasBeenKilled) return; // everything ended ok, we do postprocess actions if (NumberOfProcesses == NumberOfProcessesEndedOk) { // we need to transfer all the files... (keep only distinct target files) foreach (var compilationProcess in _listOfCompilationProcesses) { TransferedFiles.AddRange(compilationProcess.ProExecutionObject.CreateListOfFilesToDeploy()); } TransferedFiles = obj.ProEnv.Deployer.DeployFiles(TransferedFiles, f => _deployPercentage = f); // Read all the log files stores the errors foreach (var compilationProcess in _listOfCompilationProcesses) { var errorList = compilationProcess.ProExecutionObject.LoadErrorLog(); foreach (var keyValue in errorList) { ErrorsList.AddRange(keyValue.Value); } } DeploymentDone = true; } ExecutionTime = GetElapsedTime(); if (OnCompilationEnd != null) OnCompilationEnd(); }
/// <summary> /// Method called after the execution of the program extracting the db info /// </summary> private static void ExtractionDoneOk(ProExecution lastExec) { // copy the dump to the folder database if (Utils.CopyFile(lastExec.ExtractDbOutputPath, Path.Combine(Config.FolderDatabase, Path.GetFileName(lastExec.ExtractDbOutputPath) ?? ""))) { // update info UpdateDatabaseInfo(); UserCommunication.Notify("Database structure extracted with success!<br>The auto-completion has been updated with the latest info, enjoy!", MessageImg.MsgOk, "Database info", "Extracting database structure", 10); if (_onExtractionDone != null) { _onExtractionDone(); _onExtractionDone = null; } } }
/// <summary> /// Should be called to extract the database info from the current environnement /// </summary> public static void FetchCurrentDbInfo(Action onExtractionDone) { try { // dont extract 2 db at once if (_isExtracting) { UserCommunication.Notify("Already fetching info for another environment, please wait the end of the previous execution!", MessageImg.MsgWarning, "Database info", "Extracting database structure", 5); return; } // save the filename of the output database info file for this environment UserCommunication.Notify("Now fetching info on all the connected databases for the current environment<br>You will be warned when the process is over", MessageImg.MsgInfo, "Database info", "Extracting database structure", 5); var exec = new ProExecution { OnExecutionEnd = execution => _isExtracting = false, OnExecutionOk = ExtractionDoneOk, NeedDatabaseConnection = true, ExtractDbOutputPath = GetOutputName }; _onExtractionDone = onExtractionDone; _isExtracting = exec.Do(ExecutionType.Database); } catch (Exception e) { ErrorHandler.ShowErrors(e, "FetchCurrentDbInfo"); } }
/// <summary> /// Called after the execution of run/compile/check/prolint /// </summary> public static void OnSingleExecutionOk(ProExecution lastExec) { try { var treatedFile = lastExec.ListToCompile.First(); CurrentOperation currentOperation; if (!Enum.TryParse(lastExec.ExecutionType.ToString(), true, out currentOperation)) { currentOperation = CurrentOperation.Run; } var isCurrentFile = treatedFile.InputPath.EqualsCi(Plug.CurrentFilePath); var otherFilesInError = false; int nbWarnings = 0; int nbErrors = 0; // Read log info var errorList = lastExec.LoadErrorLog(); if (!errorList.Any()) { // the compiler messages are empty var fileInfo = new FileInfo(lastExec.LogPath); if (fileInfo.Length > 0) { // the .log is not empty, maybe something went wrong in the runner, display errors UserCommunication.Notify( "Something went wrong while " + currentOperation.GetAttribute <CurrentOperationAttr>().ActionText + " the following file:<br>" + treatedFile.InputPath.ToHtmlLink() + "<br>The progress compiler didn't return any errors but the log isn't empty, here is the content :" + Utils.ReadAndFormatLogToHtml(lastExec.LogPath), MessageImg.MsgError, "Critical error", "Action failed"); return; } } else { // count number of warnings/errors, loop through files > loop through errors in each file foreach (var keyValue in errorList) { foreach (var fileError in keyValue.Value) { if (fileError.Level <= ErrorLevel.StrongWarning) { nbWarnings++; } else { nbErrors++; } } otherFilesInError = otherFilesInError || !treatedFile.InputPath.EqualsCi(keyValue.Key); } } // Prepare the notification content var notifTitle = currentOperation.GetAttribute <CurrentOperationAttr>().Name; var notifImg = (nbErrors > 0) ? MessageImg.MsgError : ((nbWarnings > 0) ? MessageImg.MsgWarning : MessageImg.MsgOk); var notifTimeOut = (nbErrors > 0) ? 0 : ((nbWarnings > 0) ? 10 : 5); var notifSubtitle = lastExec.ExecutionType == ExecutionType.Prolint ? (nbErrors + nbWarnings) + " problem" + ((nbErrors + nbWarnings) > 1 ? "s" : "") + " detected" : (nbErrors > 0) ? nbErrors + " error" + (nbErrors > 1 ? "s" : "") + " found" : ((nbWarnings > 0) ? nbWarnings + " warning" + (nbWarnings > 1 ? "s" : "") + " found" : "Syntax correct"); // build the error list var errorsList = new List <FileError>(); foreach (var keyValue in errorList) { errorsList.AddRange(keyValue.Value); } // when compiling, transfering .r/.lst to compilation dir var listTransferFiles = new List <FileToDeploy>(); if (lastExec.ExecutionType == ExecutionType.Compile) { listTransferFiles = lastExec.CreateListOfFilesToDeploy(); listTransferFiles = lastExec.ProEnv.Deployer.DeployFiles(listTransferFiles); } // Notify the user, or not if (Config.Instance.CompileAlwaysShowNotification || !isCurrentFile || !Npp.GetFocus() || otherFilesInError) { UserCommunication.NotifyUnique(treatedFile.InputPath, "Was " + currentOperation.GetAttribute <CurrentOperationAttr>().ActionText + " :<br>" + ProCompilation.FormatCompilationResult(treatedFile.InputPath, errorsList, listTransferFiles), notifImg, notifTitle, notifSubtitle, null, notifTimeOut); } } catch (Exception e) { ErrorHandler.ShowErrors(e, "Error in OnExecutionOk"); } }
private void ExecuteDeploymentHook() { // launch the compile process for the current file if (File.Exists(Config.FileDeploymentHook)) { _executingHook = true; try { var hookExec = new ProExecution { DeploymentStep = _currentStep, DeploymentSourcePath = _currentProfile.SourceDirectory }; if (hookExec.Do(ExecutionType.DeploymentHook)) { hookExec.Process.WaitForExit(); var fileInfo = new FileInfo(hookExec.LogPath); if (fileInfo.Length > 0) { // the .log is not empty, maybe something went wrong in the runner, display errors UserCommunication.Notify( "Something went wrong while executing the deployment hook procedure:<br>" + Config.FileDeploymentHook.ToHtmlLink() + "<br>The following problems were logged :" + Utils.ReadAndFormatLogToHtml(hookExec.LogPath), MessageImg.MsgError, "Deployment hook procedure", "Execution failed"); _hookProcedureErrors.Append("The execution for step " + _currentStep + " returned the following errors :" + Utils.ReadAndFormatLogToHtml(hookExec.LogPath)); } } } finally { _executingHook = false; } } }