Codeanalyseregeln und -konventionen mit EditorConfig 

Wenn über das Grundsätzliche keine Einigkeit besteht, ist es sinnlos, miteinander Pläne zu machen. 

Konfuzius

Was ist eine EditorConfig?

EditorConfig hilft dabei konstante Quellcode Konventionen über mehrere Entwickler, IDEs und Projekte beizubehalten. 

Das Projekt besteht aus einem Dateiformat zur Definition von Quellcode Konventionen und einer Sammlung von Texteditor-Plugins, die es verschiedenen Editoren und IDEs ermöglicht das Dateiformat zu lesen und die festgelegten Konventionen anzuwenden. 

Plugin-frei ist Visual Studio. 

Plugin-gebunden ist unter anderem Visual Studio Code. 

Mehr Informationen über die EditorConfig findest du hier.

Weshalb nutzen wir eine EditorConfig?

Wir verwenden die EditorConfig, damit wir effizient arbeiten können und unser Fokus auf der Logik der Applikation liegt. Dieses Vorgehen bewahrt uns davor ständig unseren Quellcode auf Einheitlichkeit kontrollieren zu müssen. So sparen wir Zeit und fördern das gemeinsame Verständnis.

Das Item Template wird von uns als weitere Grundlage benutzt. Ziel dieses Projekt ist es, eine eigene EditorConfig Datei zu erstellen und diese in jedem kommenden Projekt zu verwenden. Dabei sparen wir Zeit bei der Analyse des Quellcodes ein und implementieren diesen einheitlich. 

Vorgehen – Wie erstelle ich eine EditorConfig Datei?

Die EditorConfig Datei wird in einem NuGet-Paket verpackt. NuGet ist der empfehlenswerteste Ansatz für dieses Projekt, dank des einfachen Erstellens der Pakete, der Verfügbarkeit sowie der einfachen Installation. Ein anderer Ansatz für das Projekt wäre ein Visual Studio Template zu erstellen, dazu mehr in einem nächsten Blogbeitrag. 

Der ganze Prozess vom Packen der nuspec-Datei bis zum Hochladen auf Nuget.org, wird von einer Azure Build Pipeline übernommen, welche wir implementiert haben. 

Umsetzung

Anlegen des Projekts

Zuerst erstellen wir eine C# Klassenbibliothek und entfernen die Standarddateien. Anschliessend legen wir folgende Projektstruktur an:

Die Abbildung zeigt die Projektstruktur, wenn eine editorconfig angelegt wird.

In der .editorconfig Datei sind die Konventionen definiert. 

Referenzen (Dependencies) werden hier nicht benötigt.

Inhalte template.json

Innerhalb des .template.config Verzeichnis liegt die Datei template.json, welche die Konventionen der .NET CLI Vorlagen beinhaltet. Diese ist für den Fall da, dass wir ein Visual Studio Item Template erstellen. Ausserdem die Datei dotnetcli.host.json, die als Erinnerung an die Parameter für den Visual Studio Dialog ist. 

Hier ein Ausschnitt der template.json:

Konventionen definieren

Die Konventionen generieren wir mit der Extension ReSharper und definieren noch weitere Konventionen, wie zum Beispiel spezielle Tabs für YAML Dateien.

Unten ein kleiner Ausschnitt der .editorconfig Datei. 

Auf der Abbildung zu sehen ist ein Ausschnitt einer editorconfig Datei.

`root = true` gibt an, dass der Editor nicht nach weiteren .editorconfig Dateien suchen soll. 

Danach kommen Standardkonventionen, die von allen IDEs und Editoren unterstützt werden. 

Um alle Verstösse der Konventionen in der Error List von Visual Studio anzuzeigen, sind die letzten Einstellungen da. Sie definieren den Schweregrad mit welcher jede Kategorie von Konvention angezeigt werden soll. 

NuGet-Paket erstellen

Um das Item Template auf NuGet als Paket bereitzustellen, muss eine nuspec-Datei mit folgendem Inhalt erstellt werden: 

<?xml version="1.0" encoding="utf-8"?> 

<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd"> 

  <metadata> 

  <readme>docs/README.md</readme> 

<icon>content\databinding-default-editorconfig\icon.png</icon> 

    <id>databinding.editorconfig</id> 

    <version>$version$</version> 

    <description> 

      Databinding EditorConfig Standard 

      Blogpost: coming soon... 

    </description> 

    <authors>Simon Müller</authors> 

    <license type="expression">MIT</license> 

    <packageTypes> 

      <packageType name="Template" /> 

    </packageTypes> 

  </metadata> 

  <files> 

    <file src="Template_EditorConfig\Template_EditorConfig\templates\"  

    exclude="Template_EditorConfig\Template_EditorConfig\templates\**\bin\**; 

    Template_EditorConfig\Template_EditorConfig\templates\**\obj\**" 

    target="content"/> 

    <file src="..\README.md" target="docs/README.md"/> 

  </files> 

