Connect with us

Entwicklung & Code

Linting-Stack für Node-Projekte: Code-Qualität, Formatierung und Prosa-Linting


Nicht nur Code bestimmt die Softwarequalität, sondern auch die Art, wie Softwareentwicklerinnen und -entwickler ihn dokumentieren und präsentieren. In einer Zeit, in der viele Entwicklerteams vollständig remote arbeiten und die Codebase weiter kontinuierlich wächst, ist die konsistente und automatisierte Qualitätskontrolle eine Notwendigkeit.

Weiterlesen nach der Anzeige


David König

David König

David König ist seit über 20 Jahren in der IT aktiv. Viele Jahre hat ihn das Thema Workplace-Management und Infrastruktur als Berater beschäftigt, bevor er in die Entwicklung gegangen ist, um sich intensiv mit den Themen Produkt-Management und DevOps auseinanderzusetzen. Nachdem er den Schaffensprozess von Software von allen Seiten kennengelernt hat und neben der IT-Community auch in der Heim- und Handcommunity aktiv ist, versteht er die Entwicklung und den Betrieb von Software weniger als Wissenschaft, sondern als Handwerk. Dieser Gedanke treibt ihn und er versucht immer wieder, Parallelen zwischen Handwerk und Softwareentwicklung aufzuzeigen.

Heute betreibt David Softwareentwicklung in der Automotive-Branche bei der adesso SE und zusammen mit vielen weiteren Kollegen IoT-Projekte und die pragmatische Vision der Softwareentwicklung als Handwerk vor allem im AI-Bereich.

Während meiner Arbeit an einem node-basierten Dokumentationsstack mit dem Static-Site-Generator Astro und Starlight, einem darauf aufbauenden Framework speziell für Dokumentationswebsites, bin ich auf die Herausforderung gestoßen, nicht nur sauberen Code, sondern auch hochwertige Prosa zu produzieren. Prosa kommt aus dem Lateinischen und bedeutet „geradeheraus reden“ – also ohne Schnörkel normal sprechen.

Im Rahmen einer Dokumentation bezeichnet Prosa den gesamten ausformulierten Textinhalt der technischen Dokumentation – alle Erklärungen, Anleitungen, Beschreibungen und Kommentare. Ziel ist es, dass Stil-Konsistenz, Grammatik, Wortwahl, Lesbarkeit und die Einhaltung von Dokumentationsrichtlinien sichergestellt sind und die technische Dokumentation nicht nur funktional korrekt, sondern auch verständlich, einheitlich und professionell geschrieben ist.

Die Lösung: Ein mehrstufiges Linting-System, das Code-Qualität, Formatierung und Prosa-Linting für englischsprachige Dokumentation geschickt miteinander verbindet und sich durch Git Pre-Commit Hooks sowie CI/CD-Pipelines automatisieren lässt. Prosa Linting für deutsche Texte ist nicht nativ integriert, lässt sich aber durch eigene Regeln integrieren. Hierbei kann die KI bei der Erstellung der Regeln gute Dienste tun. Eine gute Hilfestellung bietet hier auch der webbasierte Regelgenerator valegen.

  • Automatisierung ist der Schlüssel: Pre-Commit Hooks und CI/CD-Pipelines stellen sicher, dass Qualitätsstandards eingehalten werden
  • Dreistufiger Ansatz: Code-Qualität, Formatierung und Prosa-Linting ergänzen sich perfekt
  • Tool-Integration: Astro, Starlight, Vale und moderne Entwicklertools harmonieren ausgezeichnet
  • Skalierbarkeit: Das System wächst mit dem Projekt und dem Team mit
  • Zukunftssicherheit: KI-Integration wird nahtlos möglich

Weiterlesen nach der Anzeige

Bevor es an die detaillierte Umsetzung des dreistufigen Linting-Konzepts geht, ist eine praktische Arbeitsumgebung einzurichten. Als grundlegendes Code- und Dokumentations-Beispiel dient Astrogon – ein vielseitiges Astro-Theme, das sich ideal für die Demonstration des Linting-Systems eignet. Astrogon ist ein schnell anpassbares, Mehrzweck-Website-Template, das auf Astro JS, Tailwind CSS und React basiert. So bildet es eine solide Grundlage für verschiedene Website-Typen – von Blogs über Dokumentationsseiten bis hin zu Portfolio-Websites.

Astrogon eignet sich deshalb als Demo-Basis, weil es:

  1. Verschiedene Dateitypen enthält: .astro, .tsx, .js, .md, .mdx, .css
  2. Realistische Komplexität bietet: ein echtes Projekt mit authentischen Herausforderungen
  3. Einen modernen Stack verwendet: aktuelle Technologien, die typisch für moderne Webprojekte sind
  4. Gut strukturiert ist: klare Ordnerstruktur für effektives Linting
  5. Content-fokussiert arbeitet: viel Text-Content für Prosa-Linting

