protected static void AddIndirectReferences(IProjectFinder projectFinder, Regex[] assemblyNamePatterns, bool ignoreOnlyMatching, HashSet <string> originalAssemblyReferenceNames, Queue <AssemblyReference> remainingReferences, string targetPath, Project buildingProject, FileInfo[] projectOutputs, string explicitTargetPath, AssemblyReference assemblyReference, List <IndirectReferenceInfo> indirectReferencesOutsideSolution) { var indirectReferences = GetIndirectReferences(originalAssemblyReferenceNames, targetPath, projectOutputs, explicitTargetPath) .Where(x => IncludeAssemblyWhenCopyingDeps(x, assemblyNamePatterns, ignoreOnlyMatching)) .ToArray(); if (false == indirectReferences.Any()) { return; } var buildingSolution = projectFinder.GetSLNFileForProject(buildingProject); // TODO: Print the name of the project that is missing these indirect references instead of letting the user guess. _logger.InfoFormat("Adding indirect references listed below. The direct reference is to {0}.\n{1}\nThis probably means some project is referencing {0} but does not reference all of the listed indirect assemblies above.\nHere's a list of projects referencing {0}:\n{2}", assemblyReference.Name, StringExtensions.Tabify(indirectReferences.Select(x => x.Name)), StringExtensions.Tabify(ProjectsUsingAssemblyReference(projectFinder, assemblyReference))); foreach (var indirectReference in indirectReferences) { var indirectReferenceBuildingProject = projectFinder.FindProjectForAssemblyReference(indirectReference).SingleOrDefault(); var indirectReferenceInfo = new IndirectReferenceInfo(assemblyReference, buildingProject, indirectReference, indirectReferenceBuildingProject); if (null != indirectReferenceBuildingProject) { if (projectFinder.GetSLNFileForProject(indirectReferenceBuildingProject).FullName.Equals(buildingSolution.FullName, StringComparison.InvariantCultureIgnoreCase)) { originalAssemblyReferenceNames.Add(ComparableAssemblyName(indirectReference)); remainingReferences.Enqueue(indirectReference); continue; } } indirectReferencesOutsideSolution.Add(indirectReferenceInfo); } }
public static void CopyAssemblyReferencesFromBuiltProjects( IProjectFinder projectFinder, Regex[] assemblyNamePatterns, bool ignoreOnlyMatching, IEnumerable <AssemblyReference> assemblyReferences, bool ignoreMissing) { // TODO: Refactor this mess, and save for each indirect reference the dependency path that caused it to be included in a unified way var originalAssemblyReferenceNames = new HashSet <string>(assemblyReferences.Select(ComparableAssemblyName)); var remainingReferences = new Queue <AssemblyReference>(assemblyReferences); var indirectReferencesOutsideSolution = new List <IndirectReferenceInfo>(); var ignoredAssemblies = new List <AssemblyReference>(); var badHintPathAssemblies = new List <AssemblyReference>(); var missingProjects = new List <AssemblyReference>(); var unbuiltProjects = new List <Project>(); while (remainingReferences.Any()) { var assemblyReference = remainingReferences.Dequeue(); if (false == IncludeAssemblyWhenCopyingDeps(assemblyReference, assemblyNamePatterns, ignoreOnlyMatching)) { _logger.DebugFormat("Not copying ignored assembly: '{0}'", assemblyReference.ToString()); ignoredAssemblies.Add(assemblyReference); continue; } if (String.IsNullOrWhiteSpace(assemblyReference.HintPath)) { _logger.DebugFormat("Can't copy dependency (no target path): Missing HintPath for assembly reference: '{0}', used by projects:\n{1}", assemblyReference, ProjectsUsingAssemblyReference(projectFinder, assemblyReference)); badHintPathAssemblies.Add(assemblyReference); continue; } var targetPath = System.IO.Path.GetDirectoryName(assemblyReference.HintPath); var buildingProject = projectFinder.FindProjectForAssemblyReference(assemblyReference).SingleOrDefault(); if (null == buildingProject) { _logger.DebugFormat("Can't find dependency (no building project): No project builds assembly reference: '{0}', used by projects:\n{1}", assemblyReference, ProjectsUsingAssemblyReference(projectFinder, assemblyReference)); missingProjects.Add(assemblyReference); continue; } if (ignoreMissing && (false == System.IO.Directory.Exists(buildingProject.GetAbsoluteOutputPath()))) { _logger.DebugFormat("Ignoring (not copying) all components from not-built project: {0}", buildingProject.ToString()); unbuiltProjects.Add(buildingProject); continue; } var projectOutputs = buildingProject.GetBuiltProjectOutputs().ToArray(); _logger.InfoFormat("Copy: {0,-40} -> {1}", buildingProject.Name, targetPath); CopyFilesToDirectory(projectOutputs, targetPath, ignoreMissing); // Add sub-references - the indirectly referenced assemblies, the ones used by the current assemblyReference var explicitTargetPath = System.IO.Path.GetDirectoryName(assemblyReference.ExplicitHintPath); // TODO: Refactor AddIndirectReferences(projectFinder, assemblyNamePatterns, ignoreOnlyMatching, originalAssemblyReferenceNames, remainingReferences, targetPath, buildingProject, projectOutputs, explicitTargetPath, assemblyReference, indirectReferencesOutsideSolution); } WarnAboutRemainingIndirectReferences(projectFinder, originalAssemblyReferenceNames, indirectReferencesOutsideSolution); WarnAboutUncopiedAssemblies(assemblyNamePatterns, ignoreOnlyMatching, ignoredAssemblies, badHintPathAssemblies, missingProjects, unbuiltProjects); }