/// <summary> /// Retrieve the project call stack based on the starting point of buildEventContext e /// </summary> internal string[] ProjectCallStackFromProject(BuildEventContext e) { BuildEventContext currentKey = e; ProjectStartedEventMinimumFields startedEvent = GetProjectStartedEvent(currentKey); List <string> stackTrace = new List <string>(); // If there is no started event then there should be no stack trace // this is a valid situation if the event occures in the engine or outside the context of a project // or the event is raised before the project started event if (startedEvent == null) { return(new string[0]); } List <ProjectStartedEventMinimumFields> projectStackTrace = GetProjectCallStack(e); foreach (ProjectStartedEventMinimumFields projectStartedEvent in projectStackTrace) { if (!string.IsNullOrEmpty(projectStartedEvent.TargetNames)) { stackTrace.Add(ResourceUtilities.FormatResourceString("ProjectStackWithTargetNames", projectStartedEvent.ProjectFile, projectStartedEvent.TargetNames, projectStartedEvent.FullProjectKey)); } else { stackTrace.Add(ResourceUtilities.FormatResourceString("ProjectStackWithDefaultTargets", projectStartedEvent.ProjectFile, projectStartedEvent.FullProjectKey)); } } stackTrace.Reverse(); return(stackTrace.ToArray()); }
/// <summary> /// Will remove a project started event from the list of deferred project started events /// </summary> internal void RemoveProjectStartedEvent(BuildEventContext e) { ProjectStartedEventMinimumFields startedEvent = GetProjectStartedEvent(e); // Only remove the project from the event list if it is in the list, and no errors have occurred in the project if (startedEvent?.ErrorInProject == false) { projectStartedEvents.Remove(e); } }
internal ProjectStartedEventMinimumFields(int projectKey, int entryPointKey, ProjectStartedEventArgs startedEvent, ProjectStartedEventMinimumFields parentProjectStartedEvent) { this.targetNames = startedEvent.TargetNames; this.projectFile = startedEvent.ProjectFile; this.showProjectFinishedEvent = false; this.errorInProject = false; this.projectId = startedEvent.ProjectId; this.buildEventContext = startedEvent.BuildEventContext; this.parentProjectStartedEvent = parentProjectStartedEvent; this.projectFullKey = new ProjectFullKey(projectKey, entryPointKey); this.timeStamp = startedEvent.Timestamp; }
/// <summary> /// Adds a new project to the list of project started events which have been fired /// </summary> internal void AddProjectStartedEvent(ProjectStartedEventArgs e) { //Parent event can be null if this is the root project ProjectStartedEventMinimumFields parentEvent = GetProjectStartedEvent(e.ParentProjectBuildEventContext); lock (projectStartedEvents) { if (!projectStartedEvents.ContainsKey(e.BuildEventContext)) { int projectTargetKeyLocal = 1; int projectIncrementKeyLocal = 1; // If we haven't seen this project before (by full path) then // allocate a new key for it and save it away if (!projectKey.ContainsKey(e.ProjectFile)) { projectIncrementKey++; projectKey[e.ProjectFile] = projectIncrementKey; projectIncrementKeyLocal = projectIncrementKey; } else { // We've seen this project before, so retrieve it projectIncrementKeyLocal = projectKey[e.ProjectFile]; } // If we haven't seen any entrypoint for the current project (by full path) then // allocate a new entry point key if (!projectTargetKey.ContainsKey(e.ProjectFile)) { projectTargetKey[e.ProjectFile] = projectTargetKeyLocal; } else { // We've seen this project before, but not this entrypoint, so increment // the entrypoint key that we have. projectTargetKeyLocal = projectTargetKey[e.ProjectFile] + 1; projectTargetKey[e.ProjectFile] = projectTargetKeyLocal; } projectStartedEvents.Add(e.BuildEventContext, new ProjectStartedEventMinimumFields(projectIncrementKeyLocal, projectTargetKeyLocal, e, parentEvent)); } } }
/// <summary> /// Get a call stack of event contexts for a starting point event context /// </summary> internal List <ProjectStartedEventMinimumFields> GetProjectCallStack(BuildEventContext e) { List <ProjectStartedEventMinimumFields> stackTrace = new List <ProjectStartedEventMinimumFields>(); ProjectStartedEventMinimumFields currentKey = GetProjectStartedEvent(e); // currentKey can be null if the stack trace is requested before the project started event has been seen // or if the call stack is requested by an event which is not associated with a project such as an event // from the engine itself if (currentKey != null) { //Add the event where the stack should start stackTrace.Add(currentKey); // Loop through the call tree until the root project started event has been found while (currentKey.ParentProjectStartedEvent != null) { currentKey = currentKey.ParentProjectStartedEvent; stackTrace.Add(currentKey); } } return(stackTrace); }