Giter Site home page Giter Site logo

aolszowka / msbuildprojectreferencedependencygraph Goto Github PK

View Code? Open in Web Editor NEW
19.0 2.0 7.0 151 KB

Utility to take a MsBuild Project File and generate a DOT Graph of all its ProjectReference Elements

License: MIT License

C# 83.28% GAP 1.85% G-code 13.37% Batchfile 1.50%
msbuild dot-graph projectreference-elements

msbuildprojectreferencedependencygraph's Introduction

MsBuildProjectReferenceDependencyGraph

CI - Master

Utility to take a MsBuild Project File or Visual Studio Solution file and generate a DOT Graph of all its ProjectReference Elements

Usage

dotnet create-digraph MyProject.csproj > out.g

or

MsBuildProjectReferenceDependencyGraph.exe MyProject.csproj > out.g

Because the output is simply piped to Standard Out we redirect it to an output file for further processing by other utilities.

For example you can use Webgraphviz (http://www.webgraphviz.com/) to produce a graph online or download and install GraphViz (https://graphviz.gitlab.io/)

Extended Help

There are now two ways to run this tool:

  1. (Compiled Executable) Invoke the tool via MsBuildProjectReferenceDependencyGraph and pass the arguments.
  2. (Dotnet Tool) Install this tool using the following command dotnet tool install MsBuildProjectReferenceDependencyGraph (assuming that you have the nuget package in your feed) then invoke it via dotnet create-digraph

In both cases the flags to the tooling are identical:

Usage: MyProject.sln-or-proj [-s][-a][-sar][-spr][-sA]

Takes either an MsBuild Project File or Visual Studio Solution File and generate
a DOT Graph of all its ProjectReference Elements.

               <>            The Project or Solution to evaluate
  -a, --anonymize            Anonymizes the names of all references
      --sA, --ShowAllReferences
                             Show both "Assembly" and "PackageReference"
                               References in graph
      --sar, --ShowAssemblyReferences
                             Show "Assembly" References in graph
      --spr, --ShowPackageReferences
                             Show "PackageReference" References in graph
  -s, --sort                 Sort the output of this tool
  -?, -h, --help             Show this message and exit

In all of the examples below we show this tool being invoked via the dotnet create-digraph command but it would alternatively work with MsBuildProjectReferenceDependencyGraph.exe as well.

Anonymize (-a | --anonymize)

Produce an anonymized version of your graph. This is useful for when you wish to share the general shape of your dependency tree without exposing any privileged information.

dotnet create-diagraph MyProject.csproj -a > out.g

digraph {
"1"
"2"
"3"
"3" -> "1"
"3" -> "2"
}

Show* Flags

This program was originally designed only to trace <ProjectReference> References, however it has been extended to support showing other similar References such as <Assembly> and <PackageReference> directives. You must pass the appropriate flag to have the tool follow these.

They are each put into their own section in the generated DotGraph and are also appended with a [class=""] attribute to allow for any custom CSS applied to the DotGraph to call these out in a different style.

Be warned that this can generate extremely complex graphs.

ShowAllReferences (-sA | --ShowAllReferences)

This combines all of the flags described below into a single argument.

dotnet create-diagraph ProjectD.csproj -sA > out.g

digraph {
"ProjectD.csproj"
//--------------------------
// AssemblyReference Section
//--------------------------
"Moq" [class="AssemblyReference"]
"ProjectD.csproj" -> "Moq"
"ProjectD.csproj" -> "System"
"System" [class="AssemblyReference"]
//--------------------------
// PackageReference Section
//--------------------------
"NUnit" [class="PackageReference"]
"ProjectD.csproj" -> "NUnit"
}

ShowAssemblyReferences (-sar | --ShowAssemblyReferences)

In addition to displaying <ProjectReference> a new section will be generated in the DotGraph to show <Assembly> References.

WARNING Assembly References are considered "best effort" they are truncated down to just the assembly name. This means that if you have projects with references like:

Project 1

<Reference Include="Moq, Version=4.0.10827.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
    <HintPath>..\..\..\..\..\ProductDependencies\Moq\Moq.dll</HintPath>
</Reference>

Project 2

<Reference Include="Moq, Version=5.0.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL" />

Project 3

<Reference Include="Moq" />

This tooling treats all them as the same reference, even though MSBuild will not. This was done to simplify the processing of the dependencies.

dotnet create-diagraph MoqProject.csproj -sA > out.g

digraph {
"MoqProject.csproj"
//--------------------------
// AssemblyReference Section
//--------------------------
"Moq" [class="AssemblyReference"]
"MoqProject.csproj" -> "Moq"
}

ShowPackageReferences (-spr | --ShowPackageReferences)

In addition to displaying <ProjectReference> a new section will be generated in the DotGraph to show <PackageReference> References.

WARNING Package References are considered "best effort" they are based on just the package name and do not account for the version. This means that if you have projects with references like:

Project 1

<PackageReference Include="NUnit">
    <Version>3.11.0</Version>
</PackageReference>

Project 2

<PackageReference Include="NUnit">
    <Version>3.12.0</Version>
</PackageReference>

This tooling treats all them as the same reference, even though MSBuild will not. This was done to simplify the processing of the dependencies.

dotnet create-diagraph NUnitProject.csproj -sA > out.g

digraph {
"NUnitProject.csproj"
//--------------------------
// PackageReference Section
//--------------------------
"NUnit" [class="PackageReference"]
"NUnitProject.csproj" -> "NUnit"
}

Sort (-s | --sort)

Sort the output (based on filename) if you need the output to be idempotent. For example consider using the tool to dump trees in a tight loop and committing the changes (if any) into a version control system.

dotnet create-diagraph MyProject.csproj -s > out.g

GOTCHAs

Line Endings

This tool heavily utilizes StringBuilder.AppendLine(string) to build up the digraphs. As of the writing of this program, Microsoft implements this using Envrionment.NewLine and does not provide a way for consumers of StringBuilder to override this.

This means that when this tool is used on non-Windows platforms the line endings of the generated digraph files are \n (Line Feed) as opposed to \r\n (Carriage Return Line Feed) in Windows. Currently this tool does not attempt to perform any normalization and is left as an exercise to the reader.

License

This is licensed under the MIT License.

Third Party Licenses

This project uses other open source contributions see LICENSES.md for a comprehensive listing.

Bugs/Feature Requests

I accept pull requests and am responsive on GitHub, Let me know!

msbuildprojectreferencedependencygraph's People

Contributors

aolszowka avatar madkat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

msbuildprojectreferencedependencygraph's Issues

Needs a .gitignore

The project currently has no .gitignore, so any local build shows changes in the repo.

C++ style Shared Projects populated as orphaned nodes

Not sure if this is a bug in this software, or a failure on the MSBuild side to correctly process the distinction, but utilizing C++ Shared Projects results in orphaned nodes for the shared project itself. C# Shared Project nodes do not appear in the graph at all.

Snip from a solution file demonstrating how the two types of shared projects are contained:

Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SynergyCodeGenerator", "SynergyCodeGenerator\SynergyCodeGenerator.shproj", "{676A1601-B931-48B6-8FE4-67E0E57E0CE6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SynergyDotnetAnalysisEngine", "SynergyDotnetAnalysisEngine\SynergyDotnetAnalysisEngine.vcxitems", "{4FA605A4-7114-4B20-980A-935DD4069F03}"
EndProject

There are minor differences in how those imports are handled on consuming projects. I do not think the import format is relevant unless we want to establish dependence on Shared Projects.
C++

<ImportGroup Label="Shared">
    <Import Project="..\SynergyDotnetAnalysisEngine.vcxitems" Label="Shared" />
</ImportGroup>

C#

<Import Project="..\SynergyCodeGenerator.projitems" Label="Shared" />

My assumption is that this is a difference on the MSBuild side since I do not see any specific handling for .shproj in this source base. Perhaps there is a workaround that could be done here, or a better issue to be logged in MSBuild.

Request: Optionally Show the Full Path to the Projects

The Short
Optionally provide the ability to show the full path of the project in the graph.

The Long
Historically this project has truncated the output to have only the file name of the project, this has severe limitations if the file names are reused at different depths.

This was never encountered in the project because this is also a limitation of the Solution File Format (and therefore would not have been possible off of a single solution). In fact https://github.com/aolszowka/MsBuildFindDuplicateProjectFileNames was written to identify this issue and resolve it.

However as the use of this Dependency graph continues to grow it is useful to know what the full path is to the projects in question.

Request: Utilize NDesk.Options For Options Parsing

tl;dr; Use http://www.ndesk.org/Options to perform our options parsing. Its MIT Licensed which is compatible with the license of this project and is extremely lightweight.

Currently we do a bunch of manual options parsing, however this makes it difficult to extend this program by forcing us to deal with command line parsing which isn't our goal. Rather we should spin this out into a library.

There are lots of options parsing libraries available to us, for example Microsoft provides https://github.com/dotnet/command-line-api. However if you look at the number of dependencies that has to carry around you nope out of that pretty quickly.

Rather I am going to suggest we use NDesk.Options for parsing, its a super lightweight dependency (just a single CS file), the usage is very straight forward, and is MIT Licensed.

The only downsides I can see is that it is not actively maintained (last updated back in 2008) and has some pretty gnarly LINQ in it to perform its magic. This probably means that there are some corner cases but at this point its better than rolling our own.

Bug: Not All MSBuild Project Formats Supported When Using Solution Files (.SLN)

When support was added for solution files an additional bug was found in that Solution Folders were inadvertently being used. Unfortunately the fix was to filter using the MsBuild API to select only KnownToBeMSBuildFormat as seen here:

.Where(project => project.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat)

Which was added on On e81ea24

However if the project type has not been registered with their API (such as the case with synproj files) this falls over.

Design: Refactor Options Passing

The primary driver for the generation of the graph is here:

internal static string CreateDOTGraph(IDictionary<string, IEnumerable<string>> projectReferenceDependencies, bool anonymizeNames, bool sortProjects, bool showAssemblyReferences)

As it stands today this is just taking additional arguments. Its probably getting to the point where this should be refactored into a DTO of some sort to pass the options around.

Request: Anonymizer

As a user, I would like all of my project names to be anonymized so that I can safely share my graph with others.

Request: Convert to .NET Core

Convert this project to .NET Core

The reason is I would like to try and ship these tools as a .NET Core Tool (https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools-how-to-create)

I have been getting pretty good at these conversions and have only had a few "gotchas", in addition I am finding it easiest if I also enable GitHub Actions at the same time (closing #17) to allow for cross-platform unit testing as well as automated NuGet Package creation/distribution. See the latest conversion of VisualStudioSolutionUpdater here: aolszowka/VisualStudioSolutionUpdater#14

Its unclear how many people utilize this in their day to day workflow, but I utilize it pretty heavily myself so it will at least get tested on the Windows side.

@madkat I know you help build the pre-alpha version of this tool initially, but I have no idea if you continued to use it after that, any immediate "don't do this" out of you personally?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.