static void Main(string[] args) { if (!args.Any()) { Console.WriteLine("You did not provide the required targetProject argument."); Environment.Exit(1); } // See if the anonymize flag has been sent bool anonymizeNames = args.Any(current => Regex.IsMatch(current.ToLowerInvariant(), @"^[-\/]+([a]{1}|anonymize)$")); // See if the Sort Flag has been set bool sortOutput = args.Any(current => Regex.IsMatch(current.ToLowerInvariant(), @"^[-\/]+([s]{1}|sort)$")); // See if the target project flag has been set string targetProject = _ParseForTargetProjectFlag(args); string targetArgument = args.First(); List <string> projectsToEvaluate = new List <string>(); if (Path.GetExtension(targetArgument).Equals(".sln", StringComparison.InvariantCultureIgnoreCase)) { IEnumerable <string> projectsInSolution = MSBuildUtilities.GetProjectsFromSolution(targetArgument); // These come back as relative paths; we need to "expand" them // otherwise we'll get duplicates when we go to resolve. projectsInSolution = PathUtilities.ResolveRelativePaths(projectsInSolution); projectsToEvaluate.AddRange(projectsInSolution); } else { // Assume its just a single project projectsToEvaluate.Add(targetArgument); } Dictionary <string, IEnumerable <string> > projectReferenceDependencies = MSBPRDependencyGraph.ResolveProjectReferenceDependencies(projectsToEvaluate); string output = MSBPRDependencyGraph.CreateDOTGraph(projectReferenceDependencies, targetProject, anonymizeNames, sortOutput, false); Console.WriteLine(output); }
/// <summary> /// Given a IEnumerable of Target Project Files, return all Package References. /// </summary> /// <param name="targetProjects">An IEnumerable of strings that represent MSBuild Projects.</param> /// <returns>A Dictionary in which the Key is the Project Path, and the Value is an IEnumerable of all its referenced Packages</returns> internal static Dictionary <string, IEnumerable <string> > ResolvePackageReferenceDependencies(IEnumerable <string> targetProjects) { ConcurrentBag <KeyValuePair <string, IEnumerable <string> > > resolvedPackageReferences = new ConcurrentBag <KeyValuePair <string, IEnumerable <string> > >(); // Because of the large number of projects that could be scanned perform this in parallel. Parallel.ForEach(targetProjects, targetProject => { IEnumerable <string> currentProjectPackageReferences = MSBuildUtilities.PackageReferences(targetProject); KeyValuePair <string, IEnumerable <string> > currentResult = new KeyValuePair <string, IEnumerable <string> >(targetProject, currentProjectPackageReferences); resolvedPackageReferences.Add(currentResult); } ); // Convert this into the Dictionary Dictionary <string, IEnumerable <string> > result = new Dictionary <string, IEnumerable <string> >(); foreach (KeyValuePair <string, IEnumerable <string> > kvp in resolvedPackageReferences) { result.Add(kvp.Key, kvp.Value); } return(result); }
/// <summary> /// Given a IEnumerable of Target Project Files, Resolve All N-Order ProjectReference Dependencies. /// </summary> /// <param name="targetProjects">An IEnumerable of strings that represent MSBuild Projects.</param> /// <returns>A Dictionary in which the Key is the Project, and the Value is an IEnumerable of all its Project Reference projects</returns> internal static Dictionary <string, IEnumerable <string> > ResolveProjectReferenceDependencies(IEnumerable <string> targetProjects) { Stack <string> unresolvedProjects = new Stack <string>(); Dictionary <string, IEnumerable <string> > resolvedProjects = new Dictionary <string, IEnumerable <string> >(); // Load up the initial projects to the stack foreach (string targetProject in targetProjects.Distinct()) { unresolvedProjects.Push(targetProject); } while (unresolvedProjects.Count > 0) { string currentProject = unresolvedProjects.Pop(); // First check just to make sure it wasn't already resolved. if (!resolvedProjects.ContainsKey(currentProject)) { // Get all this projects references string[] projectDependencies = MSBuildUtilities.ProjectDependencies(currentProject).ToArray(); resolvedProjects.Add(currentProject, projectDependencies); foreach (string projectDependency in projectDependencies) { // Save the stack by not resolving already resolved projects if (!resolvedProjects.ContainsKey(projectDependency)) { unresolvedProjects.Push(projectDependency); } } } } return(resolvedProjects); }
static void Main(string[] args) { string targetFile = string.Empty; bool showHelp = false; // Create an Options Object MSBPROptions options = new MSBPROptions(); OptionSet p = new OptionSet() { { "<>", Strings.TargetArgumentDescription, v => targetFile = v }, { "a|anonymize", Strings.AnonymizeDescription, v => options.AnonymizeNames = v != null }, { "sA|ShowAllReferences", Strings.ShowAllReferencesDescription, v => { if (v != null) { options.ShowAssemblyReferences = true; options.ShowPackageReferences = true; } } }, { "sar|ShowAssemblyReferences", Strings.ShowAssemblyReferencesDescription, v => options.ShowAssemblyReferences = v != null }, { "spr|ShowPackageReferences", Strings.ShowPackageReferencesDescription, v => options.ShowPackageReferences = v != null }, { "s|sort", Strings.SortDescription, v => options.SortProjects = v != null }, { "?|h|help", Strings.HelpDescription, v => showHelp = v != null }, }; try { p.Parse(args); } catch (OptionException) { Console.WriteLine(Strings.ShortUsageMessage); Console.WriteLine($"Try `{Strings.ProgramName} --help` for more information."); return; } if (showHelp || string.IsNullOrEmpty(targetFile)) { Environment.ExitCode = ShowUsage(p); } else if (!File.Exists(targetFile)) { Console.WriteLine(Strings.InvalidTargetArgument, targetFile); Environment.ExitCode = 9009; } else { List <string> projectsToEvaluate = new List <string>(); if (Path.GetExtension(targetFile).Equals(".sln", StringComparison.InvariantCultureIgnoreCase)) { IEnumerable <string> projectsInSolution = MSBuildUtilities.GetProjectsFromSolution(targetFile); // These come back as relative paths; we need to "expand" them // otherwise we'll get duplicates when we go to resolve. projectsInSolution = projectsInSolution.Select(relativeProjectPath => Path.GetFullPath(relativeProjectPath)); projectsToEvaluate.AddRange(projectsInSolution); } else { // Assume its just a single project FileInfo fi = new FileInfo(targetFile); projectsToEvaluate.Add(fi.FullName); } Dictionary <string, IEnumerable <string> > projectReferenceDependencies = MSBPRDependencyGraph.ResolveProjectReferenceDependencies(projectsToEvaluate); string output = MSBPRDependencyGraph.CreateDOTGraph(projectReferenceDependencies, options); Console.WriteLine(output); } }