private void AddBuildJob(IPipelineRunManager pipelineRunManager, BuildJob job, List <RunnableJob> runnableJobs, HashSet <BuildJob> dependentJobs, IDictionary <BuildJob, IJobStatus> jobMap) { if (dependentJobs.Contains(job)) { throw new CircularDependencyException(); } if (jobMap.ContainsKey(job)) { return; } dependentJobs.Add(job); foreach (var input in job.Input) { switch (input.Source) { case ArtifactBuildInput artifact: AddBuildJob(pipelineRunManager, artifact.Job, runnableJobs, dependentJobs, jobMap); break; } } dependentJobs.Remove(job); var runnable = new RunnableJob(pipelineRunManager, job, jobMap); jobMap.Add(job, runnable.JobStatus); runnableJobs.Add(runnable); }
public static IJob GetJob(ICloudStampyLogger logger, CloudStampyParameters args, StampyJobType requestedJobType) { IJob job = null; switch (requestedJobType) { case StampyJobType.None: break; case StampyJobType.CreateService: job = new ServiceCreationJob(logger, args); break; case StampyJobType.Build: job = new BuildJob(logger, args); break; case StampyJobType.Deploy: job = new DeploymentJob(logger, args); break; case StampyJobType.Test: job = new TestJob(logger, args); break; case StampyJobType.RemoveResources: job = new ScavengerJob(logger, args); break; default: break; } return(job); }
private void SanityCheckBuildJobs(Project[] CheckProjects) { // check that project, config and platform strings in build jobs are valid // remove invalid ones string[] SolutionConfigs; string[] SolutionPlatforms; GetSolutionConfigsAndPlatforms(out SolutionConfigs, out SolutionPlatforms); foreach (var JobSet in _BuildJobSetsCollection) { for (int JobIdx = JobSet.BuildJobs.Count - 1; JobIdx >= 0; JobIdx--) { BuildJob Job = JobSet.BuildJobs[JobIdx]; bool bProjectOkay = CheckProjects.Any(Proj => String.CompareOrdinal(Job.Project.FullName, Proj.FullName) == 0); bool bConfigOkay = SolutionConfigs.Any(Config => String.CompareOrdinal(Job.Config, Config) == 0); bool bPlatformOkay = SolutionPlatforms.Any(Platform => String.CompareOrdinal(Job.Platform, Platform) == 0); if (!bProjectOkay || !bConfigOkay || !bPlatformOkay) { JobSet.BuildJobs.RemoveAt(JobIdx); } } } }
// Called when this building is committed (goes from a queued/placement state to actually being in the world) public void Commit() { Completed = false; BuildingStatus.maxHP = finishedBuilding.GetComponent<BuildingStatus>().maxHP; BuildingStatus.SetHP(1); GameUtil.RescanPathfinding(); BuildJob = new BuildJob(this, Owner, true); }
private static void OnOutputTextChanged(DependencyObject Obj, DependencyPropertyChangedEventArgs Args) { BuildJob ThisBuildJob = (BuildJob)Obj; if (ThisBuildJob != null) { ThisBuildJob.HasOutputText = !String.IsNullOrEmpty(ThisBuildJob.OutputText); } }
private static void OnJobStatusChanged(DependencyObject Obj, DependencyPropertyChangedEventArgs Args) { BuildJob ThisBuildJob = (BuildJob)Obj; if (ThisBuildJob != null) { ThisBuildJob.JobStatusDisplayString = ThisBuildJob.GetJobStatusString(); } }
public void StartTask(BuildJob buildJob) { if(BuildJob != buildJob) { BuildJob = buildJob; HasStartedBuilding = false; if(!BuildJob.AllSubJobsComplete) { Debug.LogError("All build sub jobs are not complete! We shouldn't be building yet."); } } }
private void OpenItemOutputCommandExecuted(object sender, ExecutedRoutedEventArgs e) { BuildJob Job = e.Parameter as BuildJob; if (Job == null) { return; } DisplayBatchOutputText(Job.OutputText); }
public void correctly_maps_succesful_build() { const string project = "project"; const string buildName = "build"; const string user = "******"; var startDate = DateTime.Now; var finishDate = startDate.AddMinutes(12); var build = new BuildJob { Project = new Project { Name = project }, Name = buildName, BuildCollection = new BuildCollection { Builds = new[] { new Build { StartDate = startDate, FinishDate = finishDate, State = BuildState.Finished, Status = BuildStatus.Success, Trigger = new BuildTrigger { Type = TriggerType.User, User = new TeamCityUser { Name = user } } } } } }; var result = _buildMapper.Map(new[] { build }); result.ShouldHaveSingleItem(); var models = result[project]; models.ShouldNotBeNull(); models.ShouldHaveSingleItem(); var model = models.First(); model.ShouldNotBeNull(); model.Name.ShouldBe(buildName); model.Date.ShouldBe(finishDate); model.Status.ShouldBe(TeamCityStatusModel.Success); model.TriggeredBy.ShouldBe(user); }
private TeamCityBuildModel MapSingleBuild(BuildJob buildJob) { var lastBuild = buildJob.BuildCollection.Builds.First(); return(new TeamCityBuildModel { Name = buildJob.Name, Date = lastBuild.FinishDate ?? lastBuild.StartDate, Status = MapStatus(lastBuild), TriggeredBy = MapTriggeredBy(lastBuild.Trigger) }); }
public static Project FromHudsonAPI(HudsonFreeStyleProjectResponse response, BuildJob lastbuild, BuildJob successfulbuild, BuildJob completedbuild, BuildJob currentbuild, IEnumerable<Project> upstreamProjects, IEnumerable<Project> downstreamProjects, ProjectBuildQueue queue) { var projectname = response.Name; var progress = 0; if (currentbuild.IsBuilding) progress = GetPercentageProgress(currentbuild.Timestamp, successfulbuild.Duration); var position = queue.Items.ToList().FindIndex(x => x.Name == projectname) + 1; return new Project(projectname, lastbuild, successfulbuild, completedbuild, currentbuild, progress, position, upstreamProjects, downstreamProjects); }
/// <summary> /// /// </summary> /// <param name="buildJob"></param> /// <returns></returns> public HttpResponseMessage Post(BuildJob buildJob) { var result = _compiler.CompileFromPlainText(_participant, buildJob.Code); //TODO use CompilerResult class as response return(Request.CreateResponse(HttpStatusCode.Created, new BuildResult { Output = result.StandardOutput.Length == 0 && result.StandardError.Length == 0 ? "Build succesvol" : string.Empty, Error = result.StandardError, CompileTime = result.CompilationTime })); }
/// <summary> /// /// </summary> /// <param name="buildJob"></param> /// <returns></returns> public HttpResponseMessage Post(BuildJob buildJob) { var result = _compiler.CompileFromPlainText(_participant, buildJob.Code); //TODO use CompilerResult class as response return Request.CreateResponse(HttpStatusCode.Created, new BuildResult{ Output = result.StandardOutput.Length == 0 && result.StandardError.Length == 0 ? "Build succesvol" : string.Empty, Error = result.StandardError, CompileTime = result.CompilationTime }); }
public void Init(int numChunks) { chunkPool = new Chunk[numChunks]; for (int i = 0; i < numChunks; i++) { SpawnChunkObj(i); } chunkQueue = new List <ChunkData>(); _buildJob = new BuildJob(); _buildJob.Setup(); }
public Project(string name, BuildJob lastbuild, BuildJob successfulbuild, BuildJob completedbuild, BuildJob currentbuild, int currentBuildProgress, int currentQueuePosition, IEnumerable<Project> upstreamProjects, IEnumerable<Project> downstreamProjects) { Name = name; LastBuild = lastbuild; LastSuccessfulBuild = successfulbuild; LastCompletedBuild = completedbuild; CurrentBuild = currentbuild; CurrentBuildProgress = currentBuildProgress; CurrentQueuePosition = currentQueuePosition; UpstreamProjects = upstreamProjects; DownstreamProjects = downstreamProjects; }
private string GetBuildJobOutputText(BuildJob Job, DateTime?StartTime) { var OutputText = new StringBuilder(); var Window = UnrealVSPackage.Instance.DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput); if (Window != null) { var OutputWindow = Window.Object as OutputWindow; if (OutputWindow != null) { var OutputWindowPane = OutputWindow.OutputWindowPanes.Item("Build"); if (OutputWindowPane != null) { var TextStartPoint = (EditPoint2)OutputWindowPane.TextDocument.StartPoint.CreateEditPoint(); string BuildOutputText = TextStartPoint.GetText(OutputWindowPane.TextDocument.EndPoint); OutputText.AppendLine("========== Build Output =========="); OutputText.AppendLine(string.Empty); OutputText.Append(BuildOutputText); OutputText.AppendLine(string.Empty); } } } int JobIndex = LastBuildJobsQueued.IndexOf(Job) + 1; int JobCount = LastBuildJobsQueued.Count; OutputText.AppendLine(string.Format("========== Batch Builder {0} - Job {1} of {2} ==========", OutputPanelTitle, JobIndex, JobCount)); OutputText.AppendLine(string.Empty); OutputText.AppendLine("------ " + Job.DisplayString + " ------"); OutputText.AppendLine("Status: " + Job.JobStatusDisplayString); if (StartTime.HasValue) { OutputText.AppendLine("Started: " + StartTime.Value.ToLongTimeString()); if (Job.JobStatus == BuildJob.BuildJobStatus.Complete || Job.JobStatus == BuildJob.BuildJobStatus.Failed || Job.JobStatus == BuildJob.BuildJobStatus.Cancelled) { DateTime EndTime = DateTime.Now; OutputText.AppendLine("Ended: " + EndTime.ToLongTimeString()); OutputText.AppendLine(string.Format("Execution time: {0:F2} seconds", (EndTime - StartTime.Value).TotalSeconds)); } } return(OutputText.ToString()); }
public void RunBuildJob(BuildJob job, IMSBuildChainedLoggerFilter loggerChain, Action <bool> reportWhenDone, CancellationToken cancellationToken) { if (job == null) { throw new ArgumentNullException("job"); } if (loggerChain == null) { throw new ArgumentNullException("loggerChain"); } BuildWorker worker = GetFreeWorker(); worker.RunJob(job, loggerChain, reportWhenDone, cancellationToken); }
public static Project FromHudsonAPI(HudsonFreeStyleProjectResponse response, BuildJob lastbuild, BuildJob successfulbuild, BuildJob completedbuild, BuildJob currentbuild, IEnumerable <Project> upstreamProjects, IEnumerable <Project> downstreamProjects, ProjectBuildQueue queue) { var projectname = response.Name; var progress = 0; if (currentbuild.IsBuilding) { progress = GetPercentageProgress(currentbuild.Timestamp, successfulbuild.Duration); } var position = queue.Items.ToList().FindIndex(x => x.Name == projectname) + 1; return(new Project(projectname, lastbuild, successfulbuild, completedbuild, currentbuild, progress, position, upstreamProjects, downstreamProjects)); }
public void RunJob(BuildJob job, IMSBuildChainedLoggerFilter loggerChain, Action <bool> reportWhenDone, CancellationToken cancellationToken) { Debug.Assert(loggerChain != null); this.loggerChain = loggerChain; this.reportWhenDone = reportWhenDone; try { process.Writer.Write("StartBuild"); job.WriteTo(process.Writer); this.cancellationRegistration = cancellationToken.Register(OnCancel); } catch (IOException ex) { // "Pipe is broken" loggerChain.HandleError(new BuildError(null, 0, 0, null, "Error talking to build worker: " + ex.Message)); BuildDone(false); } }
private void Write(BuildJob job) { try { foreach (var token in job.Tokens) { job.Index.Add(new VectorNode(token, job.DocId)); } } catch (Exception ex) { _log.Log(ex.ToString()); throw; } }
private void DownButtonClick(object Sender, RoutedEventArgs E) { if (!IsSingleBuildJobSelected) { return; } BuildJob SelectedJob = (BuildJob)BuildJobsList.SelectedItem; int CurrentIdx = BuildJobs.IndexOf(SelectedJob); if (CurrentIdx < BuildJobs.Count - 1) { BuildJobs.Move(CurrentIdx, CurrentIdx + 1); } }
public PipelineConfigurator( PrepareBranchJob prepareBranch, FetchJob fetch, MergeJob merge, BuildJob build, PushJob push) { JobCollection = FromJobs(prepareBranch, fetch, merge, build, push); StartJob = new CombinedStartJob(FromCollection <IStartJob>(prepareBranch, fetch)); ConfigureResult = pipeline => pipeline.Join(prepareBranch, fetch, x => x.Item1) .LinkTo(merge) .LinkTo(build) .LinkTo(push) .Result; }
private void OnDblClickBuildingListItem(object sender, MouseButtonEventArgs e) { var Elem = sender as FrameworkElement; if (Elem == null) { return; } BuildJob Job = Elem.DataContext as BuildJob; if (Job == null) { return; } DisplayBatchOutputText(Job.OutputText); }
public RunnableJob(IPipelineRunManager pipelineRunManager, BuildJob job, IDictionary <BuildJob, IJobStatus> jobMap) { BuildTask = job.Task; Status = new JobStatus(pipelineRunManager.BuildPath(job), job); var inputHandlers = new List <(BuildInputHandler handler, string path)>(); foreach (var input in job.Input) { var handler = input.Source switch { GitBuildInput git => HandleGitInput(pipelineRunManager, git), HttpRequestBuildInput http => HandleHttpInput(pipelineRunManager, http), ArtifactBuildInput artifact => HandleArtifactInput(artifact, jobMap[artifact.Job]), _ => throw new Exception("Unknown build input type") }; inputHandlers.Add((handler, input.Path)); } this.inputHandlers = inputHandlers; }
private BuildJob ScanDependencyGraph(Dictionary <JobID, BuildJob> outList, JobID build) { BuildJob existing; if (outList.TryGetValue(build, out existing)) { return(existing); } var job = new BuildJob(build); outList.Add(build, job); foreach (var p in build.Project.References) { var platform = IsPlatformAgnostic(p.Project) ? Platform.None : build.Platform; var dep = ScanDependencyGraph(outList, new JobID(platform, p.Project)); job.References.Add(dep); dep.ReferencedBy.Add(job); } return(job); }
void buildJobEnded (BuildJob job) { if ( jobGO.ContainsKey(job)) Destroy(jobGO[job]); Debug.Log("Job ended!"); if (job.GetType().Equals(typeof(TileBuildJob))){ busyTiles.Remove(job.tile); TileBuildJob tileJob = (TileBuildJob) job; if (tileBuildQueue.Contains(tileJob)) { tileBuildQueue.Remove(tileJob); } } else { List<Vector2> tiles = ((HouseBuildJob)job).position.GetTiles(); foreach(Vector2 tile in tiles) { busyTiles.Remove(tile); } } }
private void TickBuildQueue() { if (_ActiveBuildJob != null || _BuildQueue.Count == 0) { return; } while (_ActiveBuildJob == null && _BuildQueue.Count > 0) { BuildJob Job = _BuildQueue.Dequeue(); Project Project = Job.Project.GetProjectSlow(); if (Project != null) { Utils.ExecuteProjectBuild( Project, Job.Config, Job.Platform, Job.JobType, delegate { // Job starting _ActiveBuildJob = Job; _ActiveBuildJob.JobStatus = BuildJob.BuildJobStatus.Executing; _BuildJobStartTime = DateTime.Now; }, delegate { // Job failed to start - clear active job _ActiveBuildJob.JobStatus = BuildJob.BuildJobStatus.FailedToStart; _ActiveBuildJob.OutputText = GetBuildJobOutputText(_ActiveBuildJob, _BuildJobStartTime); _ActiveBuildJob = null; }); } } }
public void Build(List <ProjectVersion> projectVersions) { ProjectVersion activeProjectVersion = null; try { foreach (ProjectVersion projectVersion in projectVersions.Distinct()) { activeProjectVersion = projectVersion; projectVersion.SetStringProperty("LastBuildResult", "Not started"); entities.SaveChanges(); BuildJob job = new BuildJob(); job.Start( projectVersion.Id, projectId => TaskRunnerContext.SetProjectVersionState(projectId, ProjectState.Building), (projectId, isSuccess) => { TaskRunnerContext.SetProjectVersionState(projectId, isSuccess ? ProjectState.Idle : ProjectState.Error); }); } } catch (Exception e) { AspNetDeployException aspNetDeployException = new AspNetDeployException("Build project failed", e); aspNetDeployException.Data.Add("SourceControl version Id", activeProjectVersion.SourceControlVersion.Id); aspNetDeployException.Data.Add("Solution file", activeProjectVersion.SolutionFile); Factory.GetInstance <ILoggingService>().Log(aspNetDeployException, null); if (e.IsCritical()) { throw; } } }
// This method makes all time dependent stuff. public override void TimeLap(float time) { if (myJob == null) { myJob = BuildJobController.Instance.takeBuildJob(); if (myJob != null) { moveAgent.destination = myJob.tile; moveAgent.path = PathfindingManager.Instance.GetPath(moveAgent.Pos - MoveAgent.TILE_CENTER, moveAgent.destination); Debug.Log("Destination changed"); } } if (moveAgent.destination.Equals(moveAgent.Pos - MoveAgent.TILE_CENTER) && myJob != null) // Unit reached final point and ready to doWork. { if (myJob.DoWork(time)) { JobEnded(); } } moveAgent.TimeLap(time); }
private void OnDblClickBuildListItem(object sender, MouseButtonEventArgs e) { var Elem = sender as FrameworkElement; if (Elem == null) { return; } BuildJob Job = Elem.DataContext as BuildJob; if (Job == null) { return; } // Switch the Startup Project and the build config and platform to match this Job if (Job.Project != null) { IsBusy = true; var Project = Job.Project.GetProjectSlow(); if (Project != null) { // Switch to this project var ProjectHierarchy = Utils.ProjectToHierarchyObject(Project); UnrealVSPackage.Instance.SolutionBuildManager.set_StartupProject(ProjectHierarchy); // Switch the build config Utils.SetActiveSolutionConfiguration(Job.Config, Job.Platform); } IsBusy = false; } }
private void button1_Click(object sender, EventArgs e) { if (!Directory.Exists(textBox1.Text)) { Directory.CreateDirectory(textBox1.Text); } WebClient clt = new WebClient(); string data = clt.DownloadString(textBox2.Text); Regex r = new Regex("A HREF=\"([0-9]+)\\.([0-9]+)\\.([0-9]+)/\""); Dictionary <string, bool> added = new Dictionary <string, bool>(); checkedListBox1.Items.Clear(); foreach (Match match in r.Matches(data)) { int major = int.Parse(match.Groups[1].ToString()); int minor = int.Parse(match.Groups[2].ToString()); if (major < 3) { continue; } string fullver = string.Format("{0}.{1}.{2}", match.Groups[1], match.Groups[2], match.Groups[3]); string ver = string.Format("{0}.{1}.x", major, minor); if (!checkBox1.Checked) { ver = fullver; } if (added.ContainsKey(ver)) { continue; } added[ver] = true; checkedListBox1.Items.Add(new BuildJob { FullVersion = fullver, SavedVersion = ver }); } Application.DoEvents(); for (int i = 0; i < checkedListBox1.Items.Count; i++) { BuildJob job = checkedListBox1.Items[i] as BuildJob; if (Directory.Exists(textBox1.Text + "\\" + job.SavedVersion)) { checkedListBox1.SetItemChecked(i, true); continue; } else { checkedListBox1.SetItemChecked(i, true); string dir = textBox1.Text + "\\" + job.SavedVersion; Directory.CreateDirectory(dir); VBoxBuildForm.FetchAndBuild(job.FullVersion, true, dir); } } }
private void TickBuildQueue() { if (_ActiveBuildJob != null || _BuildQueue.Count == 0) return; while (_ActiveBuildJob == null && _BuildQueue.Count > 0) { BuildJob Job = _BuildQueue.Dequeue(); Project Project = Job.Project.GetProjectSlow(); if (Project != null) { Utils.ExecuteProjectBuild( Project, Job.Config, Job.Platform, Job.JobType, delegate { // Job starting _ActiveBuildJob = Job; _ActiveBuildJob.JobStatus = BuildJob.BuildJobStatus.Executing; _BuildJobStartTime = DateTime.Now; }, delegate { // Job failed to start - clear active job _ActiveBuildJob.JobStatus = BuildJob.BuildJobStatus.FailedToStart; _ActiveBuildJob.OutputText = GetBuildJobOutputText(_ActiveBuildJob, _BuildJobStartTime); _ActiveBuildJob = null; }); } } }
void StartBuild() { Dictionary <string, string> globalProperties = new Dictionary <string, string>(); MSBuildBasedProject.InitializeMSBuildProjectProperties(globalProperties); foreach (KeyValuePair <string, string> pair in options.Properties) { LoggingService.Debug("Setting property " + pair.Key + " to '" + pair.Value + "'"); globalProperties[pair.Key] = pair.Value; } globalProperties["Configuration"] = options.Configuration; if (options.Platform == "Any CPU") { globalProperties["Platform"] = "AnyCPU"; } else { globalProperties["Platform"] = options.Platform; } InterestingTasks.AddRange(MSBuildEngine.CompileTaskNames); loggers.Add(new SharpDevelopLogger(this)); if (options.BuildOutputVerbosity == BuildOutputVerbosity.Diagnostic) { this.ReportMessageEvents = true; this.ReportAllTaskFinishedEvents = true; this.ReportAllTaskStartedEvents = true; this.ReportTargetFinishedEvents = true; this.ReportTargetStartedEvents = true; this.ReportUnknownEvents = true; loggers.Add(new SDConsoleLogger(feedbackSink, LoggerVerbosity.Diagnostic)); globalProperties["MSBuildTargetsVerbose"] = "true"; } //loggers.Add(new BuildLogFileLogger(project.FileName + ".log", LoggerVerbosity.Diagnostic)); foreach (IMSBuildAdditionalLogger loggerProvider in MSBuildEngine.AdditionalMSBuildLoggers) { loggers.Add(loggerProvider.CreateLogger(this)); } loggerChain = new EndOfChain(this); foreach (IMSBuildLoggerFilter loggerFilter in MSBuildEngine.MSBuildLoggerFilters) { loggerChain = loggerFilter.CreateFilter(this, loggerChain) ?? loggerChain; } WriteAdditionalTargetsToTempFile(globalProperties); BuildJob job = new BuildJob(); job.ProjectFileName = projectFileName; job.Target = options.Target.TargetName; // First remove the flags for the controllable events. job.EventMask = EventTypes.All & ~ControllableEvents; // Add back active controllable events. if (ReportMessageEvents) { job.EventMask |= EventTypes.Message; } if (ReportTargetStartedEvents) { job.EventMask |= EventTypes.TargetStarted; } if (ReportTargetFinishedEvents) { job.EventMask |= EventTypes.TargetFinished; } if (ReportAllTaskStartedEvents) { job.EventMask |= EventTypes.TaskStarted; } if (ReportAllTaskFinishedEvents) { job.EventMask |= EventTypes.TaskFinished; } if (ReportUnknownEvents) { job.EventMask |= EventTypes.Unknown; } if (!(ReportAllTaskStartedEvents && ReportAllTaskFinishedEvents)) { // just some TaskStarted & TaskFinished events should be reported job.InterestingTaskNames.AddRange(InterestingTasks); } foreach (var pair in globalProperties) { job.Properties.Add(pair.Key, pair.Value); } foreach (ILogger logger in loggers) { logger.Initialize(eventSource); } if (projectMinimumSolutionVersion <= Solution.SolutionVersionVS2008) { BuildWorkerManager.MSBuild35.RunBuildJob(job, loggerChain, OnDone, feedbackSink.ProgressMonitor.CancellationToken); } else { BuildWorkerManager.MSBuild40.RunBuildJob(job, loggerChain, OnDone, feedbackSink.ProgressMonitor.CancellationToken); } }
private static TestResult BuildAndRunValidationJob(LoadedBSP.LoadedMCU mcu, string mcuDir, bool validateRegisters, LoadedRenamingRule[] renameRules, GeneratedProject prj, ToolFlags flags, Dictionary <string, bool> sourceExtensions, string[] nonValidateReg, string[] UndefinedMacros, BSPEngine.VendorSample vendorSample = null) { BuildJob job = new BuildJob(); string prefix = string.Format("{0}\\{1}\\{2}-", mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, mcu.BSP.Toolchain.Toolchain.GNUTargetID); //esp32 if (flEsp32) { prefix = prefix.Replace('\\', '/'); } job.OtherTasks.Add(new BuildTask { Executable = prefix + "g++", Arguments = $"{flags.StartGroup} {flags.EffectiveLDFLAGS} $^ {flags.EndGroup} -o $@", AllInputs = prj.SourceFiles.Where(f => sourceExtensions.ContainsKey(Path.GetExtension(f).TrimStart('.'))) .Select(f => Path.ChangeExtension(Path.GetFileName(f), ".o")) .Concat(prj.SourceFiles.Where(f => f.EndsWith(".a", StringComparison.InvariantCultureIgnoreCase))) .ToArray(), PrimaryOutput = "test.elf", }); job.OtherTasks.Add(new BuildTask { Executable = prefix + "objcopy", Arguments = "-O binary $< $@", AllInputs = new[] { "test.elf" }, PrimaryOutput = "test.bin", }); foreach (var sf in prj.SourceFiles) { var sfE = sf.Replace('\\', '/'); string ext = Path.GetExtension(sf); if (!sourceExtensions.ContainsKey(ext.TrimStart('.'))) { if (ext != ".txt" && ext != ".a" && ext != ".h") { Console.WriteLine($"#{sf} is not a recognized source file"); } } else { bool isCpp = ext.ToLower() != ".c"; string obj = Path.ChangeExtension(Path.GetFileName(sfE), ".o"); job.CompileTasks.Add(new BuildTask { PrimaryOutput = Path.ChangeExtension(Path.GetFileName(sfE), ".o"), AllInputs = new[] { sfE }, Executable = prefix + (isCpp ? "g++" : "gcc"), Arguments = $"-c $< { (isCpp ? "-std=gnu++11 ":" ")} {flags.GetEffectiveCFLAGS(isCpp, ToolFlags.FlagEscapingMode.ForMakefile)} -o {obj}".Replace('\\', '/').Replace("/\"", "\\\""), }); } } bool errorsFound = false; foreach (var g in job.CompileTasks.GroupBy(t => t.PrimaryOutput.ToLower())) { if (g.Count() > 1) { Console.WriteLine($"ERROR: {g.Key} corresponds to the following files:"); foreach (var f in g) { Console.WriteLine("\t" + f.AllInputs.FirstOrDefault()); } errorsFound = true; } } if (errorsFound) { throw new Exception("Multiple source files with the same name found"); } job.GenerateMakeFile(Path.Combine(mcuDir, "Makefile"), "test.bin"); if (!string.IsNullOrEmpty(mcu.MCUDefinitionFile) && validateRegisters) { string firstSrcFileInPrjDir = prj.SourceFiles.First(fn => Path.GetDirectoryName(fn) == mcuDir); InsertRegisterValidationCode(firstSrcFileInPrjDir, XmlTools.LoadObject <MCUDefinition>(mcu.MCUDefinitionFile), renameRules, nonValidateReg, UndefinedMacros); } Console.Write("Building {0}...", Path.GetFileName(mcuDir)); bool buildSucceeded; if (true) { var proc = Process.Start(new ProcessStartInfo("cmd.exe", "/c " + Path.Combine(mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, "make.exe") + " -j" + Environment.ProcessorCount + " > build.log 2>&1") { UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = mcuDir }); proc.WaitForExit(); buildSucceeded = proc.ExitCode == 0; } else { buildSucceeded = job.BuildFast(mcuDir, Environment.ProcessorCount); } bool success = false; string mapFile = Path.Combine(mcuDir, GeneratedProject.MapFileName); if (buildSucceeded && File.Exists(mapFile)) { success = File.ReadAllLines(Path.Combine(mcuDir, mapFile)).Where(l => RgMainMap.IsMatch(l)).Count() > 0; if (success) { string binFile = Path.Combine(mcuDir, "test.bin"); using (var fs = File.Open(binFile, FileMode.Open)) if (fs.Length < 512) { success = false; } } } if (!success) { return(TestResult.Failed); } if (vendorSample != null) { FillSampleDependenciesFromDepFiles(vendorSample, mcuDir); } Directory.Delete(mcuDir, true); return(TestResult.Succeeded); }
private void OnStartStopButtonClick(object sender, RoutedEventArgs e) { if (!IsBusy) { // Start RunBuildJobs(); } else { // Stop UnrealVSPackage.Instance.DTE.ExecuteCommand("Build.Cancel"); if (_ActiveBuildJob != null) { _ActiveBuildJob.JobStatus = BuildJob.BuildJobStatus.Cancelled; _ActiveBuildJob.OutputText = GetBuildJobOutputText(_ActiveBuildJob, _BuildJobStartTime); _ActiveBuildJob = null; } foreach (var BuildJob in _BuildQueue) { BuildJob.JobStatus = BuildJob.BuildJobStatus.Cancelled; BuildJob.OutputText = GetBuildJobOutputText(BuildJob, null); } _BuildQueue.Clear(); UpdateBusyState(); } }
public ArtifactBuildInput(BuildJob job, string artifactPath) { Job = job ?? throw new ArgumentNullException(nameof(job)); ArtifactPath = artifactPath ?? throw new ArgumentNullException(nameof(job)); }
private void OnBuildDone(bool bSucceeded, bool bModified, bool bWasCancelled) { if (_ActiveBuildJob != null) { if (bWasCancelled) { _ActiveBuildJob.JobStatus = BuildJob.BuildJobStatus.Cancelled; if (IsBusy) { foreach (var Job in _BuildQueue) { Job.JobStatus = BuildJob.BuildJobStatus.Cancelled; Job.OutputText = GetBuildJobOutputText(Job, null); } _BuildQueue.Clear(); } } else if (bSucceeded) { _ActiveBuildJob.JobStatus = BuildJob.BuildJobStatus.Complete; } else { _ActiveBuildJob.JobStatus = BuildJob.BuildJobStatus.Failed; } _ActiveBuildJob.OutputText = GetBuildJobOutputText(_ActiveBuildJob, _BuildJobStartTime); } _ActiveBuildJob = null; UpdateBusyState(); }
public BuildTask(BuildTaskScript taskScript, BuildJob job) : base() { TaskScript = taskScript; Job = job; }
internal Task <bool> RunBuildAsync(CancellationToken cancellationToken) { Dictionary <string, string> globalProperties = new Dictionary <string, string>(); globalProperties.AddRange(SD.MSBuildEngine.GlobalBuildProperties); foreach (KeyValuePair <string, string> pair in options.Properties) { LoggingService.Debug("Setting property " + pair.Key + " to '" + pair.Value + "'"); globalProperties[pair.Key] = pair.Value; } globalProperties["Configuration"] = options.Configuration; if (options.Platform == "Any CPU") { globalProperties["Platform"] = "AnyCPU"; } else { globalProperties["Platform"] = options.Platform; } InterestingTasks.AddRange(parentBuildEngine.CompileTaskNames); loggers.Add(new SharpDevelopLogger(this)); if (options.BuildOutputVerbosity == BuildOutputVerbosity.Diagnostic) { this.ReportMessageEvents = true; this.ReportAllTaskFinishedEvents = true; this.ReportAllTaskStartedEvents = true; this.ReportTargetFinishedEvents = true; this.ReportTargetStartedEvents = true; this.ReportUnknownEvents = true; loggers.Add(new SDConsoleLogger(feedbackSink, LoggerVerbosity.Diagnostic)); globalProperties["MSBuildTargetsVerbose"] = "true"; } //loggers.Add(new BuildLogFileLogger(project.FileName + ".log", LoggerVerbosity.Diagnostic)); foreach (IMSBuildAdditionalLogger loggerProvider in parentBuildEngine.AdditionalMSBuildLoggers) { loggers.Add(loggerProvider.CreateLogger(this)); } loggerChain = new EndOfChain(this); foreach (IMSBuildLoggerFilter loggerFilter in parentBuildEngine.MSBuildLoggerFilters) { loggerChain = loggerFilter.CreateFilter(this, loggerChain) ?? loggerChain; } WriteAdditionalTargetsToTempFile(globalProperties); BuildJob job = new BuildJob(); job.ProjectFileName = projectFileName; job.Target = options.Target.TargetName; // First remove the flags for the controllable events. job.EventMask = EventTypes.All & ~ControllableEvents; // Add back active controllable events. if (ReportMessageEvents) { job.EventMask |= EventTypes.Message; } if (ReportTargetStartedEvents) { job.EventMask |= EventTypes.TargetStarted; } if (ReportTargetFinishedEvents) { job.EventMask |= EventTypes.TargetFinished; } if (ReportAllTaskStartedEvents) { job.EventMask |= EventTypes.TaskStarted; } if (ReportAllTaskFinishedEvents) { job.EventMask |= EventTypes.TaskFinished; } if (ReportUnknownEvents) { job.EventMask |= EventTypes.Unknown; } if (!(ReportAllTaskStartedEvents && ReportAllTaskFinishedEvents)) { // just some TaskStarted & TaskFinished events should be reported job.InterestingTaskNames.AddRange(InterestingTasks); } foreach (var pair in globalProperties) { job.Properties.Add(pair.Key, pair.Value); } foreach (ILogger logger in loggers) { logger.Initialize(eventSource); } tcs = new TaskCompletionSource <bool>(); if (projectMinimumSolutionVersion <= SolutionFormatVersion.VS2008) { if (DotnetDetection.IsDotnet35SP1Installed()) { BuildWorkerManager.MSBuild35.RunBuildJob(job, loggerChain, OnDone, cancellationToken); } else { loggerChain.HandleError(new BuildError(job.ProjectFileName, ".NET 3.5 SP1 is required to build this project.")); tcs.SetResult(false); } } else { BuildWorkerManager.MSBuild40.RunBuildJob(job, loggerChain, OnDone, cancellationToken); } return(tcs.Task); }
public bool BuildProject(Project project, BuildJob job) { string buildResultDirectory = "Temp"; if (!Directory.Exists(buildResultDirectory)) { Directory.CreateDirectory(buildResultDirectory); } // Generate build result file name from project path char[] chars = Path.GetInvalidFileNameChars(); string buildResultFile = project.FullFileName; foreach (var ch in chars) { buildResultFile = buildResultFile.Replace(ch, '_'); } buildResultFile = Path.Combine(buildResultDirectory, Path.ChangeExtension(buildResultFile, ".tmp")); string msBuild = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"); string binDirectory = AppDomain.CurrentDomain.BaseDirectory; if (!File.Exists(msBuild)) { MessageService.ShowError(".Net Framework 4.0 not installed."); return(false); } Environment.SetEnvironmentVariable("BooBinPath", Path.Combine(binDirectory, @"..\AddIns\AddIns\BackendBindings\BooBinding\v4.0")); // Start msbuild ProcessStartInfo info = new ProcessStartInfo() { FileName = msBuild, //Arguments = string.Format(@"/c {0} ""{1}"" /clp:ErrorsOnly;WarningsOnly /nologo", msBuild, project.FullFileName), Arguments = string.Format(@"""{1}"" /logger:XmlLogger,""{2}\MSBuildLoggers40.dll"";logfile=""{3}"" /t:{4} /p:{5} /verbosity:m", null, // Reserved for testing in "cmd /c" project.FullFileName, Path.Combine(binDirectory, "Tools\\Frameworks"), buildResultFile, job.Target, "Configuration=" + job.Properties["Configuration"] + ";" + "Platform=" + job.Properties["Platform"]), UseShellExecute = false, RedirectStandardOutput = true, CreateNoWindow = true }; File.WriteAllText(Path.Combine(buildResultDirectory, "log.tmp"), info.FileName + " " + info.Arguments); Process process = Process.Start(info); process.WaitForExit(); bool succeeded = process.ExitCode == 0; try { // Parse build result XmlDocument document = new XmlDocument(); document.Load(buildResultFile); XmlNodeList projects = document.SelectNodes("/build/project"); foreach (XmlNode p in projects) { string projectFile = p.Attributes["file"].Value; ReportResult(projectFile, p.SelectNodes("error"), ReportError); ReportResult(projectFile, p.SelectNodes("warning"), ReportWarning); ReportResult(projectFile, p.SelectNodes("message"), ReportMessage); } } catch (Exception ex) { LoggingService.Error("Parse build result failed.", ex); succeeded = false; } if (!succeeded) { LoggingService.Info(process.StandardOutput.ReadToEnd()); } return(succeeded); }
void JobEnded() { myJob = null; //Debug.Log("Job ended!"); }
void StartBuild() { WorkerManager.ShowError = MessageService.ShowError; BuildWorker.BuildSettings settings = new BuildWorker.BuildSettings(); SharpDevelopLogger logger = new SharpDevelopLogger(this); settings.Logger.Add(logger); InterestingTasks.AddRange(MSBuildEngine.CompileTaskNames); foreach (IMSBuildAdditionalLogger loggerProvider in MSBuildEngine.AdditionalMSBuildLoggers) { settings.Logger.Add(loggerProvider.CreateLogger(this)); } BuildJob job = new BuildJob(); job.IntPtrSize = IntPtr.Size; job.ProjectFileName = project.FileName; // Never report custom events (those are usually derived EventArgs classes, and SharpDevelop // doesn't have the matching assemblies loaded - see SD2-1514). // Also, remove the flags for the controllable events. job.EventMask = EventTypes.All & ~(ControllableEvents | EventTypes.Custom); // Add back active controllable events. if (ReportMessageEvents) { job.EventMask |= EventTypes.Message; } if (ReportTargetStartedEvents) { job.EventMask |= EventTypes.TargetStarted; } if (ReportTargetFinishedEvents) { job.EventMask |= EventTypes.TargetFinished; } if (ReportAllTaskStartedEvents) { job.EventMask |= EventTypes.TaskStarted; } if (ReportAllTaskFinishedEvents) { job.EventMask |= EventTypes.TaskFinished; } if (ReportUnknownEvents) { job.EventMask |= EventTypes.Unknown; } if (!(ReportAllTaskStartedEvents && ReportAllTaskFinishedEvents)) { // just some TaskStarted & TaskFinished events should be reported job.InterestingTaskNames.AddRange(InterestingTasks); } job.AdditionalImports.AddRange(additionalTargetFiles); BuildPropertyGroup pg = new BuildPropertyGroup(); MSBuildBasedProject.InitializeMSBuildProjectProperties(pg); foreach (BuildProperty p in pg) { job.Properties[p.Name] = p.FinalValue; } Solution solution = project.ParentSolution; job.Properties["SolutionDir"] = EnsureBackslash(solution.Directory); job.Properties["SolutionExt"] = ".sln"; job.Properties["SolutionFileName"] = Path.GetFileName(solution.FileName); job.Properties["SolutionPath"] = solution.FileName; foreach (var pair in options.Properties) { job.Properties[pair.Key] = pair.Value; } job.Properties["Configuration"] = options.Configuration; if (options.Platform == "Any CPU") { job.Properties["Platform"] = "AnyCPU"; } else { job.Properties["Platform"] = options.Platform; } job.Target = options.Target.TargetName; bool buildInProcess = false; if (AllowBuildInProcess && Interlocked.CompareExchange(ref isBuildingInProcess, 1, 0) == 0) { buildInProcess = true; } LoggingService.Info("Start job (buildInProcess=" + buildInProcess + "): " + job.ToString()); if (buildInProcess) { settings.BuildDoneCallback = delegate(bool success) { LoggingService.Debug("BuildInProcess: Received BuildDoneCallback"); if (Interlocked.Exchange(ref isBuildingInProcess, 0) != 1) { MessageService.ShowError("isBuildingInProcess should have been 1!"); } logger.FlushCurrentError(); feedbackSink.Done(success); }; Thread thread = new Thread(new ThreadStart( delegate { LoggingService.Debug("Acquiring InProcessMSBuildLock"); lock (MSBuildInternals.InProcessMSBuildLock) { WorkerManager.RunBuildInProcess(job, settings); LoggingService.Debug("Leaving InProcessMSBuildLock"); } })); thread.Name = "InProcess build thread " + thread.ManagedThreadId; thread.SetApartmentState(ApartmentState.STA); thread.Start(); } else { settings.BuildDoneCallback = delegate(bool success) { LoggingService.Debug("BuildOutOfProcess: Received BuildDoneCallback"); logger.FlushCurrentError(); feedbackSink.Done(success); }; WorkerManager.StartBuild(job, settings); } }
private void TickBuildQueue() { if (_ActiveBuildJob != null || _BuildQueue.Count == 0) return; while (_ActiveBuildJob == null && _BuildQueue.Count > 0) { BuildJob Job = _BuildQueue.Dequeue(); Project Project = Job.Project.GetProjectSlow(); if (Project != null) { IVsHierarchy ProjHierarchy = Utils.ProjectToHierarchyObject(Project); if (ProjHierarchy != null) { SolutionConfigurations SolutionConfigs = UnrealVSPackage.Instance.DTE.Solution.SolutionBuild.SolutionConfigurations; var SolutionConfig = (from SolutionConfiguration2 Sc in SolutionConfigs select Sc).FirstOrDefault( Sc => String.CompareOrdinal(Sc.Name, Job.Config) == 0 && String.CompareOrdinal(Sc.PlatformName, Job.Platform) == 0); if (SolutionConfig != null) { SolutionContext ProjectSolutionCtxt = SolutionConfig.SolutionContexts.Item(Project.UniqueName); if (ProjectSolutionCtxt != null) { IVsCfgProvider2 CfgProvider2 = Utils.HierarchyObjectToCfgProvider(ProjHierarchy); if (CfgProvider2 != null) { IVsCfg Cfg; CfgProvider2.GetCfgOfName(ProjectSolutionCtxt.ConfigurationName, ProjectSolutionCtxt.PlatformName, out Cfg); if (Cfg != null) { _ActiveBuildJob = Job; _ActiveBuildJob.JobStatus = BuildJob.BuildJobStatus.Executing; _BuildJobStartTime = DateTime.Now; int JobResult = VSConstants.E_FAIL; if (Job.JobType == BuildJob.BuildJobType.Build) { JobResult = UnrealVSPackage.Instance.SolutionBuildManager.StartUpdateSpecificProjectConfigurations( 1, new[] {ProjHierarchy}, new[] {Cfg}, null, new uint[] {0}, null, (uint) VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_BUILD, 0); } else if (Job.JobType == BuildJob.BuildJobType.Rebuild) { JobResult = UnrealVSPackage.Instance.SolutionBuildManager.StartUpdateSpecificProjectConfigurations( 1, new[] {ProjHierarchy}, new[] {Cfg}, new uint[] {0}, null, null, (uint) (VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_BUILD | VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_FORCE_UPDATE), 0); } else if (Job.JobType == BuildJob.BuildJobType.Clean) { JobResult = UnrealVSPackage.Instance.SolutionBuildManager.StartUpdateSpecificProjectConfigurations( 1, new[] {ProjHierarchy}, new[] {Cfg}, new uint[] {0}, null, null, (uint) VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_CLEAN, 0); } if (JobResult == VSConstants.S_OK) { // Job running - show output PrepareOutputPane(); } else { // Job failed to start - clear active job _ActiveBuildJob.JobStatus = BuildJob.BuildJobStatus.FailedToStart; _ActiveBuildJob.OutputText = GetBuildJobOutputText(_ActiveBuildJob, _BuildJobStartTime); _ActiveBuildJob = null; } } } } } } } } }
private static TestResult BuildAndRunValidationJob(LoadedBSP.LoadedMCU mcu, string mcuDir, bool validateRegisters, LoadedRenamingRule[] renameRules, GeneratedProject prj, ToolFlags flags, Dictionary<string, bool> sourceExtensions, string[] nonValidateReg, BSPEngine.VendorSample vendorSample = null) { BuildJob job = new BuildJob(); string prefix = string.Format("{0}\\{1}\\{2}-", mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, mcu.BSP.Toolchain.Toolchain.GNUTargetID); job.OtherTasks.Add(new BuildTask { Executable = prefix + "g++", Arguments = $"{flags.EffectiveLDFLAGS} $^ -o $@", AllInputs = prj.SourceFiles.Where(f => sourceExtensions.ContainsKey(Path.GetExtension(f).TrimStart('.'))) .Select(f => Path.ChangeExtension(Path.GetFileName(f), ".o")) .Concat(prj.SourceFiles.Where(f => f.EndsWith(".a", StringComparison.InvariantCultureIgnoreCase))) .ToArray(), PrimaryOutput = "test.elf", }); job.OtherTasks.Add(new BuildTask { Executable = prefix + "objcopy", Arguments = "-O binary $< $@", AllInputs = new[] { "test.elf" }, PrimaryOutput = "test.bin", }); foreach (var sf in prj.SourceFiles) { string ext = Path.GetExtension(sf); if (!sourceExtensions.ContainsKey(ext.TrimStart('.'))) { if (ext != ".txt") Console.WriteLine($"#{sf} is not a recognized source file"); } else { bool isCpp = ext.ToLower() != ".c"; string obj = Path.ChangeExtension(Path.GetFileName(sf), ".o"); job.CompileTasks.Add(new BuildTask { PrimaryOutput = Path.ChangeExtension(Path.GetFileName(sf), ".o"), AllInputs = new[] { sf }, Executable = prefix + (isCpp ? "g++" : "gcc"), Arguments = $"-c $< {flags.GetEffectiveCFLAGS(isCpp)} -o {obj}", }); } } job.GenerateMakeFile(Path.Combine(mcuDir, "Makefile"), "test.bin"); if (!string.IsNullOrEmpty(mcu.MCUDefinitionFile) && validateRegisters) { string firstSrcFileInPrjDir = prj.SourceFiles.First(fn => Path.GetDirectoryName(fn) == mcuDir); InsertRegisterValidationCode(firstSrcFileInPrjDir, XmlTools.LoadObject<MCUDefinition>(mcu.MCUDefinitionFile), renameRules, nonValidateReg); } Console.Write("Building {0}...", Path.GetFileName(mcuDir)); bool buildSucceeded; if (false) { var proc = Process.Start(new ProcessStartInfo("cmd.exe", "/c " + Path.Combine(mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, "make.exe") + " -j" + Environment.ProcessorCount + " > build.log 2>&1") { UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = mcuDir }); proc.WaitForExit(); buildSucceeded = proc.ExitCode == 0; } else { buildSucceeded = job.BuildFast(mcuDir, Environment.ProcessorCount); } bool success = false; string mapFile = Path.Combine(mcuDir, GeneratedProject.MapFileName); if (buildSucceeded && File.Exists(mapFile)) { success = File.ReadAllLines(Path.Combine(mcuDir, mapFile)).Where(l => RgMainMap.IsMatch(l)).Count() > 0; if (success) { string binFile = Path.Combine(mcuDir, "test.bin"); using (var fs = File.Open(binFile, FileMode.Open)) if (fs.Length < 512) success = false; } } if (!success) return TestResult.Failed; if (vendorSample != null) { FillSampleDependenciesFromDepFiles(vendorSample, mcuDir); } Directory.Delete(mcuDir, true); return TestResult.Succeeded; }
private string GetBuildJobOutputText(BuildJob Job, DateTime? StartTime) { var OutputText = new StringBuilder(); var Window = UnrealVSPackage.Instance.DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput); if (Window != null) { var OutputWindow = Window.Object as OutputWindow; if (OutputWindow != null) { var OutputWindowPane = OutputWindow.OutputWindowPanes.Item("Build"); if (OutputWindowPane != null) { var TextStartPoint = (EditPoint2)OutputWindowPane.TextDocument.StartPoint.CreateEditPoint(); string BuildOutputText = TextStartPoint.GetText(OutputWindowPane.TextDocument.EndPoint); OutputText.AppendLine("========== Build Output =========="); OutputText.AppendLine(string.Empty); OutputText.Append(BuildOutputText); OutputText.AppendLine(string.Empty); } } } int JobIndex = LastBuildJobsQueued.IndexOf(Job) + 1; int JobCount = LastBuildJobsQueued.Count; OutputText.AppendLine(string.Format("========== Batch Builder {0} - Job {1} of {2} ==========", OutputPanelTitle, JobIndex, JobCount)); OutputText.AppendLine(string.Empty); OutputText.AppendLine("------ " + Job.DisplayString + " ------"); OutputText.AppendLine("Status: " + Job.JobStatusDisplayString); if (StartTime.HasValue) { OutputText.AppendLine("Started: " + StartTime.Value.ToLongTimeString()); if (Job.JobStatus == BuildJob.BuildJobStatus.Complete || Job.JobStatus == BuildJob.BuildJobStatus.Failed || Job.JobStatus == BuildJob.BuildJobStatus.Cancelled) { DateTime EndTime = DateTime.Now; OutputText.AppendLine("Ended: " + EndTime.ToLongTimeString()); OutputText.AppendLine(string.Format("Execution time: {0:F2} seconds", (EndTime - StartTime.Value).TotalSeconds)); } } return OutputText.ToString(); }