Durch einen Fork des originalen Astrogon Repository, den man lokal klont, lässt sich das Projekt einfach aufsetzen.


# Create a fork (via GitHub.com)

#  Clone repository
git clone 
cd my-linting-project

# Install dependencies
npm install

# Fix existing vulnerabilities
npm audit fix

# Start development server
npm run dev


Nach der Installation steht eine vollständig funktionsfähige Website mit folgender Struktur parat:


my-linting-project/
├── docs/ # Documentation
├── public/ # Static public viewable resources
├── src/
│ ├── assets/ # Pictures, icons,...
│ ├── components/ # reusable components
│ ├── content/ # Markdown/MDX content collections
│ ├── lib/ # Utility functions
│ ├── pages/ # Astro-pages (Routing)
│ ├── styles/ # CSS/SCSS files
│ ├── types/ # TypeScript type-definitions
│ ├── content.config.ts # Content Collections configuration
│ └── env.d.ts # Environment variables types
├── .editorconfig # Editor-configuration
├── .prettierrc # Preconfigured prettier
├── .markdownlint.json # Preconfigured markdownlot
├── astro.config.mjs # Astro configuration
├── package.json # Dependencies and scripts
├── tailwind.config.js # Tailwind CSS configuration
├── tsconfig.json # TypeScript Configuration
└── wrangler.jsonc # Cloudflare workers configuration


Modernes Linting geht weit über die reine Syntaxprüfung hinaus und umfasst drei komplementäre Dimensionen der Qualitätskontrolle: Code-Qualität für die Logik, Formatierung für die Konsistenz und Prosa-Linting für die menschliche Lesbarkeit. Für diese drei Aspekte kommen verschiedene Linter zum Einsatz: ESLint für die Code-Qualität, Prettier für die Formatierung und Vale für das Prosa-Linting.

Code-Qualität mit ESLint: ESLint bildet das Fundament des Linting-Stacks. Es analysiert TypeScript-, JavaScript- und Astro-Dateien auf potenzielle Fehler, Style-Inkonsistenzen und Best-Practice-Verletzungen. Die Installation leitet der folgende Befehl ein:

npm install -D eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser astro-eslint-parser eslint-plugin-astro

Im nächsten Schritt folgt das Anlegen der Datei .eslintrc.js, die die Konfiguration für die verschiedenen Dateitypen definiert. Dies gelingt am einfachsten über den offiziellen Konfigurations-Wizard von ESLint:

npm init @eslint/config@latest


module.exports = {
  extends: [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
  ],
  parser: "@typescript-eslint/parser",
  plugins: ["@typescript-eslint"],
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module",
  },
  env: {
    node: true,
    browser: true,
    es2022: true,
  },
  rules: {
    "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
    "@typescript-eslint/no-explicit-any": "warn",
    "@typescript-eslint/no-empty-interface": "off",
  },
  overrides: [
    {
      files: ["*.astro"],
      extends: ["plugin:astro/recommended"],
      parser: "astro-eslint-parser",
      parserOptions: {
        parser: "@typescript-eslint/parser",
        extraFileExtensions: [".astro"],
      },
    },
  ],
};


Anschließend sind die aufrufenden npm-Skripte in der Datei package.json zu hinterlegen.


{
  "scripts": {
    "lint": "eslint ./src --ext .js,.ts,.jsx,.tsx,.astro --fix",
    "lint:check": "eslint ./src --ext .js,.ts,.jsx,.tsx,.astro"
  }
}


Der Befehl npm run lint korrigiert dann automatisch behebbare Probleme, während npm run lint:check nur überprüft, ohne Änderungen vorzunehmen, und die Ergebnisse im Terminal ausgibt.

Code-Formatierung mit Prettier: Prettier sorgt für einheitliche Code-Formatierung und nimmt Entwicklern die Diskussion über Code-Style ab. Besonders in Astro-Projekten mit gemischten Dateitypen ist eine konsistente Formatierung essenziell. Prettier lässt sich mit folgendem Befehl installieren:

npm install -D prettier prettier-plugin-astro prettier-plugin-tailwindcss

Die Konfiguration von .prettierrc\ im Root-Verzeichnis des Repository berücksichtigt die spezifischen Anforderungen von Astro-Projekten:


{
  "plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"],
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 80,
  "useTabs": false,
  "bracketSpacing": true,
  "bracketSameLine": false,
  "arrowParens": "always",
  "endOfLine": "lf",
  "overrides": [
    {
      "files": ["*.astro"],
      "options": {
        "parser": "astro"
      }
    },
    {
      "files": ["*.md", "*.mdx"],
      "options": {
        "printWidth": 100,
        "proseWrap": "always"
      }
    }
  ]
}


Sind die Abhängigkeiten installiert und die Konfiguration angelegt, werden die entsprechenden npm-Skripte in der Datei package.json eingefügt:


{
  "scripts": {
      ...
      ...
    "format": "prettier --write ./src --log-level silent",
    "format:check": "prettier --check ./src --log-level silent"
  }
}