</package> 

Alternativ ist das auch in der .csproj Datei möglich. Wir haben uns für die nuspec-Datei entschieden, da es eine klare Trennung zeigt zwischen Projekt und NuGet Einstellungen. 

Die definierten Dateien in <file> werden in das Content Verzeichnis im NuGet-Paket gepackt. 

Speziell daran ist die Versionsnummer ($version$), welche von der Pipeline mit einem PowerShell-Skript automatisch hochgezählt und ersetzt wird. 

Kontrollierung

Ein guter Weg, um ein NuGet-Paket zu kontrollieren, ist der nuget Package Explorer.

Das NuGet-Paket steht jetzt zum Herunterladen bereit.

Auf der Abbildung ist das NuGet-Paket der editorconfig zu sehen, das bereit steht für den download.

Probleme mit der .editorconfig Datei

Beim Kontrollieren mit dem Package Explorer ist uns schnell aufgefallen, dass die .editorconfig Datei immer gefehlt hat und so die Installation fehlgeschlagen ist.  

Nach unserer Recherche wurde klar, dass alle mit einem Punkt beginnenden Dateien automatisch ausgeschlossen werden. Auch mit explizitem Angeben in der nuspec-Datei. Mit dem Argument `-NoDefaultExcludes`, beim Packen der nuspec-Datei, konnten wir dies umgehen: 

`nuget pack src/databinding.editorconfig.nuspec -NoDefaultExcludes -Properties version=$(Build.BuildNumber) -OutputDirectory $(Build.ArtifactStagingDirectory)` 

Version zur Datei hinzufügen

Um zu Erkennen mit welcher .editorconfig Datei gearbeitet wird, haben wir mit einem PowerShell-Skript die Version am Anfang hinzugefügt:

...

scriptType: 'inlineScript' 

inlineScript: | 

$editorconfig = 'src/Template_EditorConfig/Template_EditorConfig/templates/databinding-default-editorconfig/Default/.editorconfig' 

              $content = Get-Content -Path $editorconfig -Raw 

              New-Item -ItemType "file" -Path $editorconfig -Force 

              Set-Content -Path $editorconfig -Value "###`n# Version: $(Build.BuildNumber)`n###`n" 

              Add-Content -Path $editorconfig -Value $content 

PowerShell kann nur Inhalt am Ende einer Datei anfügen. In vier Schritten haben wir eine Lösung gefunden:

  1. Die Datei wird ausgelesen und der Inhalt gespeichert.
  2. Die Datei wird mit einer leeren Datei (gleicher Dateiname) ersetzt.
  3. Die neue Datei bekommt die Version.
  4. Der Inhalt der alten Datei wird angehängt.

README Bilder Sourcen

Die Bilder in der README.md Datei wurden auf NuGet.org nicht angezeigt.

Markdown Bilderlink auf GitHub

Wie sich herausgestellt hat, braucht NuGet.org eine vertrauenswürdige Source der Bilder, um sie anzuzeigen. Dazu haben wir ein öffentliches GitHub Repository angelegt, welches alle Bilder beinhaltet. Die Source der Bilder muss direkt (raw.githubusercontent…) auf das Bild gelegt werden. 

Nur ein Bild aus einer nicht vertrauenswürdigen Source führt dazu, dass die anderen auch nicht geladen werden. 

Verwendung im Projekt

Installation über nuget

Über nuget.org oder direkt über die Kommandozentrale lässt sich das Paket installieren:

dotnet tool install --global databinding.editorconfig --version <Versions Nummer>  

Um die Installation zu verifizieren, kann folgender Befehl ausgeführt werden:

dotnet new --list 

Das Template wird jetzt in der Liste angezeigt:

Zur Deinstallation:

dotnet new -u databinding.editorconfig 

Hinzufügen über Terminal

Um das Template einer Solution oder einem Projekt hinzuzufügen, muss das Projekt/Solution-Verzeichnis in der Kommandozentrale geöffnet werden. Beispiel:

Projektverzeichnis editorconfig in Terminal

Folgender Befehl erstellt die .editorconfig Datei in dem Projekt/Solution Verzeichnis:

dotnet new db-editorconfig 

Danach mit dem Dialog «Add Existing Item» die Datei hinzufügen, sonst werden die Konventionen nicht übernommen.

Analyse laufen lassen 

Mit einem Rechtsklick auf das Projekt/Solution oder Alt+F11 (Visual Studio), kann eine Analyse des bestehenden Quellcodes gemacht werden. 

Verstösse gegen die Konventionen werden danach mit dem eingestellten Schweregrad in der Error List angezeigt. 

