Enforcing C# EditorConfig formatting conventions at build time

Β· 619 words Β· 3 minutes to read

EditorConfig is an excellent way to enforce stylistic rules on your C# projects. However, the rules and their corresponding IDExxxx diagnostics are only enforced in the editor, such as Visual Studio or VS Code with OmniSharp, but not at build time.

While there are various categories of EditorConfig conventions that you can use, in this post, I will show you how to enforce the formatting conventions (IDE0055) at build time.

Why doesn’t it work out of the box? πŸ”—

The reason why the EditorConfig rule violations would not be respected at build time, is that at the moment the rules are defined in the Microsoft.CodeAnalysis.CSharp.Features assembly, which is only embedded into the editor, and not known to the compiler outside of the IDE context. They do have lots of dependencies (i.e. Workspace related) that prevent them from being used in the typical analyzers format - which would address the problem, as analyzers participate in build both in the IDE and in the command line.

This is of course quite a shame, because the biggest value proposition of using EditorConfig file in the first place, is to share the settings across all contributors, as well as making sure the project style settings are respected during all types of build runs.

How to address this? πŸ”—

When using EditorConfig to configure the code style in your C# project, you can define rules belonging to three categories (actually four, because there is also the “default/basic” EditorConfig indentation stuff):

  • formatting conventions
  • language conventions
  • naming conventions

Unfortunately at the moment, for the latter two we cannot do much. But there is already a solution for build-time enforcement for the formatting conventions.

The formatting conventions all generate the same diagnostic ID - IDE0055 and, it turns out, there is a prototype port of all those EditorConfig formatting-specific rules to the analyzer infrastructure. The Roslyn teams have created a “fix formatting” analyzer that does the same thing as the logic embedded into Microsoft.CodeAnalysis.CSharp.Features, and deals with the IDE0055.

There is no stable version of the package yet, so in order to take advantage of this, you need to pull in the package from the Roslyn CI feed. The necessary feed definition for your NuGet.config is:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="roslyn" value="https://dotnet.myget.org/F/roslyn/api/v3/index.json" />
  </packageSources>
</configuration>

And the NuGet package reference, to add to your project file:

<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeStyle" Version="3.6.0-beta1-20071-02">
   <PrivateAssets>all</PrivateAssets>
   <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

With this setup, the formatting rules are enforced via analyzer infrasturcture and you can benefit from them the same way as you’d do from the regular analyzers.

EditorConfig support in the compiler πŸ”—

The Roslyn team has been working really hard of making EditorConfig a first class citizen in the compiler. That probably warranties its own blog post - which I will try to come back to in the future. However, to keep this brief, the support for EditorConfig in the compiler is the critical aspect of making this functionality work - as the compiler needs to read and understand the EditorConfig, and then configures its analyzer accordingly.

What is even better, is that starting with Visual Studio 16.3, you can also define diagnostic severity in EditorConfig file, and they’d be respected in the compiler. That applies to all diagnostics, including the formatting specific IDE0055. The syntax is as follows:

dotnet_diagnostic.IDE0055.severity = error

This now replaces the old school .ruleset files and can be used as single point of configuration for both Microsoft and 3rd party analyzer diagnostic severity, as well as the place to define EditorConfig conventions.

Such diagnostic severity control via EditorConfig is not supported in VS Code + OmniSharp yet, but we are working on getting it in there very soon.

Hope this post helps and happy Editorconf-ing!

About


Hi! I'm Filip W., a software architect from ZΓΌrich πŸ‡¨πŸ‡­. I like Toronto Maple Leafs πŸ‡¨πŸ‡¦, Rancid and quantum computing. Oh, and I love the Lowlands 🏴󠁧󠁒󠁳󠁣󠁴󠁿.

You can find me on Github, on Mastodon and on Bluesky.

My Introduction to Quantum Computing with Q# and QDK book
Microsoft MVP