/// <summary>
        /// Given a Dictionary in which the Key Represents the Project and the Value represents the list Project Dependencies, generate a DOT Graph.
        /// </summary>
        /// <param name="projectReferenceDependencies">The dictionary to generate the graph for.</param>
        /// <param name="anonymizeNames">Determines if the names should be anonymized.</param>
        /// <param name="sortProjects">Determines if the output of the DOT Graph should be sorted.</param>
        /// <param name="showAssemblyReferences">Determines if Assembly/PackageReferences should be shown on the graph.</param>
        /// <returns>A string that represents a DOT Graph</returns>
        internal static string CreateDOTGraph(IDictionary <string, IEnumerable <string> > projectReferenceDependencies, MSBPROptions options)
        {
            // If we are going to use a anonymizer initialize it
            Anonymizer <string> anonymizer = null;

            if (options.AnonymizeNames)
            {
                anonymizer = new Anonymizer <string>();
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("digraph {");

            // If we need to sort the projects do so at this time
            IEnumerable <KeyValuePair <string, IEnumerable <string> > > projectReferenceDependenciesToPrint = projectReferenceDependencies;

            if (options.SortProjects)
            {
                projectReferenceDependenciesToPrint = projectReferenceDependencies.OrderBy(kvp => Path.GetFileName(kvp.Key));
            }

            // Perform the ProjectReference Results
            foreach (KeyValuePair <string, IEnumerable <string> > kvp in projectReferenceDependenciesToPrint)
            {
                string projectName = Path.GetFileName(kvp.Key);

                if (options.AnonymizeNames)
                {
                    projectName = anonymizer.Anonymoize(projectName);
                }

                IEnumerable <string> projectReferences = kvp.Value;

                if (options.SortProjects)
                {
                    projectReferences = projectReferences.OrderBy(filePath => Path.GetFileName(filePath));
                }

                sb.AppendLine($"\"{projectName}\"");

                foreach (string projectDependency in projectReferences)
                {
                    string projectDependencyName = Path.GetFileName(projectDependency);

                    if (options.AnonymizeNames)
                    {
                        projectDependencyName = anonymizer.Anonymoize(projectDependencyName);
                    }

                    sb.AppendLine($"\"{projectName}\" -> \"{projectDependencyName}\"");
                }
            }

            // If we need to show assembly references find them
            if (options.ShowAssemblyReferences)
            {
                sb.AppendLine("//--------------------------");
                sb.AppendLine("// AssemblyReference Section");
                sb.AppendLine("//--------------------------");
                Dictionary <string, IEnumerable <string> > assemblyReferenceDependencies = ResolveAssemblyReferenceDependencies(projectReferenceDependencies.Keys);
                IEnumerable <string> assemblyReferenceSection = GenerateAssemblyReferenceSection(anonymizer, assemblyReferenceDependencies);

                if (options.SortProjects)
                {
                    assemblyReferenceSection = assemblyReferenceSection.OrderBy(x => x);
                }

                foreach (string line in assemblyReferenceSection)
                {
                    sb.AppendLine(line);
                }
            }

            if (options.ShowPackageReferences)
            {
                sb.AppendLine("//--------------------------");
                sb.AppendLine("// PackageReference Section");
                sb.AppendLine("//--------------------------");
                Dictionary <string, IEnumerable <string> > packageReferenceDependencies = ResolvePackageReferenceDependencies(projectReferenceDependencies.Keys);
                IEnumerable <string> packageReferenceSection = GeneratePackageReferenceSection(anonymizer, packageReferenceDependencies);

                if (options.SortProjects)
                {
                    packageReferenceSection = packageReferenceSection.OrderBy(x => x);
                }

                foreach (string line in packageReferenceSection)
                {
                    sb.AppendLine(line);
                }
            }

            sb.AppendLine("}");

            return(sb.ToString());
        }
Exemplo n.º 2
0
        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);
            }
        }