laedit Jérémie Bertrand

Using NDepend on Linux

on ndepend, linux

Disclaimer: Like the last time I was offered a 1 year NDepend pro license by Patrick Smacchia (NDepend creator) so I could use it and share my experience if I wanted to.
Since then I switched to Linux and was working on a little dotnet console backup utiliy which copies files and folders using rsync and cp and using source generator to handle DBus notifications, so I was curious about how NDepend will handle it.

Installation

Download the NDepend zip redistributable 14 days free trial at the price of an email or if you already have a license you can get the pro edition.
You will have a zip file to place wherever you want, I chose the recommended folder /home/$USER/ndepend/. The dotnet SDK is a prerequisite and can be downloaded here, I already have dotnet 9 installed and will use it for running NDepend.

Registration

You can then register for the 14 days trial with this command:

dotnet ~/ndepend/net9.0/NDepend.Console.MultiOS.dll --RegEval

Or if you have a license key:

dotnet ~/ndepend/net9.0/NDepend.Console.MultiOS.dll --RegLic [License key]

Analysis

First let's create an ndepend projet:

dotnet ~/ndepend/net9.0/NDepend.Console.MultiOS.dll --CreateProject ./bafifo.ndproj ./bafifo/bafifo.csproj

And run the first analysis:

dotnet ~/ndepend/net9.0/NDepend.Console.MultiOS.dll ./bafifo.ndproj

With a direct result:

ERROR:   2 quality gates fail:
  - 'Critical Rules Violated' value 3 rules greater than fail threshold 0 rules
  - 'Debt Rating per Namespace' value 2 namespaces greater than fail threshold 0 namespaces

Luckily NDepend generates a complete report in HTML file NDependOut/NDependReport.html so here are a better view at the quality gates:
NDepend quality gates for my project

It includes rules: Rules in source file

Which are also integrated in source files: Rules in source file

Besides the report, NDepend generates an interactive component dependencies matrix on NDependOut/NDependReportFiles/ComponentDependenciesMatrix.html (ouch, I have work to do):
NDepend component dependencies matrix for my project

And an interactive component dependencies diagram on NDependOut/NDependReportFiles/ComponentDependenciesDiagram.html:
NDepend component dependencies diagram for my project

Fixes

ND1400 - Avoid namespaces mutually dependent and ND1401 - Avoid namespaces dependency cycles
It was a utility class in the wrong namespace, a quick move of the file, fix its namespace and it was good.

ND1901 - Avoid non-readonly static fields
Forgot a readonly on a static field.

ND1807 - Avoid public methods not publicly visible
Nice one to catch over exposed methods and properties. It also picked up a public init on a property setter in a class which has only one private constructor with a parameter to initialize that property, so the init can only be used by that constructor.
In my opinion it can be seen as a bit much but at least it forces the consistancy throughout the code.

ND1311 - Don't use obsolete types, methods or fields
This one was caused by a dependency which used an obsolete type but a new version of the package fixed that.

ND1803 - Types that could be declared as private, nested in a parent type
This one included types generated by a source generator, a custom notmycode rule in the JustMyCode group inserted in the .ndproj file fixed it:

// <Name>Discard generated code from Tmds.DBus.SourceGenerator from JustMyCode</Name>
notmycode
from t in Application.Types where
t.ParentNamespace.Name.Equals("Tmds.DBus.SourceGenerator")
select t

ND1208 - Methods should be declared static if possible
Amongst the methods listed was get_EqualityContract() which is generated by the record keyword, it can be discarded by excluding methods marked with System.Runtime.CompilerServices.CompilerGeneratedAttribute:

// <Name>Discard generated mehods marked by CompilerGenerated from JustMyCode</Name>
notmycode
from m in Application.Methods where
m.HasAttribute("System.Runtime.CompilerServices.CompilerGeneratedAttribute".AllowNoMatch())
select m

ND2208 - Do not raise reserved exception types
The only methods listed were not from my code:

ND2103 - Namespace name should correspond to file location
Got this issue for the files containing the declarations of the namespace bafifo.Configuration which are located in the directory /repos/bafifo/bafifo/Configuration. After having checkd for typos but found nothing and compared to other files in other namespaces/folders I don't know what is bugging here.

Conclusion

I am glad to see it working well on linux, including the generation of all the reports and graphs.
There are just 3 things that can be improved :

Sources:

No comments (for now), but you can reach me on mastodon.