Build Error auslösen 

Konventionsverstösse können auf Wunsch einen Build Error auslösen. Hierfür muss die rot umrandete Zeile in der Projekt-Datei unter <PropertyGroup> hinzugefügt werden:

Die Abbildung zeigt die Projekt-Datei. Die rot umrandete Zeile steht für: EnforceCodeStyleInBuild true / EnforceCodeStyleInBuild

Widersprüche

Widersprüche zwischen den Code-Analysen treten öfters auf, je mehr Extension, Analyser usw. installiert sind.

Beispiel für einen Widerspruch war die Konvention für Csharp:

csharp_style_var_for_built_in_types = true 

Und die Konvention von ReSharper:

resharper_for_built_in_types = use_var_when_evident 

Die Lösung war die ReSharper Convention auf `use_var` zu stellen, damit der Wiederspruch gelöst wird.

Visual Studio Item Template

Die Überlegung

Geplant war, dass die .editorconfig Datei als Item Template über den Visual Studio Dialog „Add New Item“ hinzugefügt werden kann:

die Editorconfig Datei als item template im Visual Studio Dialog.

Ein Projekt Template, welches wir erstellt haben, wurde automatisch nach der Installation angezeigt. Wir nahmen an, dass dies bei dem Item Template genau gleich funktionieren würde. 

Zum Blogbeitrag

Probleme

Das Item Template wurde nicht angezeigt nach der Installation über die Konsole. 

Weitere Recherchen haben ergeben, dass das Item Template im Verzeichnis `%USERPROFILE%\Documents\Visual Studio 2022\Templates\ItemTemplates` gespeichert werden muss. Ausserdem in einem ZIP Ordner mit einer .vstemplate Datei:

Auf der Abbildung ist der Inhalt des ZIP-Ordners zu sehen mit der .editorconfig, der _PreviewImage.png, _TemplateIcon.png und dem MyTemplate.vstemplate

Inhalt der .vstemplate Datei:

<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item"> 

  <TemplateData> 

    <DefaultName>db-editorconfig.png</DefaultName> 

    <Name>db-editorconfig</Name> 

    <Description>&lt;No description available&gt;</Description> 

    <ProjectType>CSharp</ProjectType> 

    <SortOrder>10</SortOrder> 

    <Icon>__TemplateIcon.png</Icon> 

    <PreviewImage>__PreviewImage.png</PreviewImage> 

  </TemplateData> 

  <TemplateContent> 

    <References /> 

    <ProjectItem SubType="" TargetFileName=".editorconfig" ReplaceParameters="false">.editorconfig</ProjectItem> 

  </TemplateContent> 

</VSTemplate> 

Weshalb wurde es nicht umgesetzt?

Es ist eine einfache Art das Template zu einem Projekt oder zu einer Solution hinzuzufügen. Jedoch ist es den Aufwand aus folgenden Gründen nicht wert:

  • Zusätzliche Dateien müssen erstellt und ins NuGet-Paket gepackt werden. 
  • Der Benutzer muss aus dem NuGet-Paket die Dateien zusammensuchen und sie als ZIP Ordner im oben genannten Verzeichnis speichern. 
  • Es ist nur für Visual Studio. 
  • Das Item Template lässt sich nicht für alle Projekttypen auslegen. Das hat zur Folge, dass bei vielen Projekten das Template nicht angezeigt wird.  

Fazit

Die EditorConfig lässt sich einfach zu einem Projekt oder einer Solution hinzufügen. Es hilft Entwickler, die gemeinsam an einem Projekt arbeiten, die Quellcode Konventionen einzuhalten. 

Die grosse Mehrheit der Konventionen wird allerdings nur von Visual Studio in Zusammenhang mit der ReSharper Extension unterstützt. Es können andere Editoren und IDEs verwendet werden, welche aber nicht so viele Verstösse gegen die Konventionen anzeigen. 

Wiederum kann der persönlich bevorzugte Editor zum Implementieren verwendet werden und zum Schluss die Analyse in Visual Studio durchgeführt werden. 

Für die databinding GmbH stellen diese Konventionen einen grossen Mehrwert da, weil Visual Studio und ReSharper oft zum Einsatz kommen. 

Mein persönliches Fazit zu EditorConfig

Für mich war dies ein gutes Startprojekt, um die Methoden und Tools, die bei der databinding GmbH eingesetzt werden, kennenzulernen. Bei der Umsetzung dieses Projekts sind mir oft Fehler unterlaufen, z.B. das Problem mit dem NoDefaultExclude beim Packen der nuspec-Datei. Durch Verwendung der Pipeline werden mir diese Fehler nicht mehr passieren, weil diese automatisiert sind.  

Das EditorConfig Projekt findet sich auf GitHub

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren.