/// <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(Array.Empty <string>()); } List <ProjectStartedEventMinimumFields> projectStackTrace = GetProjectCallStack(e); foreach (ProjectStartedEventMinimumFields projectStartedEvent in projectStackTrace) { if (!string.IsNullOrEmpty(projectStartedEvent.TargetNames)) { stackTrace.Add(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("ProjectStackWithTargetNames", projectStartedEvent.ProjectFile, projectStartedEvent.TargetNames, projectStartedEvent.FullProjectKey)); } else { stackTrace.Add(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("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 != null && !startedEvent.ErrorInProject) { _projectStartedEvents.Remove(e); } }
internal ProjectStartedEventMinimumFields(int projectKey, int entryPointKey, ProjectStartedEventArgs startedEvent, ProjectStartedEventMinimumFields parentProjectStartedEvent, bool requireTimeStamp) { _targetNames = startedEvent.TargetNames; _projectFile = startedEvent.ProjectFile; _showProjectFinishedEvent = false; _errorInProject = false; _projectId = startedEvent.ProjectId; _buildEventContext = startedEvent.BuildEventContext; _parentProjectStartedEvent = parentProjectStartedEvent; _projectFullKey = new ProjectFullKey(projectKey, entryPointKey); if (requireTimeStamp) { _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, bool requireTimestamp) { //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 += 1; _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, requireTimestamp)); } } }
/// <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); }