/// <summary> /// Given a project or targets file (the PRE), and the project context from which it comes, gather /// the list of task registrations defined in that file. /// </summary> /// <remarks> /// Does NOT currently take into account conditions on task registrations, so any tasks that are registered /// with two or more mutually exclusive conditions may end up associated with the wrong registration. /// </remarks> private void GatherAndEvaluatedTasksInFile(ProjectRootElement pre, Project containingProject, HashSet <UsingTaskData> usingTasks) { foreach (ProjectUsingTaskElement usingTask in pre.UsingTasks) { string evaluatedTaskName = EvaluateIfNecessary(usingTask.TaskName, containingProject); // A task registration can define either AssemblyName or AssemblyFile, but not both. string evaluatedTaskAssemblyPath = null; if (String.IsNullOrEmpty(usingTask.AssemblyName)) { evaluatedTaskAssemblyPath = EvaluateIfNecessary(usingTask.AssemblyFile, containingProject); evaluatedTaskAssemblyPath = Path.GetFullPath(evaluatedTaskAssemblyPath); } else { string evaluatedTaskAssemblyName = EvaluateIfNecessary(usingTask.AssemblyName, containingProject); if (!String.IsNullOrEmpty(evaluatedTaskAssemblyName)) { if (!_assemblyLocationsByName.TryGetValue(evaluatedTaskAssemblyName, out evaluatedTaskAssemblyPath)) { try { // If all we have is an assembly name, try to find the file path so that we can write // that to the CSV instead. AssemblyName name = new AssemblyName(evaluatedTaskAssemblyName); Assembly a = Assembly.Load(name); evaluatedTaskAssemblyPath = a.Location; } catch (Exception) { // But if we can't, it's not critical -- just give them what we have. evaluatedTaskAssemblyPath = evaluatedTaskAssemblyName; } _assemblyLocationsByName[evaluatedTaskAssemblyName] = evaluatedTaskAssemblyPath; } } else { evaluatedTaskAssemblyPath = String.Empty; } } UsingTaskData taskData = new UsingTaskData(evaluatedTaskName, evaluatedTaskAssemblyPath, pre.FullPath); usingTasks.Add(taskData); } }
/// <summary> /// Given a task name and its associated project, make a "best guess" /// at what assembly the task comes from. /// </summary> private string GetAssemblySpecificationFor(string taskName, int projectContextId, string projectFile) { // First let's see if this task is defined in the project anywhere HashSet <UsingTaskData> usingTasks = null; if (!_tasksByProjectContextId.TryGetValue(projectContextId, out usingTasks)) { throw new LoggerException(String.Format(CultureInfo.CurrentCulture, "Why haven't we collected using task data for {0}?", projectFile)); } // Just grab the first one. NOT accurate if there are conditioned task registrations UsingTaskData matchingData = usingTasks.Where(ut => IsPartialNameMatch(taskName, ut.TaskName)).FirstOrDefault(); if (matchingData == null) { // If there isn't a registration for the project, fall back to checking the default tasks for // that project's ToolsVersion. string parentProjectToolsVersion = null; if (!_toolsVersionsByProjectContextId.TryGetValue(projectContextId, out parentProjectToolsVersion)) { throw new LoggerException(String.Format(CultureInfo.CurrentCulture, "Why don't we have a cached ToolsVersion for {0}?", projectFile)); } HashSet <UsingTaskData> defaultUsingTasks = null; if (!_defaultTasksByToolset.TryGetValue(parentProjectToolsVersion, out defaultUsingTasks)) { throw new LoggerException(String.Format(CultureInfo.CurrentCulture, "Why haven't we collected default using task data for TV {0}?", parentProjectToolsVersion)); } matchingData = defaultUsingTasks.Where(ut => IsPartialNameMatch(taskName, ut.TaskName)).FirstOrDefault(); } if (matchingData == null) { throw new LoggerException(String.Format(CultureInfo.CurrentCulture, "Why couldn't we find a matching UsingTask for task {0} in project {1}?", taskName, projectFile)); } return(matchingData.TaskAssembly); }
/// <summary> /// Given a project or targets file (the PRE), and the project context from which it comes, gather /// the list of task registrations defined in that file. /// </summary> /// <remarks> /// Does NOT currently take into account conditions on task registrations, so any tasks that are registered /// with two or more mutually exclusive conditions may end up associated with the wrong registration. /// </remarks> private void GatherAndEvaluatedTasksInFile(ProjectRootElement pre, Project containingProject, HashSet<UsingTaskData> usingTasks) { foreach (ProjectUsingTaskElement usingTask in pre.UsingTasks) { string evaluatedTaskName = EvaluateIfNecessary(usingTask.TaskName, containingProject); // A task registration can define either AssemblyName or AssemblyFile, but not both. string evaluatedTaskAssemblyPath = null; if (String.IsNullOrEmpty(usingTask.AssemblyName)) { evaluatedTaskAssemblyPath = EvaluateIfNecessary(usingTask.AssemblyFile, containingProject); evaluatedTaskAssemblyPath = Path.GetFullPath(evaluatedTaskAssemblyPath); } else { string evaluatedTaskAssemblyName = EvaluateIfNecessary(usingTask.AssemblyName, containingProject); if (!String.IsNullOrEmpty(evaluatedTaskAssemblyName)) { if (!_assemblyLocationsByName.TryGetValue(evaluatedTaskAssemblyName, out evaluatedTaskAssemblyPath)) { try { // If all we have is an assembly name, try to find the file path so that we can write // that to the CSV instead. AssemblyName name = new AssemblyName(evaluatedTaskAssemblyName); Assembly a = Assembly.Load(name); evaluatedTaskAssemblyPath = a.Location; } catch (Exception) { // But if we can't, it's not critical -- just give them what we have. evaluatedTaskAssemblyPath = evaluatedTaskAssemblyName; } _assemblyLocationsByName[evaluatedTaskAssemblyName] = evaluatedTaskAssemblyPath; } } else { evaluatedTaskAssemblyPath = String.Empty; } } UsingTaskData taskData = new UsingTaskData(evaluatedTaskName, evaluatedTaskAssemblyPath, pre.FullPath); usingTasks.Add(taskData); } }