/// <summary> /// Start the deployment! /// </summary> private void BtStartOnButtonPressed(object sender, EventArgs eventArgs) { SetDataFromFields(); SaveProfilesList(); if (string.IsNullOrEmpty(DeployProfile.Current.SourceDirectory) || !Directory.Exists(DeployProfile.Current.SourceDirectory)) { BlinkTextBox(fl_directory, ThemeManager.Current.GenericErrorColor); return; } // init screen btStart.Visible = false; btReset.Visible = false; progressBar.Visible = true; progressBar.Progress = 0; progressBar.Text = @"Please wait, the deployment is starting..."; btReport.Visible = false; lbl_report.Visible = false; _reportExportPath = null; Application.DoEvents(); // start the deployment Task.Factory.StartNew(() => { _proEnv = new ProEnvironment.ProEnvironmentObject(ProEnvironment.Current); _currentProfile = new DeployProfile(DeployProfile.Current); // new mass compilation _currentCompil = new ProCompilation { // check if we need to force the compiler to only use 1 process // (either because the user want to, or because we have a single user mode database) MonoProcess = _currentProfile.ForceSingleProcess || _proEnv.IsDatabaseSingleUser(), NumberOfProcessesPerCore = _currentProfile.NumberProcessPerCore, RFilesOnly = _currentProfile.OnlyGenerateRcode }; _currentCompil.OnCompilationEnd += OnCompilationEnd; var filesToCompile = _proEnv.Deployer.GetFilesList(new List <string> { _currentProfile.SourceDirectory }, _currentProfile.ExploreRecursively ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly, 0); _deploymentPercentage = 0; _currentStep = 0; _totalSteps = _proEnv.Deployer.DeployTransferRules.Count > 0 ? _proEnv.Deployer.DeployTransferRules.Max(rule => rule.Step) : 0; _filesToDeployPerStep.Clear(); _hookProcedureErrors.Clear(); if (filesToCompile.Count > 0 && _currentCompil.CompileFiles(filesToCompile)) { UpdateReport(""); UpdateProgressBar(); btCancel.SafeInvoke(button => button.Visible = true); this.SafeInvoke(page => { // start a recurrent event (every second) to update the progression of the compilation _progressTimer = new Timer(); _progressTimer.Interval = 500; _progressTimer.Tick += (o, args) => UpdateProgressBar(); _progressTimer.Start(); }); } else { if (filesToCompile.Count == 0) { UserCommunication.Notify("No compilable files found in the input directories,<br>the valid extensions for compilable Progress files are : " + Config.Instance.CompileKnownExtension, MessageImg.MsgInfo, "Multiple compilation", "No files found", 10); } // nothing started ResetScreen(); } }); }
private void BuildReport() { StringBuilder currentReport = new StringBuilder(); currentReport.Append(@"<h2 style='margin-top: 8px; margin-bottom: 8px;'>Results :</h2>"); // the execution ended successfully if (_currentCompil.NumberOfProcesses == _currentCompil.NumberOfProcessesEndedOk) { var listLinesByStep = new Dictionary <int, List <Tuple <int, string> > > { { 0, new List <Tuple <int, string> >() } }; var listLinesCompilation = new List <Tuple <int, string> >(); StringBuilder line = new StringBuilder(); var totalDeployedFiles = 0; var nbDeploymentError = 0; var nbCompilationError = 0; var nbCompilationWarning = 0; // compiled files foreach (var fileToCompile in _currentCompil.GetListOfFileToCompile.OrderBy(compile => Path.GetFileName(compile.InputPath))) { var toCompile = fileToCompile; var errorsOfTheFile = _currentCompil.ErrorsList.Where(error => error.CompiledFilePath.Equals(toCompile.InputPath)).ToList(); bool hasError = errorsOfTheFile.Count > 0 && errorsOfTheFile.Exists(error => error.Level > ErrorLevel.StrongWarning); bool hasWarning = errorsOfTheFile.Count > 0 && errorsOfTheFile.Exists(error => error.Level <= ErrorLevel.StrongWarning); if (hasError || hasWarning) { // only add compilation errors line.Clear(); line.Append("<div %ALTERNATE%style=\"background-repeat: no-repeat; background-image: url('" + (hasError ? "Error30x30" : "Warning30x30") + "'); padding-left: 40px; padding-top: 6px; padding-bottom: 6px;\">"); line.Append(ProCompilation.FormatCompilationResult(fileToCompile.InputPath, errorsOfTheFile, null)); line.Append("</div>"); listLinesCompilation.Add(new Tuple <int, string>(hasError ? 3 : 2, line.ToString())); } if (hasError) { nbCompilationError++; // if compilation errors, delete all transfer records for this file since they obviously didn't happen _filesToDeployPerStep[0].RemoveAll(move => move.Origin.Equals(toCompile.InputPath)); } else if (hasWarning) { nbCompilationWarning++; } } // for each deploy step foreach (var kpv in _filesToDeployPerStep) { // group by transfer type foreach (var groupType in kpv.Value.GroupBy(deploy => deploy.DeployType).Select(deploys => deploys.ToList()).ToList().OrderBy(list => list.First().DeployType)) { // group either by directory name or by archive name var groupDirectory = groupType.First().DeployType <= DeployType.Zip ? groupType.GroupBy(deploy => deploy.ArchivePath).Select(deploys => deploys.ToList()).ToList().OrderBy(list => list.First().ArchivePath) : groupType.GroupBy(deploy => Path.GetDirectoryName(deploy.To)).Select(deploys => deploys.ToList()).ToList().OrderBy(list => Path.GetDirectoryName(list.First().To)); foreach (var group in groupDirectory) { var deployFailed = group.Exists(deploy => !deploy.IsOk); var first = group.First(); line.Clear(); line.Append("<div %ALTERNATE%style=\"background-repeat: no-repeat; background-image: url('" + (deployFailed ? "Error30x30" : "Ok30x30") + "'); padding-left: 40px; padding-top: 6px; padding-bottom: 6px;\">"); string groupBase; if (first.DeployType < DeployType.Archive) { groupBase = first.ArchivePath; var dirPath = Path.GetDirectoryName(first.TargetDir); line.Append("<div style='padding-bottom: 5px;'><img src='" + Utils.GetExtensionImage(first.DeployType == DeployType.Prolib ? "Pl": "Zip", true) + "' height='15px'><b>" + groupBase.ToHtmlLink(Path.GetFileName(groupBase)) + "</b> in " + string.Format("<a class='SubTextColor' href='{0}'>{1}</a>", dirPath, dirPath) + "</div>"); } else { groupBase = Path.GetDirectoryName(first.To); line.Append("<div style='padding-bottom: 5px;'><img src='" + Utils.GetExtensionImage(first.DeployType == DeployType.Ftp ? "Ftp" : "Folder", true) + "' height='15px'><b>" + groupBase.ToHtmlLink() + "</div>"); } foreach (var file in group.OrderBy(deploy => deploy.To)) { var ext = (Path.GetExtension(file.To) ?? "").Replace(".", ""); var transferMsg = file.DeployType == DeployType.Move ? "" : "(" + file.DeployType + ") "; line.Append("<div style='padding-left: 10px'>"); if (file.IsOk) { line.Append("<img src='" + Utils.GetExtensionImage(ext) + "' height='15px'>" + transferMsg + file.To.ToHtmlLink(file.To.Replace(groupBase, "").TrimStart('\\'))); } else { line.Append("<img src='Error30x30' height='15px'>Transfer error for " + transferMsg + file.To.Replace(_proEnv.BaseCompilationPath, "")); } line.Append(" <span style='padding-left: 8px; padding-right: 8px;'>from</span> " + string.Format("<a class='SubTextColor' href='{0}'>{1}</a>", Path.GetDirectoryName(file.Origin), file.Origin.Replace(kpv.Key <= 1 ? _proEnv.BaseLocalPath : _proEnv.BaseCompilationPath, "").TrimStart('\\'))); line.Append("</div>"); } line.Append("</div>"); if (!listLinesByStep.ContainsKey(kpv.Key)) { listLinesByStep.Add(kpv.Key, new List <Tuple <int, string> >()); } listLinesByStep[kpv.Key].Add(new Tuple <int, string>(deployFailed ? 3 : 1, line.ToString())); if (deployFailed) { nbDeploymentError += group.Count(deploy => !deploy.IsOk); } else { totalDeployedFiles += group.Count; } } } } // compilation currentReport.Append(@"<div style='padding-top: 7px; padding-bottom: 7px;'>Compiling <b>" + _currentCompil.NbFilesToCompile + "</b> files : <b>" + Utils.GetNbFilesPerType(_currentCompil.GetListOfFileToCompile.Select(compile => compile.InputPath).ToList()).Aggregate("", (current, kpv) => current + (@"<img style='padding-right: 5px;' src='" + Utils.GetExtensionImage(kpv.Key.ToString(), true) + "' height='15px'><span style='padding-right: 12px;'>x" + kpv.Value + "</span>")) + "</b></div>"); // compilation time currentReport.Append(@"<div><img style='padding-right: 20px; padding-left: 5px;' src='Time' height='15px'>Total elapsed time for the compilation : <b>" + _currentCompil.ExecutionTime + @"</b></div>"); if (nbCompilationError > 0) { currentReport.Append("<div><img style='padding-right: 20px; padding-left: 5px;' src='Error30x30' height='15px'>" + nbCompilationError + " files with compilation error(s)</div>"); } if (nbCompilationWarning > 0) { currentReport.Append("<div><img style='padding-right: 20px; padding-left: 5px;' src='Warning30x30' height='15px'>" + nbCompilationWarning + " files with compilation warning(s)</div>"); } if (_currentCompil.NbFilesToCompile - nbCompilationError - nbCompilationWarning > 0) { currentReport.Append("<div><img style='padding-right: 20px; padding-left: 5px;' src='Ok30x30' height='15px'>" + (_currentCompil.NbFilesToCompile - nbCompilationError - nbCompilationWarning) + " files compiled correctly</div>"); } // deploy currentReport.Append(@"<div style='padding-top: 7px; padding-bottom: 7px;'>Deploying <b>" + totalDeployedFiles + "</b> files : <b>" + Utils.GetNbFilesPerType(_filesToDeployPerStep.SelectMany(pair => pair.Value).Select(deploy => deploy.To).ToList()).Aggregate("", (current, kpv) => current + (@"<img style='padding-right: 5px;' src='" + Utils.GetExtensionImage(kpv.Key.ToString(), true) + "' height='15px'><span style='padding-right: 12px;'>x" + kpv.Value + "</span>")) + "</b></div>"); // deployment time currentReport.Append(@"<div><img style='padding-right: 20px; padding-left: 5px;' src='Time' height='15px'>Total elapsed time for the deployment : <b>" + _currentCompil.GetElapsedTime() + @"</b></div>"); if (nbDeploymentError > 0) { currentReport.Append("<div><img style='padding-right: 20px; padding-left: 5px;' src='Error30x30' height='15px'>" + nbDeploymentError + " files not deployed</div>"); } if (totalDeployedFiles - nbDeploymentError > 0) { currentReport.Append("<div><img style='padding-right: 20px; padding-left: 5px;' src='Ok30x30' height='15px'>" + (totalDeployedFiles - nbDeploymentError) + " files deployed correctly</div>"); } // compilation if (listLinesCompilation.Count > 0) { currentReport.Append("<h3 style='margin-top: 7px; margin-bottom: 7px;'>Compilation error details :</h3>"); var boolAlternate = false; foreach (var listLine in listLinesCompilation.OrderByDescending(tuple => tuple.Item1)) { currentReport.Append(listLine.Item2.Replace("%ALTERNATE%", boolAlternate ? "class='AlternatBackColor' " : "class='NormalBackColor' ")); boolAlternate = !boolAlternate; } } // hook procedure errors if (_hookProcedureErrors.Length > 0) { currentReport.Append("<h3 style='margin-top: 7px; margin-bottom: 7px;'>Deployment hook procedures errors :</h3>"); currentReport.Append(_hookProcedureErrors); } // deployment steps foreach (var listLinesKpv in listLinesByStep) { currentReport.Append("<h3 style='margin-top: 7px; margin-bottom: 7px;'>Deployment step " + listLinesKpv.Key + " :</h3>"); var boolAlternate2 = false; foreach (var listLine in listLinesKpv.Value.OrderByDescending(tuple => tuple.Item1)) { currentReport.Append(listLine.Item2.Replace("%ALTERNATE%", boolAlternate2 ? "class='AlternatBackColor' " : "class='NormalBackColor' ")); boolAlternate2 = !boolAlternate2; } } } else { if (_currentCompil.HasBeenCancelled) { // the process has been cancelled currentReport.Append(@"<div><img style='padding-right: 20px; padding-left: 5px;' src='Warning30x30' height='15px'>The compilation has been cancelled by the user</div>"); } else { // provide info on the possible error! currentReport.Append(@"<div><img style='padding-right: 20px; padding-left: 5px;' src='Error30x30' height='15px'>At least one process has ended in error, the compilation has been cancelled</div>"); if (_currentCompil.CompilationFailedOnMaxUser()) { currentReport.Append(@"<div><img style='padding-right: 20px; padding-left: 5px;' src='Help' height='15px'>One or more processes started for this compilation tried to connect to the database and failed because the maximum number of connection has been reached (error 748). To correct this problem, you can either :<br><li>reduce the number of processes to use for each core of your computer</li><li>or increase the maximum of connections for your database (-n parameter in the proserve command)</li></div>"); } currentReport.Append(@"<div></div>"); } } UpdateReport(currentReport.ToString()); }