Der Befehl npm run format korrigiert anschließend automatisch behebbare Probleme, während npm run format:check nur überprüft, ohne Änderungen vorzunehmen, und die Ergebnisse im Terminal ausgibt.

Prosa-Linting mit Vale: Vale ist ein Open-Source-Tool für das Prosa-Linting, das wie ein Code-Linter funktioniert, aber Fließtext verarbeitet. Es prüft Texte auf stilistische Fehler, wiederkehrende Muster und Verstöße gegen vordefinierte oder eigene Stilrichtlinien. Es funktioniert mit Markdown, HTML, AsciiDoc oder reStructuredText und analysiert diese Formate anhand konfigurierter Regeln. Die Style-Guides, anhand derer Vale überprüft, können frei gewählt, angepasst oder erweitert werden – beispielsweise nach Vorbildern von Google, Microsoft oder eigenen Anforderungen.

Typische Regeln erkennen etwa unnötige Passiv-Konstruktionen, zu viele Wiederholungen, fehlende Oxford-Kommas – also das Komma vor der Konjunktion in einer Aufzählung, das helfen soll, Missverständnisse zu vermeiden – oder „Weak Words“ wie „viele“ oder „manchmal“. Die Ergebnisse zeigt Vale direkt im Editor, in der Kommandozeile oder als Teil automatisierter CI-Prozesse.

Vale erfordert eine plattformspezifische Installation sowie den Download der Style-Guides und LibreOffice-kompatibler Hunspell-Wörterbücher (.dic/.aff-Dateien) für die Rechtschreibprüfung in anderen Sprachen als Englisch. Ja, die Kombination von Prosa-Linting-Style-Guides (wie Vale, Google oder Microsoft Style Guides) mit einem deutschen Wörterbuch ist durchaus sinnvoll und funktioniert einwandfrei – Vale nutzt Hunspell-Dictionaries unabhängig voneinander für Rechtschreibung und Stilregeln. Rechtschreibprüfung prüft Wörter auf Korrektheit, während Prosa-Linting Stil, Lesbarkeit und Konventionen überwacht; beide ergänzen sich nahtlos in einem Workflow. Für das beispielhafte Repository habe ich entsprechende Linux/macOS– und Windows-Skripte angelegt, die das Setup erledigen. Getestet ist aktuell nur das Bash-Skript, das PowerShell-Skript wurde via KI automatisiert auf Basis des Bash-Skripts erstellt.

Abweichend von der standardmäßigen Vorgehensweise, bei der Probleme mit dem in Vale integrierten Installer vale sync auftraten, laden die Skripte die git-Repositories für die Styleguides manuell herunter und löschen alle git-spezifischen Inhalte.


# Linux/macOS
chmod +x .vale/install-vale.sh
./.vale/install-vale.sh

# Windows
powershell -ExecutionPolicy Bypass -File .vale/install-vale.ps1


Nach Ausführen der Skripte entsteht folgendes Verzeichnis im Root-Verzeichnis des Repositories:


my-linting-project/
├── .vale/
  ├── dictionaries
  │    ├── de_DE.aff
  │    ├── de_DE.dic
  ├── styles
       ├── Base
       │    ├── accept.txt
	   │    ├── reject.txt
       │    ├── Microsoft/
       │    ├── write-good/ 
  ├── install-vale.ps1
  ├── install-vale.sh
  └── vale


Zu beachten ist dabei noch, alle dynamisch generierten Inhalte in die .gitignore-Datei aufzunehmen.


# Vale binary (install with npm run install-vale)
.vale/dictionaries
.vale/styles/Microsoft
.vale/styles/write-good
.vale/vale
.vale/vale.exe


Das Installationsskript lädt nicht nur Vale herunter, sondern auch die benötigten Styleguides. Auf der Vale-Website sind, neben einigen weiteren spezifischen, vier wesentliche Style-Guides referenziert:

Google

  • Starker Fokus auf technische Konsistenz und Präzision für Entwickler.
  • Große Ausnahmeliste für Akronyme und Begriffe aus APIs.
  • Substitutionslisten mit Google-typischer Terminologie.
  • Stil: direkt, technisch, an Entwickler gerichtet, prägnant, präzise.
  • Quelle Git, Quelle Style-Guide

Microsoft

  • Sehr starke Gewichtung auf Inklusivität und Barrierefreiheit.
  • Klare Satzlängen- und Limits für Wörter.
  • Hunderte produkt- und communityspezifische Begriffe.
  • Stil: freundlich, inklusiv, leserorientiert, markengerecht, barrierefrei.
  • Quelle Git, Quelle Style-Guide

