In our organization, we encountered the challenge of inconsistent coding styles due to multiple editorconfigs customized across various projects. To address this issue, we devised a solution – distributing the editorconfig through a NuGet package. This approach ensures effortless adherence to unified coding standards throughout our codebase. Additionally, we seamlessly integrate it with the Stylecop analyzer, further enhancing our code quality. New team members find it easy to adopt and follow the established guidelines right from the beginning. With all configurations centralized in one package, we eliminate the hassle of scattered settings.
In this guide I will show you how to distribute an .editorconfig via a NuGet package.
Solution / project
The setup consist of:
.props file
A .props file is an XML-based configuration file used to share build properties and targets, promoting consistency and simplifying management across multiple projects.
.editorconfig
The .editorconfig file is used to define and enforce consistent coding styles and formatting conventions across different text editors and IDEs. It provides a way to specify various settings related to indentation, line endings, character encoding, and other formatting rules within a codebase.
The project looks like this:
Add the .editorconfig
First add the .editorconfig. For an example .editorconfig see the source code (can be downloaded at the bottom).
After the .editorconfig has been added.
Add the .props file
<Project>
<PropertyGroup>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<NoDefaultExcludes>true</NoDefaultExcludes>
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
</PropertyGroup>
<ItemGroup>
<EditorConfigFilesToCopy Include="$(MSBuildThisFileDirectory)..\.editorconfig" />
</ItemGroup>
<Target Name="CopyEditorConfig" BeforeTargets="BeforeBuild">
<Copy
SourceFiles="@(EditorConfigFilesToCopy)"
DestinationFolder="$(MSBuildProjectDirectory)"
SkipUnchangedFiles="true"
UseHardlinksIfPossible="false" />
</Target>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
The example above also includes the StyleCop Analyzer. This is optional. If you use other analyzers or are only interested in distributing the .editorconfig, go ahead and remove StyleCop.
Let’s see what the code above does all does.
- <EditorConfigFilesToCopy Include=”$(MSBuildThisFileDirectory)\.editorconfig” />: This item specifies the .editorconfig file to be copied to the project directory. The $(MSBuildThisFileDirectory) is a variable that represents the directory of the current .props file.
- <Target Name=”CopyEditorConfig” BeforeTargets=”BeforeBuild”>: This section defines a custom build target named “CopyEditorConfig” that runs before the standard “BeforeBuild” target.
- <Copy SourceFiles=”@(EditorConfigFilesToCopy)” DestinationFolder=”$(MSBuildProjectDirectory)” SkipUnchangedFiles=”true” UseHardlinksIfPossible=”false” />: This line copies the specified EditorConfigFilesToCopy item (in this case, the .editorconfig file) to the $(MSBuildProjectDirectory), which represents the project directory.
- <PackageReference Include=”StyleCop.Analyzers” Version=”1.1.118″>. I also included the StyleCop Analyzer (since this is what we use in our projects). By including this package, the package doesn’t have to be manually installed anymore. This only required if you are using StyleCop, if not then this part can be excluded.
Overall, this code configures properties related to code style enforcement, enables .NET analyzers, suppresses certain warnings, copies an .editorconfig file, and references the “StyleCop.Analyzers” package.
Modify the .csproj file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>MyPackeIdHere</PackageId>
<Authors>DocuBear</Authors>
<Version>1.0.5</Version>
<Company>DocuBear</Company>
<Product>DocuBear.EditorConfig</Product>
<IsPackable>true</IsPackable>
<Description>This is an example description!</Description>
</PropertyGroup>
<PropertyGroup>
<NoDefaultExcludes>true</NoDefaultExcludes>
</PropertyGroup>
<ItemGroup>
<None Include="DocuBear.EditorConfig.props" Pack="true" PackagePath="\build" />
</ItemGroup>
<ItemGroup>
<None Update=".editorconfig" Pack="true" PackagePath="\" />
</ItemGroup>
</Project>
Don’t forget to add the NoDefaultExcludes propertyor by default files and folders starting with a dot are excluded in the NuGet package. In case you do not add NoDefaultExcluded true property, the .editorconfig file will be ignored and not packed.
You have to add the package you just created in every single project on which you want to apply the editorconfig. If your solutions has multiple projects, install the NuGet package in every single project. Every time the project is build, the .editorconfig is automatically placed in the folder where the project file is located. The .editorconfig will be overwritten on every build, this means the config cannot be edited / modified locally. This prevents from teammembers overwriting coding styles/rules and ensures consistency across all projects.
For the article about how to create a NuGet package see: