How to Start an Advanced .NET Project in 2024 Part II
If you don’t read the first article, be sure to read the first article first.
In the previous post, we talked about the types of analyzers. We have seen how we can improve the quality of written codes. And during PR, we should focus on the business code and leave the technical issues to the analyzers as much as possible.
I was very excited when I first met the Husky project. This project allows you to have access to Git Hook and you can perform your actions on it. If you don’t know about Git Hook, read this article.
This is where it gets interesting. Suppose you can do some work before the developer commits or pushes. I mean pre-commit and pre-push.
Fortunately, there is a Husky project on .net called Husky.Net.
Let’s talk about the idea we have.
- We want to reformat the code before the developer code is committed so that the code is cleanly added to the project.
- Before committing the code, we check the entered commit message so that the standard has been entered.
Check commit messages
We use this standard to check commit messages.
Code Formatting
To format the code. We have the following popular tools
- dotnet-format
My favorite library :) This library is created by Microsoft itself.
This library has the principles of code cleanliness inside it and also supports .editorconfig. link
- csharpier
CSharpier is an opinionated code formatter for c#. It uses Roslyn to parse your code and re-print it using its own rules. The printing process was ported from prettier but has evolved. link
I am using dotnet-format here.
In this article, I don’t want to go into the details of working with Husky, fortunately, it has good documentation.
How to configure
- Add Custom Nuget for dotnet-format
First, we add the nuget file so that we can use the latest version of dotnet-format
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="MyArtifactory" value="https://repo.mofid.dev/artifactory/api/nuget/v3/nuget" protocolVersion="3" />
<add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />
</packageSources>
<packageSourceMapping>
<packageSource key="MyArtifactory">
<package pattern="*" />
</packageSource>
<packageSource key="dotnet8">
<package pattern="dotnet-format" />
</packageSource>
</packageSourceMapping>
</configuration>
- Install Husky.Net
dotnet tool install Husky
- Install dotnet-format
dotnet tool install dotnet-format
- Check dotnet-tools file
{
"version": 1,
"isRoot": true,
"tools": {
"husky": {
"version": "0.6.4",
"commands": [
"husky"
]
},
"dotnet-format": {
"version": "8.0.453106",
"commands": [
"dotnet-format"
]
}
}
}
- Add to project file
<Target Name="Husky" BeforeTargets="Restore;CollectPackageReferences" Condition="'$(HUSKY)' != 0">
<Exec Command="dotnet tool restore" StandardOutputImportance="Low" StandardErrorImportance="High" />
<Exec Command="dotnet tool install dotnet-format" StandardOutputImportance="Low" StandardErrorImportance="High" />
<Exec Command="dotnet husky install" StandardOutputImportance="Low" StandardErrorImportance="High" WorkingDirectory="..\..\.." />
</Target>
- Add pre-commit tasks
{
"tasks": [
{
"name": "commit-message-linter",
"command": "dotnet",
"args": [
"husky",
"exec",
".husky/csx/commit-lint.csx",
"--args",
"${args}"
]
},
{
"name": "dotnet-format",
"group": "pre-commit",
"command": "dotnet",
"args": [ "dotnet-format", "--include", "${staged}", "--no-restore" ],
"include": [ "**/*.cs" ]
}
]
}
- Add commit-lint.csx file
using System.Text.RegularExpressions;
private var pattern = @"^(?=.{1,90}$)(?:build|feat|ci|chore|docs|fix|perf|refactor|revert|style|test|wip)(?:\(.+\))*(?::).{4,}(?:#\d+)*(?<![\.\s])$";
private var msg = File.ReadAllLines(Args[0])[0];
if (Regex.IsMatch(msg, pattern, RegexOptions.Compiled))
return 0;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid commit message");
Console.ResetColor();
Console.WriteLine("e.g: 'feat(scope): subject' or 'fix: subject'");
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("more info: https://www.conventionalcommits.org/en/v1.0.0/");
return 1;