Though very usual in programming environments as Javascript/Typescript, linting, or analyzing code for enforcing a set of coding style rules, is not usually present in the .NET based environments.
Rule enforcing is really useful when working on team shared codebases in order to keep them coherent, what in last term reduces both development times and coding errors.
A linting example
Maybe a practical example would be helpful for explaining what linting is to the newcomers (feel free to go on if you aren't).
Let's imagine you are a new member in a C# development team that has well established set of coding style rules. Instead (or apart) of putting them in a document, they've adopted a tool that checks these rules during the code building process. Your first code is such ambitious as this:
namespace HelloWorld
{
using System;
public class Program
{
public static void Main(string[] args)
{
Console.Write("Hello world!");
}
}
}
Instead of reviewing the styling documentation in order to check if your code meets the rules, you're using a linter that checks those rules for you during the building process. So when you build that masterpiece you get this warning:
warning SA1600: Elements should be documented
WTF means it? When you check the linter documentation you find that the rule SA1600 states that the classes and their methods must be properly documented. So you fix your code in this way:
namespace HelloWorld
{
using System;
/// <summary>Program class.</summary>
public class Program
{
/// <summary>Program entry point.</summary>
/// <param name="args">Command line args.</param>
public static void Main(string[] args)
{
Console.Write("Hello world!");
}
}
}
Now the code builds with no warnings and your first work is aligned with the team coding style at near-zero effort cost.
Adding linter support to C# in Visual Studio Code
As the blog entry claimed, the aim of this article is exposing how to use a Code Quality Analyzer (or linter) in an scenario defined by C# as programming language, .NET/.NET Core as framework and Visual Studio Code as IDE.
The proposed solution is based on StyleCopAnalyzers, a solution based on the original Microsoft's StyleCop that allows:
- Applying rules to C# codebase using Visual Studio Code.
- Customizing the behaviour of certain defined rules, modify rule criticity and even disabling rules.
- Defining rulesets per project.
- Checking the source code quality at build time, what allows seamless integration with CI tools, so code analysis can be performed when it's being deployed and, in case of finding unmet rules, stopping the deployment process.
To apply StyleCopAnalyzers to a C# project, the first step is installing it by opening a Visual Studio Code terminal (Menu Terminal/New Terminal) and typing:
dotnet add package StyleCop.Analyzers
That command will add the StyleCop.Analyzers package to the project and will perform the required changes in the .csproj file to start using it.
Now, when building your code is very probable that you received a good bunch of warnings dropped by StyleCop, so it's time to customize it.
Customization
The first, optional thing is converting those warnings into errors, so if the building process is executed by a CI tool it was able to detect a problem and stop the code deployment. To do it, edit the project file (extension .csproj) and add a
TreatWarningsAsErrors
property set to true
:
<PropertyGroup>
...
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
If you are not concerned by CI tools or, in general, treating the linting problems as warnings is not a problem, the above step can be omitted.
Now let's deal with the most important customization: The StyleCop rules and how they are applied. This behaviour is configured via two files:
- The rule sets file: It contains the set of rules that the analyzer will apply and the criticity of each uncomplishment. In practice, it allows both creating a hierachical organization of rules based on their criticity (
error, warning, info
) and disabling rules by setting their criticity tonone
. - The
stylecop.json
file, that allows customizing how certain rules will be applied. Notice that we are not customizing their criticity but how code is being analyzed.
Regarding the rule sets file, it is not necessary: if it's not present, StyleCop will apply a set of predefined rules. However, my very best advice is always adding the rule set file that matches those predefined rules, so in that way modifying them was easier.
The default rule set file can be downloaded from here. In order to keep the project files organized, I recommend creating a
.stylecop
directory in the project directory root and putting that file in it renamed as stylecop.ruleset.xml
.
Once done, configure the project to use the ruleset by adding a
CodeAnalysisRuleSet
property in the project file (extension .csproj):
<PropertyGroup>
...
<CodeAnalysisRuleSet>$(SolutionDir).stylecop/stylecop.ruleset.xml</CodeAnalysisRuleSet>
</PropertyGroup>
Finally, as the rule set file, the
stylecop.json
file is also not necessary, but again it's a good idea creating it even being empty. The main reasons are two: Keeping the project properly configured from scratch by setting the stylecop.json
file location, and giving support to VSCode Intellisense by attaching the stylecop.json
schema file.
So as a first step download the
stylecop.json
schema file from here and store it in the .stylecop
folder as stylecop.schema.json
. Then create a minimal stylecop.json
file in the same folder with this content:
{
"$schema": "./stylecop.schema.json",
"settings": {}
}
Then configure StyleCop to use the newly created
stylecop.json
file by setting the AdditionalFiles
property in the project file (extension .csproj):
<ItemGroup>
...
<AdditionalFiles Include=".stylecop/stylecop.json" />
</ItemGroup>
Now you'll be able to fine-tune the behaviour of StyleCop by checking its documentation and setting the required options in the
stylecop.json
.
Last but not least
At this point StyleCop will behave as Javascript/Typescript linters except for one thing: It won't be able to apply default fixes, something really useful in order to save time when dealing with big basecodes.
This behaviour can be partly adopted by enabling analyzers in OmniSharp (thanks, Filip W.). To do so, go to Visual Studio Code preferences (menu File/Preferences/Settings) and type "omnisharp analyzers" in the settings search box. You'll be able to enable Omnisharp support to analyzers both globally (if enabled at User level) or at project level (if enabled at Workspace level).
Once set, reload Visual Studio Code and you'll start to receive StyleCop messages in the Problems window, the problems will be highlighted in code and a default fix (the holly bulb) will be proposed.
As you can see in the previous screenshot, among others a SA1200 problem has been detected at line 9 ("Using directive should appear within a namespace declaration"), the line is highlighted in the editor window and a fix ("Reorder using statements") is proposed.
Conclusion
At the date of writing this article, there's no way of automatically fixing all the problems found in Visual Studio Code (not so in Visual Studio). I'm not sure if that's good or bad, some programmers blaim against these cool features whereas other love them.
With it, StyleCop would fully perform as Javascript/Typescript linters. In my opinion, even lacking the automatic fixing feature, StyleCop with Omnisharp is damn good enough to be adopted in professional environments based on C#, .NET (Core) and Visual Studio Code in which a code analysis tool was required to keep the codebase homogeneous.
Comentarios
Publicar un comentario