📜 ⬆️ ⬇️

Do-it-yourself analysis of links in a project

In order to begin to understand a large project, you need to understand what logical modules are in the project and how they are related. In the case of using Visual Studio in expensive editions of the product, functions for constructing various dependency graphs are available. Unfortunately, first of all, the studios with the menu “Architecture” are really expensive. Secondly, in old projects that are still being collected and have project files only for Visual Studio 2008, the studio itself does not offer much.

Of course, it is worth noting that for such a purpose there are expensive tools (for example, Understand). But for starters, I had enough of what I sketched a small script on PowerShell. This script generates a dot-file for GraphViz based on the sln file. The result is a scheme as in the figure below, from which you can already begin to understand the project.


')
Further I will tell how this script works.

The first thing I needed to do was analyze the sln files and the project files that are written there. Immediately lucky with the sln files, since in different studio versions (starting with Visual Studio 2008) the list of projects looks the same, like a set of lines of the following form:

Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BaseClasses Apr05", "..\..\3rd_party\BaseClasses_Apr05\baseclasses90.vcproj", "{2A939EC4-235F-4879-9D38-C865FFD54D82}" EndProject 

You can pull out the list of all such lines in one line on PowerShell:

 Select-String -LiteralPath $slnFile -Pattern "Project\(.*vcproj" 

It is clear that $ slnFile is the path to the file, and “Project \ (. * Vcproj” is a regular expression for selecting strings. In the sln file, all paths are relative. The next task is to pull out relative paths from the resulting lines and build complete paths on their basis to files. This can be done in one more line:

 Join-Path -Path $slnPath -ChildPath ($s -split ',')[1].Trim().Replace('"','') 

Here it is assumed that $ s contains one of the previously received strings. It is clear that division into substrings, which are separated by a comma, with the command ($ s -split ',') occurs. The second substring (obtained using [1]) just contains the relative path. Remove extra spaces with Trim and remove quotes with Replace. Then attach the path to the relative path to the sln file with the Join-Path command. Wrapping it in a loop, we got a set of paths to projects. Now it's time to look at the project files to find the dependencies between them.

Microsoft at the time of transition to Vistual Studio 2010 changed the format of project files. But the good thing is that the solution files in both VS2008 and VS2010 have XML format. This allows you to use an XPath query language to easily get the field you want. In PowerShell, this is done with the Select-Xml command. Using it, it is easy to pull out dependencies from a project file. Also, I want to see different types of projects in the final column displayed in different colors. For this you need to find out what types are. This can be done by setting the following command to a directory with a bunch of projects:

 PS D:\test> Get-ChildItem -Path . -Filter *.vcxproj -Recurse | Select-Xml -XPath "//*[local-name()=`"ConfigurationType`"]/text()" | % { Write-Output $_.Node.Value } 

You may notice that in PowerShell, the stream with the results of command execution is conveniently redirected to the next command using the “|” symbol. The Get-ChildItem command helps to find all files of the vcxproj type, and Select-Xml selects the type of configuration from them. For each file, display the type of project on the screen. With a large number of files, the output is not very informative, but in PowerShell there is a Group-Object command that saves the situation by grouping the results. Total we get something like this:

 PS D:\test> Get-ChildItem -Path . -Filter *.vcxproj -Recurse | Select-Xml -XPath "//*[local-name()=`"ConfigurationType`"]/text()" | % { Write-Output $_.Node.Value } | Group-Object Count Name Group ----- ---- ----- 92 StaticLibrary {StaticLibrary, StaticLibrary, StaticLibrary, StaticLibrary...} 287 Application {Application, Application, Application, Application...} 424 DynamicLibrary {DynamicLibrary, DynamicLibrary, DynamicLibrary, DynamicLibrary...} 

Similarly, you can do for files of types vcproj, csproj and others. In vcproj files, configuration types are encoded with numbers, but what is behind them is not difficult to find out by opening a project in Visual Studio.

At this stage, we have projects, their types and links between them. You can generate a GraphViz file. This is done very simply - we immediately write the following title:

 digraph ProjectName { size="60,60"; rankdir=LR; overlap=false; splines=true; dpi=300; node[color=mediumorchid3, style=filled, shape=box, fontsize=10, fontcolor=white]; edge[arrowhead=vee, arrowtail=inv, arrowsize=.7, fontsize=10, fontcolor=navy]; labelloc=t; label="Solution: ProjectName.sln"; fontsize=14; 

And then all the projects and links between them:

 "project1.vcproj" [color=indigo]; "project1.vcproj" -> "project2.vcproj" [color="#C3E500"]; "project2.vcproj" [color=indigo]; 

The color of the link is tied to the project to make it easier to read the graph. Those. each project all outgoing communication of the same color. You can do this using the HSL (from the English. Hue, Saturation, Lightness) color representation. We fix S and L components, and H is changed when processing the next project file. Then HSL convert to RGB and write to the output file.

The source code of the color picker function, as well as the rest of the script, can be found on GitHub .

Source: https://habr.com/ru/post/258295/


All Articles