Red Hat

  • Strikte Regeln zu „Open Source“-neutraler Sprache und Kollaboration.
  • Erlaubt keinen Produkt-Bias, eigene Accessibility- und Bias-Listen.
  • Regeln für CLI-Beispiele, Dateipfade und produktneutrale Formulierungen.
  • Bevorzugt kollaborativen Duktus und Community-Perspektive.
  • Stil: offen, kollaborativ, communitygetrieben, produktneutral, inklusiv.
  • Quelle Git, Quelle Style-Guide

Write-good

  • Fokussiert sich rein auf sprachliche Klarheit und verbessert Lesbarkeit und Stil, ohne produkt- oder technikspezifische Prüfkriterien.
  • In modernen Dokumentations-Workflows eignen sich Write-Good-Regeln ergänzend, um die sprachliche Qualität unabhängig von der Plattform zu verbessern.
  • Write-Good Vale Style-Guide

Im Folgenden kommt der „Microsoft Style Guide“ zum Einsatz – erweitert um die Style-Guides „write-good“, „MDX“ und „Vale Core“. Diese sind wie folgt charakterisiert:

Microsoft Style Guide: Unternehmensstandards für technische Dokumentation

write-good: allgemeine Regeln für klares Schreiben

Vale Core: grundlegende Prosa-Regeln

MDX: Prüfung der Sprache innerhalb von JSX Tags

Beim Einsatz unterschiedlicher Style-Guides in Kombination lässt sich in manchen Situationen schwer identifizieren, warum welche Regel benötigt wird. Ein Beispiel macht dies klarer. Gegeben ist folgende MDX-Datei:


---
title: "Using Feature Y"
author: "Adesso"
---

# Feature Y Benefits

You will be able to use this feature very effectively. It was developed by adeso and their team.


  DO NOT use this feature if your environment isn't set correctly.


Step 1: Initializing the data source
Step 2 Call the performOperation() function
Step 3: Confirm the output's accuracy

> Note: The process can be slow. It is important that you wait patiently.

