question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Editorconfig vs Global analyzerconfig

See original GitHub issue

Editorconfig

  • Starting VS2019 16.3, Roslyn compiler and IDE supports analyzer and source generator configuration via regular .editorconfig files for configuration that applies to specific source files and/or folders within a project, applicable files and/or folders are selected by section headers.

  • Designed to work well will existing .editorconfig files used to configure editor style settings for different IDEs.

  • File/directory based discovery and configuration:

    • Implicitly discovered by the project system by walking the file system and passed to the compiler
    • All supported analyzer configuration entries must be under section headers to select applicable files and/or folders. Configuration entries not under a section header are ignored by the compiler.
  • Core scenarios: Support end user analyzer and source generator configuration via below entries:

    • Options: Key-value pair entries of the form key = value for analyzer config options passed to analyzers and source generators
    • Diagnostic severity settings: Certain well-known key value pairs as per the syntax here and here to configure diagnostic severity of analyzer diagnostics and compiler warnings.
  • Conflict resolution:

    • Regular editorconfig conflict resolution mechanism is applied so that editorconfig files deeper in the directory structure override the settings from editorconfig files that are higher up.
    • Highest precedence for diagnostic severity configuration entries: Overrides diagnostic severity settings that come from command line options (/nowarn, /warnaserror) and entries coming from ruleset or global analyzerconfig files.
  • Example:

# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true

# C# files
[*.cs]

#### Core EditorConfig Options ####

# Indentation and spacing
indent_size = 4
indent_style = space
tab_width = 4

#### .NET Coding Conventions ####

# this. and Me. preferences
dotnet_style_qualification_for_method = true:warning

#### Diagnostic configuration ####

# CA1000: Do not declare static members on generic types
dotnet_diagnostic.CA1000.severity = warning

Global analyzerconfig

  • Starting VS2019 16.7, Roslyn compiler and IDE supports special global, compilation level analyzer/source generator configuration files for specifying configuration that applies to all the source files in the compilation/project, regardless of the actual file names or file paths of these source files.

  • Unlike editorconfig files, these are not designed to configure editor style settings for different IDEs.

    • File name: No restrictions or requirements
    • File format:
      • Simple key-value pair configuration entries of the form key = value
      • Must contain a top level entry of the form is_global = true
      • Can contain section headers, as long as the headers specify an absolute file path. Section headers based on globbing or relative file paths are ignored.
  • File/directory agnostic configuration:

    • No implicit discovery: Need to be explicitly specified in the MSBuild targets/project file to be passed to the compiler:
      <ItemGroup>
        <EditorConfgFiles Include="<%path_to_global_analyzer_config%>" />
      </ItemGroup>
      
    • No globbing or relative file path based section headers allowed: All supported analyzer configuration entries must either be top level without section header OR section header must have an absolute file path. Entries under any section headers that are based on globs, say [*.cs] or [*], or section headers that use relative file paths are ignored.
  • Core scenarios: Support identical analyzer configuration entries as editorconfig files, but for different core scenarios:

    • Allow NuGet packages and SDKs to ship compilation level analyzer configuration files that apply to all source files in the project, regardless of the actual file names or file paths of these source files.
    • Allow passing in project-level MSBuild property values and item metadata to analyzers and source generators: Details here
    • Allow configuration of no-location analyzer diagnostics that do not have a file path and hence cannot be configured via regular editorconfig files.
  • Conflict resolution:

    • Entries with same key coming from different global analyzerconfig files are ignored and compiler generates warnings about each of these conflicts.
    • Lowest precedence for option configuration entries: For entries with same key coming from a global analyzerconfig and editorconfig file, the editorconfig file entry always overrides the global analyzerconfig entry
    • Lowest precedence for diagnostic severity configuration entries: Diagnostic severity settings that come from editorconfig files and those that come from command line options (/nowarn, /warnaserror) always override the entries from global analyzerconfig files.
  • Example:

# Top level entry required to mark this as a global analyzer config file
is_global = true

# NOTE: No section headers for configuration entries

#### .NET Coding Conventions ####

# this. and Me. preferences
dotnet_style_qualification_for_method = true:warning

#### Diagnostic configuration ####

# CA1000: Do not declare static members on generic types
dotnet_diagnostic.CA1000.severity = warning

Confusion points

The core points of confusion are:

  • Both file kinds have a similar end user goal of configuring analyzers and/or source generators, even though they have completely orthogonal purposes - path based vs path agnostic configuration for source files in the compilation.
  • Both files have similar format for the core configuration entries: key-value pair based entries, including support for the well-known diagnostic severity configuration entries
  • Use of same compiler switch for both files + Use of the editorconfig terminology in the MSBuild item name to specify global analyzerconfig files, i.e. <EditorConfgFiles Include="path_to_global_analyzer_config"/>. This was done to reduce the engineering cost on project system side, especially legacy project system. However, this makes the user feel the file name and format must match regular .editorconfig files, including use of globbing based section headers. For example, classic user mistake highlighted in the issue here.
  • Global analyzer config files can be named .editorconfig and things work just fine as long as entries abide by the global analyzerconfig’s required format.
  • Global analyzer config files silently ignore analyzer configuration entries under section headers
  • Lack of tooling support in VS to create/edit global config files, so user has to manually do all the steps, making it hard to reason about the subtle differences between the two file formats.

Action items for future work

There are few action items that we plan to take up to reduce the above confusion:

  • [@mavasani] Documentation: Add official documentation on docs.microsoft.com on global analyzerconfig files and add a FAQ section for the differences between regular editorconfig files and global analyzerconfig files. Added with https://github.com/dotnet/docs/pull/20824. See https://docs.microsoft.com/dotnet/fundamentals/code-analysis/configuration-files
  • [@chsienki] Better compiler warnings in global analyzerconfig files:
    • Generate a compiler warning for use of editorconfig style globbing based or relative file path based section headers, instead of silently ignoring these.
    • Consider generating a compiler warning for global analyzerconfig files that are name “.editorconfig”, recommending user to choose a different file name for clarity. This likely indicates user is confusing both these file kinds to be the same format, and might be heading towards shooting themselves in the foot. Added with https://github.com/dotnet/roslyn/pull/47728.
  • [@chsienki] Potential MSBuild item name change: Consider using a different MSBuild item name for specifying global analyzer config files. Instead of recommending users to include <EditorConfgFiles Include="<%path_to_global_analyzer_config%>" />, we should consider introducing a new item name, say <GlobalAnalyzerConfgFiles Include="<%path_to_global_analyzer_config%>" />. Under the covers, compiler MSBuild targets will just append both editorconfig files and global analyzerconfig files to a single list of config files passed to the compiler. However, this will likely reduce the chances of user getting confused into thinking these are regular editorconfig files. Added with https://github.com/dotnet/roslyn/pull/47803
  • [@chsienki] Bug fix: We should update the GeneratedCodeUtilities heuristic to consider source files without a file path as generated files, currently they are considered as non-generated files: http://sourceroslyn.io/#Microsoft.CodeAnalysis/InternalUtilities/GeneratedCodeUtilities.cs,63 Tracked with https://github.com/dotnet/roslyn/issues/48480

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:3
  • Comments:12 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
mavasanicommented, Sep 15, 2020
1reaction
mavasanicommented, Nov 30, 2020

Is the new <GlobalAnalyzerConfigFiles /> only working, if I use .NET 5 SDK or is it bound to VS 16.8+?

This is a compiler feature, not tied to any specific .NET SDK. It should work on any target framework as long as you have the required VS/compiler that supports this feature (VS2019 16.8 should have the required compiler).

For example: Can I use it, if I build netstandard2.0 library when using sdk version 3.1.404 in global.json

Depends on which compiler version you are using, it needs compiler version 3.7 or later.

Can I use Microsoft.CodeAnalysis.NetAnalyzers in this case?

Yes, this analyzer package is not tied to a specific target platform or .NET SDK.

Is there a plan that I can share .editorconfig (indent-size, indent-style, …) also via a NuGet package?

No, by definition .editorconfig files are dependent on the folder location so shipping them inside a NuGet package does not make sense. This was one of the primary use cases for introducing folder agnostic global config files.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Configuration files for code analysis rules - .NET
Both EditorConfig files and global AnalyzerConfig files specify a key-value pair for each option. Conflicts arise when there are multiple ...
Read more >
EditorConfig versus analyzers - Visual Studio (Windows)
Both EditorConfig files and rule sets let you enable and disable rules and set their severity. However, EditorConfig files offer additional ways to...
Read more >
C# code style by EditorConfig in .NET 5 SDK and beyond
The Global AnalyzerConfig file is an agnostic file-system for overcoming the limitation of EditorConfig files, where their location matters. The ...
Read more >
How to Use Common EditorConfig as a NuGet Package
EditorConfig file: File-based or folder-based configuration options. · Global AnalyzerConfig file: Project-level configuration options. Useful ...
Read more >
In VS2022 can you setup a solution wide editorconfig, and ...
globalconfig files are for applying analyzer rules based on project (or as part of a NuGet package). For example, if you have files...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found