For details, check our doc [documentation](htp://example.com/feature-y).


Die Ergebnisse des Lintings fasst die folgende Tabelle zusammen:

Fehler Welcher Regelsatz Erklärungen & Korrektur
Autor „Adesso“ und „adeso“ inkonsistent geschrieben Custom Regel Korrigiert in „adesso“
Großschreibung in JSX-Komponente ``
MDX-Regelsatz Meldet falsche Großschreibung oder unbekannte JSX-Tags, erwartet `` o.Ä.
Markdown-Liste ohne korrekte Aufzählungszeichen MDX-Regelsatz Fehlt das `-` oder die Nummerierung bei Liste (z.B. `Step 2` ist kein Listenelement)
Unsichere URL im Link (htp statt http) Microsoft Regelsatz Erkennt ungültige URLs, fordert Korrektur auf gültiges Schema (`
Übermäßiger Gebrauch von Floskeln (z.B. „very effectively“, „It is important that“) Write-Good Empfiehlt prägnantere Ausdrucksweise („effectively“, „Wait patiently.“)
Use of first-person pronouns („You will be able…“, „you wait patiently“) in nicht passender Art Microsoft Regelsatz Warnt bei unpassender Verwendung von Personalpronomen, schlägt Sparse-Usage vor
Passiver Sprachgebrauch („was developed“) Write-Good & Microsoft Empfiehlt aktive Formulierung, z.B. „adesso developed this feature.“

Die korrigierte MDX-Datei sieht nach der Regelprüfung dann wie folgt aus:


---
title: "Using Feature Y"
author: "adesso"
---

# Feature Y Benefits

You can use this feature effectively, adesso and their team developed it.


  Do not use this feature if your environment is not set correctly.


- Step 1: Initialize the data source
- Step 2: Call the performOperation() function
- Step 3: Confirm the output's accuracy

> Note: The process can be slow. Please wait patiently.

For details, check our [documentation](


Mithin ergeben sich folgende Einschränkungen:

  • Die Vale-Style-Guides sind nur für englischen Text optimiert, eine Anpassung an Deutsch oder andere Sprachen scheint bisher nicht vorgesehen zu sein.
  • Die Style-Guides basieren auf klassischen Regular Expressions. Wer KI-basierte Ansätze erwartet, wird enttäuscht.
  • Speziell in größeren Projekten empfiehlt es sich einen eigenen Style-Guide aufzubauen. Die Konfiguration von Vale erfordert eine kontinuierliche Anpassung an die Bedürfnisse des Projekts.

Die Vale-Konfigurationsdatei gibt an, in welchen Verzeichnissen und mit welchen Style-Vorgaben das Tool den Text überprüfen soll. Für das Beispiel sei angenommen, dass sich der englische Content in den Unterverzeichnissen des Ordners /src/content befindet.


# Vale configuration file
# See: 
Packages = MDX

StylesPath = .vale/styles
# Add dictionary path for German dictionaries
DictionaryPath = .vale/dictionaries

MinAlertLevel = error

# File type associations - English content (excluding German docs)
[src/content/**]{.md,.mdx}

# Enable/disable specific styles for English content
BasedOnStyles = Vale, write-good, Microsoft

# Enable rules
Vale.Terms = YES  # Disables term-based checks. Example: Avoid using "jargon".
Vale.Spelling = YES  # Disables spelling checks. Example: "recieve" instead of "receive".
Vale.Vocab = YES  # Disables vocabulary checks. Example: Using "utilize" instead of "use".
Vale.Repetition = YES  # Disables repetition checks. Example: "very very good".
Vale.Wordiness = YES  # Disables wordiness checks. Example: "in order to" instead of "to".

# Write-good rules (English-specific)
write-good.Weasel = YES  # Disables detection of weasel words. Example: "some people say".
write-good.TooWordy = YES  # Disables detection of overly wordy phrases. Example: "due to the fact that".
write-good.So = YES  # Disables detection of sentences starting with "so". Example: "So, we decided to...".
write-good.ThereIs = YES  # Disables detection of "there is/are" constructions. Example: "There is a need for...".
write-good.Passive = YES  # Disables detection of passive voice. Example: "The ball was thrown by John".
write-good.Adverbs = YES  # Disables detection of adverbs. Example: "He ran quickly".
write-good.Cliches = YES  # Disables detection of cliches. Example: "Think outside the box".
write-good.E-Prime = YES  # Disables detection of E-Prime violations. Example: "He is a teacher".
write-good.Illusions = YES  # Disables detection of ambiguous phrases. Example: "The results were significant".

# Microsoft style rules (English-specific)
Microsoft.Gender = YES  # Ensures gender-neutral language is used. Example: Use "they" instead of "he/she".
Microsoft.PassiveVoice = YES  # Flags sentences written in passive voice. Example: "The report was written by Sarah".
Microsoft.Cliches = YES  # Detects overused phrases and cliches. Example: "At the end of the day".
Microsoft.Jargon = YES  # Highlights technical jargon that may confuse readers. Example: "Leverage synergies".
Microsoft.Complexity = YES  # Identifies sentences that are overly complex or difficult to read. Example: "The implementation of the solution was carried out in a manner that ensured...".
Microsoft.Redundancy = YES  # Flags redundant phrases or words. Example: "Free gift".
Microsoft.Spelling = YES  # Checks for spelling errors based on Microsoft's style guide. Example: "color" vs. "colour".
Microsoft.Spacing = YES  # Disables because of D2 diagrams - Allows ignoring spacing-related issues. Example: "word  word".
Microsoft.Contracting = YES  # Allows ignoring contracting-related issues. Example: "isn't" vs. "is not".
Microsoft.Quotes = YES  # Allows ignoring quotes-related issues. Example: "'single quotes' vs. "double quotes".
Microsoft.Contractions = YES  # Allows ignoring contractions-related issues. Example: "can't" vs. "cannot".
Microsoft.Foreign = YES  # Allows ignoring foreign phrases and words. Example: "et cetera".
Microsoft.Plurals = YES  # Allows ignoring pluralization-related issues. Example: "criterias" vs. "criteria".
Microsoft.Auto = YES  # Disables automatic suggestions for corrections. Example: "autocorrect".
Microsoft.AMPM = YES  # Allows ignoring AM/PM formatting issues. Example: "2 PM" vs. "14:00".
Microsoft.DateOrder = YES  # Allows ignoring date order-related issues. Example: "MM/DD/YYYY" vs. "DD/MM/YYYY".
Microsoft.Dashes = YES  # Allows ignoring dash-related issues. Example: "em-dash" vs. "en-dash".
Microsoft.DateFormat = YES  # Allows ignoring date format-related issues. Example: "2025-10-01" vs. "01/10/2025".
Microsoft.Units = YES  # Allows ignoring unit-related issues. Example: "5kg" vs. "5 kg".
Microsoft.Avoid = YES  # Allows ignoring "avoid" suggestions. Example: "Avoid using passive voice".
Microsoft.Negative = YES  # Allows ignoring negative phrasing suggestions. Example: "Not bad" vs. "Good".


Nun sind noch die richtigen Cross-Platform npm-Skripte für Vale bereitzustellen, um den Linter zu installieren und aufzurufen.


{
  "scripts": {
	  ...
	  ...
    "postinstall": "npm run install-vale",
	"install-vale": "node -e \"const cmd = process.platform === 'win32' ? 'powershell -ExecutionPolicy Bypass -File .vale/install-vale.ps1' : 'bash .vale/install-vale.sh'; require('child_process').exec(cmd, (err, stdout, stderr) => { if (err) { console.error(stderr); process.exit(1); } console.log(stdout); })\"",
    "prose": "node -e \"const vale = process.platform === 'win32' ? './.vale/vale.exe' : './.vale/vale'; const { exec } = require('child_process'); exec(vale + ' --config=.vale.ini src/content', (err, stdout, stderr) => { console.log(stdout); if (stderr) console.error(stderr); if (err) process.exit(1); });\""
  }
}


  • postinstall: Wird automatisch aufgerufen, wenn npm install ausgeführt wird
  • install-vale: Ruft je nach Plattform die richtigen Installationsscripte auf
  • prose: Ruft das Linting auf und gibt Fehler in der Kategorie „error“, „warning“ und „information“ aus

Ausnahmen für Sonderfälle sind eigens zu definieren, etwa für Situationen, in denen Vale eine Regel bewusst ignorieren soll. Beispielsweise würde die Regel write-good.So für den Satz „So the experiment failed because the measurements were taken incorrectly“ normalerweise den folgenden Fehler melden:


 src/content/blog/myfile.mdx
 188:52  error  Don't start a sentence with     write-good.So 
                'So '.                                        

✖ 1 error, 0 warnings and 0 suggestions in 38 files.


Um für diesen spezifischen Fall die Prüfung abzuschalten, ist die entsprechende Zeile mit einem Kommentar zu umfassen:


{/*  */}

So the experiment failed because the measurements were taken incorrectly

{/*  */}


Zu beachten ist dabei, dass die beiden Kommentar-Tags und die betroffene Zeile durch einen Zeilenumbruch getrennt sein müssen. Da es sich zudem um MDX-Dateien handelt, müssen die Zeilen erst mit einem JSX-Kommentarblock umschlossen werden, damit der Server nicht meckert, und anschließend mit einem HTML-Kommentarblock, damit Vale diesen erkennt. Darüber hinaus benötigt Vale – mit folgenden beiden Zeilen in der vale.ini – einen Hinweis, dass MDX-Dateien letztlich auch als Markdown-Dateien zu behandeln sind:


[formats]
mdx = md


Im Falle kompletter Textblöcke oder wenn der Grund der Deaktivierung der Vale-Regel benannt werden soll, ist es ebenfalls möglich, nur einzelne Regeln abzuschalten:


{/*  */}

So the experiment failed because the measurements were taken incorrectly

{/*  */}




Source link

Entwicklung & Code

Sicheres Linux: Amutable bringt „kryptografisch verifizierbare Integrität“


Ein Team von namhaften Linux-Entwicklern hat sich zum Ziel gesetzt, Linux sicherer zu machen und die Integrität von Linux-Systemen kryptografisch zu verifizieren. Das Projekt sattelt unter anderem auf „immutable Linux“ auf, also schreibgeschützten, unveränderlichen Kernsystemen. Der Name: Amutable. Die Firma hat ihren Sitz in Berlin.

Weiterlesen nach der Anzeige

Große Namen sind als Gründer involviert. Etwa Lennart Poettering, der systemd entwickelt und pflegt, oder Christian Brauner, der das VFS-Subsystem in Linux betreut, sowie Christ Kühl, ehemals Gründer von Kinvolk – die Flatcar Container Linux, ein immutable-Linux-System, entwickelt haben und von Microsoft eingekauft wurden.

Details liefert Amutable bislang nicht, deutet aber die Ziele an. Die Integrität des Systems soll kryptografisch prüfbar sein, das „System startet in einem verifizierten Status und bleibt im Zeitverlauf vertrauenswürdig“. Als Stichworte nennt die „Über“-Seite von Amutable die Integrität des Build-Prozesses, des Boot-Vorgangs und zur Laufzeit. Lennart Poettering hat bereits heiße Eisen mit „Measured Boot“ im Feuer. Ein Fingerzeig ist auch der geplante Vortrag „Remote Attestation of Imutable Operating Systems built on systemd“, den er am 12. März auf der Open Confidential Computing Conference in Berlin halten will.

Beim „Measured Boot“ prüft das System ausgehend von einer „Root of Trust“ im Trusted Platform Module (TPM) die Integrität von Firm- und Software beim Systemstart anhand von digitalen Fingerabdrücken, sogenannten Hash-Werten. Die Vergleichshashes liegen ebenfalls im TPM, dort in sogenannten Platform Configuration Registers (PCRs). Der Prozess ähnelt Secure Boot. Allerdings bricht Secure Boot bei abweichenden Hashes den Startvorgang ab, während Measured Boot die Hashes der Komponenten und ihrer Konfiguration protokolliert und sie verschlüsselt zur Überprüfung an andere Systeme senden kann (Remote Attestation, ausführliche Erläuterung von Infineon). Ein Vortrag auf der „All Systems Go“ im vergangenen Jahr zeigt zudem, was Poettering sich für Gedanken um die Sicherheitsarchitektur in Linux macht.

Derzeit besteht das Team von Amutable aus den Gründern Chris Kühl (CEO), Christian Brauner (CTO) und Lennart Poettering (Chief Engineer); Chief Product Officer ist David Strauss. Das Programmier-Team besteht aus Rodrigo Campos Catelin, Zbyszek Jędrzejewski-Szmek, Kai Lüke, Daan De Meyer, Joaquim Rocha, Aleksa Sarai und Michael Vogt. Die Beteiligten bringen Erfahrungen etwa für den Bau traditioneller Distributionen wie Debian, Fedora/CentOS, SUSE und Ubuntu mit, aber auch für unveränderliche, Image-basierte Distributionen wie Flatcar Container Linux, ParticleOS und Ubuntu Core, erklärt die Projekt-Ankündigung.

Kompetenzen für die genannten Ziele sind also reichlich vorhanden. Was genau Amutable aber bauen will, ist derzeit noch unklar. Eine diesbezügliche Anfrage wurde nicht umgehend beantwortet. Gegebenenfalls aktualisieren wir die Meldung damit.

Weiterlesen nach der Anzeige


(dmk)



Source link

Weiterlesen

Entwicklung & Code

Eine Schätzung ist keine Prognose: Sprachphilosophie im Softwareprojekt


Nicht nur in agilen Projekten gehört es zum normalen Vorgehen, Aufgaben zu schätzen (Ticket-Estimation). Persönlich vertrete ich dabei die Meinung, dass Schätzungen immer richtig sind. Es handelt sich schließlich um eine Schätzung.

Weiterlesen nach der Anzeige


Escape the Feature Factory: Stefan Mintert

Escape the Feature Factory: Stefan Mintert

(Bild: 

Stefan Mintert

)

Stefan Mintert arbeitet mit seinen Kunden daran, die Unternehmenskultur in der Softwareentwicklung zu verbessern. Das derzeit größte Potenzial sieht er in der Leadership; unabhängig von einer Hierarchieebene.

Die Aufgabe, dieses Potenzial zu heben, hat er sich nach einem beruflichen Weg mit einigen Kurswechseln gegeben. Ursprünglich aus der Informatik kommend, mit mehreren Jahren Consulting-Erfahrung, hatte er zunächst eine eigene Softwareentwicklungsfirma gegründet. Dabei stellte er fest, dass Führung gelernt sein will und gute Vorbilder selten sind.

Es zeichnete sich ab, dass der größte Unterstützungsbedarf bei seinen Kunden in der Softwareentwicklung nicht im Produzieren von Code liegt, sondern in der Führung. So war es für ihn klar, wohin die Reise mit seiner Firma Kutura geht: Führung verbessern, damit die Menschen, die die Produkte entwickeln, sich selbst entwickeln und wachsen können.

Für Heise schreibt Stefan als langjähriger, freier Mitarbeiter der iX seit 1994.

Wikipedia versteht darunter die genäherte Bestimmung von Zahlenwerten, Größen oder Parametern durch Augenschein, Erfahrung oder statistische Methoden. Eine Schätzung bestimmt also etwas, was ist, und nicht etwas, was wird. Eine Schätzung kümmert sich nicht um die Zukunft.

Die meisten Manager, die ich erlebt habe, behandeln Schätzungen aber wie eine Prognose, also eine Vorhersage über die Zukunft.

Wenn die Zukunft dann zur Gegenwart geworden ist, vergleicht man die Schätzung aus der Vergangenheit mit einem Wert, der sich zu einem späteren Zeitpunkt entwickelt hat. Das passt nicht zusammen.

Was die Manager eigentlich wollen, ist – wie gesagt – eine Prognose. Auch dazu hat Wikipedia etwas Interessantes zu sagen: Von anderen Aussagen über die Zukunft (z. B. Prophezeiungen) unterscheiden sich Prognosen durch ihre Wissenschaftsorientierung.

Wer sich als Entwickler von Schätzungen und dem Umgang damit unter Druck gesetzt fühlt, kann mal versuchen, Schätzungen durch Prognosen zu ersetzen. Selbstverständlich explodiert damit der Aufwand. Und genau das ist der Punkt: Viele Manager sprechen sehr viel und sehr gerne darüber, wie man besser schätzen kann. In diese Frage wird viel Energie gesteckt. Die Frage, wie man besser arbeiten kann, tritt dabei oft in den Hintergrund.

Weiterlesen nach der Anzeige

Es wirkt manchmal so, als ob die Schätzung (die eigentlich eine Prognose sein soll) wichtiger als das Produkt ist. Der Grund dahinter ist oft die den Managern heilige Planung. Die Gründe für deren Scheitern liegen aber nicht in der Durchführung der Schätzung. Eine Schätzung ist immer richtig, wie ich auch bereits an anderer Stelle schrieb.

Das gilt auch, wenn der geschätzte Wert vom wahren Wert abweicht. Wenn mir das nicht gefällt, müsste ich eine Schätzung durch eine Messung ersetzen. Das ist in diesem Fall nicht möglich, weil ich zukünftige Ergebnisse nicht heute messen kann.

Wenn ein Ticket bei Fertigstellung also dreimal so viel Zeit erforderte, wie geschätzt (prognostiziert) wurde, wird nicht die Frage gestellt, ob die Umsetzung des Tickets gut gelaufen ist. Nein. Bereits die Abweichung von der Schätzung (Prognose) genügt, um die geleistete Arbeit zu diskreditieren. Das halte ich für wenig zielführend, und hier sind meines Erachtens Softwareentwickler aufgefordert, der missbräuchlichen Verwendung von Schätzungen entgegenzutreten.

Der erste Schritt kann darin bestehen, klarzumachen, dass Pläne auf Grundlage von Schätzungen selbst Schätzungen und keine Zusagen sind. Wer es anders sieht, dem kann man mit hoher Wahrscheinlichkeit eine turbulente Zukunft prophezeien.

Wenn Du die Themen, die ich im Blog anspreche, in Deiner Firma verbessern möchtest, komm’ in unsere Leadership-Community für Softwareentwicklung. Sie wirkt auch ohne Führungsposition. Mit dem Code „heisedev“ gibt’s den Heise-Rabatt für Interactive-Members.


(rme)



Source link

Weiterlesen

Entwicklung & Code

Neu in .NET 10.0 [6]: Generische Erweiterungsblöcke in C# 14.0


Erweiterungsblöcke mit dem Schlüsselwort extension habe ich in der vorherigen Folge der Serie zu .NET 10.0 vorgestellt. Ein Erweiterungsblock darf einen oder mehrere generische Typparameter (optional inklusive Einschränkung mit where) besitzen:

Weiterlesen nach der Anzeige

extension(List source) { … }

oder

extension(List source) where T : INumber { … }


Der Dotnet-Doktor – Holger Schwichtenberg

Der Dotnet-Doktor – Holger Schwichtenberg

Dr. Holger Schwichtenberg ist technischer Leiter des Expertennetzwerks www.IT-Visions.de, das mit 53 renommierten Experten zahlreiche mittlere und große Unternehmen durch Beratungen und Schulungen sowie bei der Softwareentwicklung unterstützt. Durch seine Auftritte auf zahlreichen nationalen und internationalen Fachkonferenzen sowie mehr als 90 Fachbücher und mehr als 1500 Fachartikel gehört Holger Schwichtenberg zu den bekanntesten Experten für .NET und Webtechniken in Deutschland.

Folgender Code zeigt eine Klasse mit Erweiterungsblocken für List, wobei T auf Zahlen beschränkt ist, durch where T : INumber:


public static class MyExtensions
{
 extension(List source) where T : INumber // <-- Receiver Ein Erweiterungsblock darf eine oder mehrere generische Typparameter (optional inklusive Constraint) besitzen!!!
 {
  public List WhereGreaterThan(T threshold)
           => source.Where(x => x > threshold).ToList();
 
  public bool IsEmpty
           => !source.Any();
 
  /// 
  /// Erweitern um eine Instanz-Eigenschaft mit Getter und Setter
  /// 
  public int Size
  {
   get { return source.Count; }
   set
   {
    while (value < source.Count) source.RemoveAt(source.Count - 1);
    if (value > source.Count) source.AddRange(Enumerable.Repeat(default(T)!, value - source.Count).ToList());
   }
  }
 
  // NEU: Operatorüberladung als Extension und neu ist auch, dass man += überladen kann
  public void operator +=(int count)
  {
   source.Size = source.Count + count;
  }
 
  // NEU: Operatorüberladung als Extension und neu ist auch, dass man -= überladen kann
  public void operator -=(int count)
  {
   source.Size = source.Count - count;
  }
 
  // NEU: Operatorüberladung als Extension und neu ist auch, dass man ++ überladen kann
  public void operator ++()
  {
   source.Size += 1;
  }
 }
}


Folgender Code ruft die Erweiterungsmethoden für List auf:

Weiterlesen nach der Anzeige


public void Run()
 {
  CUI.Demo(nameof(CS14_ExtensionDemo) + ": Collection");
 
  var list = new List { 1, 2, 3, 4, 5 };
  var large = list.WhereGreaterThan(3);
  Console.WriteLine(large.IsEmpty);
  if (large.IsEmpty)
  {
   Console.WriteLine("Keine Zahlen größer als 3!");
  }
  else
  {
   Console.WriteLine(large.Count + " Zahlen sind größer als 3!");
  }
 
  CUI.H2("list.Size = 10");
  // Das klappt: Die Liste wird auf 10 Elemente mit Nullen aufgefüllt
  list.Size = 10;
  foreach (var x in list)
  {
   CUI.OL(x, separator: " = ");
  }
 
  CUI.H2("list.Size -= 2");
  list.Size -= 2;
  bool restart = true;
  foreach (var x in list)
  {
   CUI.OL(x, separator: " = ", restartCounter: restart);
   restart = false;
  }
 
  CUI.H2("list.Size++");
  list.Size++;
  restart = true;
  foreach (var x in list)
  {
   CUI.OL(x, separator: " = ", restartCounter: restart);
   restart = false;
  }
 }


Der Code erzeugt folgende Ausgabe:



Ausgabe des Beispielcodes


(rme)



Source link

Weiterlesen

Beliebt