configlet lint


Der Hauptzweck von configlet ist das Linting: Es wird geprüft, ob die Konfigurationsdateien eines Tracks korrekt aufgebaut sind, und zwar sowohl syntaktisch als auch semantisch. Falsch konfigurierte Tracks werden unter Umständen nicht korrekt synchronisiert, sehen auf der Website falsch aus oder bieten eine suboptimale Nutzererfahrung. Deshalb spielen die Prüfungen von configlet eine wichtige Rolle dabei, die Integrität von Exercism zu wahren.

Verwendung

Mit dem Befehl lint kannst du einen Track linten.

configlet [global-options] lint [command-options]

Global options:
  -h, --help                   Show this help message and exit
      --version                Show this tool's version information and exit
  -t, --track-dir <dir>        Specify a track directory to use instead of the current directory
  -v, --verbosity <verbosity>  The verbosity of output. Allowed values: q[uiet], n[ormal], d[etailed]

Regeln

Das sind die Linting-Regeln, die geprüft werden.

Regel: erforderliche Dateien sind vorhanden

Der Linter sollte prüfen, ob alle erforderlichen Dateien vorhanden sind. Die übungsunabhängigen Dateien, die vorhanden sein müssen, sind:

  • config.json
  • docs/ABOUT.md
  • docs/INSTALLATION.md
  • docs/LEARNING.md
  • docs/RESOURCES.md
  • docs/SNIPPET.txt
  • docs/TESTS.md
  • exercises/shared/.docs/help.md
  • exercises/shared/.docs/tests.md

Die Dateien, die spezifisch für Konzeptübungen sind und vorhanden sein müssen, sind:

  • exercises/concept/<slug>/.docs/hints.md
  • exercises/concept/<slug>/.docs/instructions.md
  • exercises/concept/<slug>/.docs/introduction.md
  • exercises/concept/<slug>/.meta/config.json

Eine ähnliche Liste wird es für Praxisübungen geben, aber die Spezifikation dafür haben wir noch nicht festgelegt.

Jedes in der config.json aufgeführte Konzept sollte die folgenden Dateien haben:

  • concepts/<slug>/about.md
  • concepts/<slug>/introduction.md
  • concepts/<slug>/links.json

Regel: Die Datei config.json ist gültig

Die Datei config.json sollte die folgenden Prüfungen bestehen:

  • Die Datei muss gültiges JSON sein
  • Der Schlüssel "language" ist erforderlich
  • Der Wert von "language" muss ein nicht-leerer String¹ mit einer Länge <= 255 sein
  • Der Schlüssel "slug" ist erforderlich
  • Der Wert von "slug" muss ein kebab-case-String² mit einer Länge <= 255 sein
  • Der Schlüssel "active" ist erforderlich
  • Der Wert von "active" muss ein boolescher Wert sein
  • Der Schlüssel "blurb" ist erforderlich
  • Der Wert von "blurb" muss ein nicht-leerer String¹ mit einer Länge <= 400 sein
  • Der Schlüssel "version" ist erforderlich
  • Der Wert von "version" muss die Ganzzahl 3 sein
  • Der Schlüssel "status.concept_exercises" ist erforderlich
  • Der Wert von "status.concept_exercises" muss ein boolescher Wert sein
  • Der Schlüssel "status.test_runner" ist erforderlich
  • Der Wert von "status.test_runner" muss ein boolescher Wert sein
  • Der Schlüssel "status.representer" ist erforderlich
  • Der Wert von "status.representer" muss ein boolescher Wert sein
  • Der Schlüssel "status.analyzer" ist erforderlich
  • Der Wert von "status.analyzer" muss ein boolescher Wert sein
  • Der Schlüssel "online_editor.indent_style" ist erforderlich
  • Der Wert von "online_editor.indent_style" muss der String space oder tab sein
  • Der Schlüssel "online_editor.indent_size" ist erforderlich
  • Der Wert von "online_editor.indent_size" muss eine Ganzzahl >= 0 und <= 8 sein
  • Der Schlüssel "online_editor.highlightjs_language" ist optional
  • Der Wert von "online_editor.highlightjs_language" muss ein nicht-leerer String¹ sein
  • Der Schlüssel "files" ist optional
  • Der Wert von "files" muss ein Objekt sein
  • Der Schlüssel "files.solution" ist optional
  • Der Wert von "files.solution" muss ein Array sein
  • Die Werte von "files.solution" müssen gültige Muster⁵ sein
  • Die Werte von "files.solution" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.test" ist optional
  • Der Wert von "files.test" muss ein Array sein
  • Die Werte von "files.test" müssen gültige Muster⁵ sein
  • Die Werte von "files.test" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.example" ist optional
  • Der Wert von "files.example" muss ein Array sein
  • Die Werte von "files.example" müssen gültige Muster⁵ sein
  • Die Werte von "files.example" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.exemplar" ist optional
  • Der Wert von "files.exemplar" muss ein Array sein
  • Die Werte von "files.exemplar" müssen gültige Muster⁵ sein
  • Die Werte von "files.exemplar" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.editor" ist optional
  • Der Wert von "files.editor" muss ein Array sein
  • Die Werte von "files.editor" müssen gültige Muster⁵ sein
  • Die Werte von "files.editor" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.invalidator" ist optional
  • Der Wert von "files.invalidator" muss ein Array sein
  • Die Werte von "files.invalidator" müssen gültige Muster⁵ sein
  • Die Werte von "files.invalidator" dürfen keine Duplikate enthalten
  • Muster dürfen nur in einem der Arrays "files.solution", "files.test", "files.example", "files.exemplar", "files.editor" oder "files.invalidator" aufgeführt werden (keine Überschneidung)
    • Wenn der Track d oder plsql ist, dürfen sich die Dateien in "files.solution" und "files.test" überschneiden
    • Die Dateien in "files.example und "files.exemplar" dürfen sich überschneiden
  • Der Schlüssel "test_runner.average_run_time" ist erforderlich, wenn "status.test_runner" gleich true ist
  • Der Wert von "test_runner.average_run_time" muss eine Ganzzahl > 0 sein
  • Der Schlüssel "approaches.snippet_extension" ist erforderlich, wenn der Track einen oder mehrere Ansätze hat
  • Der Wert von "approaches.snippet_extension" muss ein nicht-leerer String¹ sein
  • Der Schlüssel "exercises" ist erforderlich
  • Der Schlüssel "exercises.concept" ist erforderlich
  • Der Wert von "exercises.concept" muss ein Array sein
  • Der Schlüssel "exercises.concept[].slug" ist erforderlich
  • Der Wert von "exercises.concept[].slug" muss ein kebab-case-String² mit einer Länge <= 255 sein
  • Der Wert von "exercises.concept[].slug" muss in "exercises.concept[].slug" eindeutig sein und darf nicht in "exercises.practice[].slug" vorkommen
  • Der Schlüssel "exercises.concept[].name" ist erforderlich
  • Der Wert von "exercises.concept[].name" muss ein Title-Case-String³ mit einer Länge <= 255 sein
  • Der Schlüssel "exercises.concept[].uuid" ist erforderlich
  • Der Wert von "exercises.concept[].uuid" muss ein eindeutiger UUID-String der Version 4⁶ sein
  • Der Wert von "exercises.concept[].uuid" darf sich für die jeweilige Übung niemals ändern
  • Der Schlüssel "exercises.concept[].concepts" ist erforderlich
  • Der Wert von "exercises.concept[].concepts" muss ein nicht-leeres Array aus Strings sein, wenn "exercises.concept[].status" nicht gleich deprecated ist
  • Der Wert von "exercises.concept[].concepts" muss ein leeres Array sein, wenn "exercises.concept[].status" gleich deprecated ist
  • Die Werte von "exercises.concept[].concepts" müssen kebab-case-Strings² sein
  • Die Werte von "exercises.concept[].concepts" dürfen keine Duplikate enthalten
  • Die Werte von "exercises.concept[].concepts" dürfen in der Eigenschaft "concepts" keiner anderen Konzeptübung vorkommen
  • Die Werte von "exercises.concept[].concepts" müssen mit der Eigenschaft "concepts.slug" eines der Konzepte übereinstimmen
  • Der Schlüssel "exercises.concept[].prerequisites" ist erforderlich
  • Der Wert von "exercises.concept[].prerequisites" muss ein nicht-leeres Array aus Strings sein, wenn "exercises.concept[].status" nicht gleich deprecated ist, mit Ausnahme von genau einer Übung, die darf als Wert ein leeres Array haben
  • Der Wert von "exercises.concept[].prerequisites" muss ein leeres Array sein, wenn "exercises.concept[].status" gleich deprecated ist
  • Die Werte von "exercises.concept[].prerequisites" müssen kebab-case-Strings² sein
  • Die Werte von "exercises.concept[].prerequisites" dürfen keine Duplikate enthalten
  • Die Werte von "exercises.concept[].prerequisites" müssen mit den Werten der Eigenschaft "concepts" einer anderen Konzeptübung übereinstimmen
  • Die Werte von "exercises.concept[].prerequisites" dürfen keinem der Werte in der Eigenschaft "exercises.concept[].concepts" der Übung entsprechen
  • Die Werte von "exercises.concept[].prerequisites" müssen mit der Eigenschaft "concepts.slug" eines der Konzepte übereinstimmen
  • Zwischen "exercises.concept[].concepts" und "exercises.concept[].prerequisites" dürfen keine Zyklen bestehen
  • Der Schlüssel "exercises.concept[].status" ist optional
  • Der Wert von "exercises.concept[].status" muss der String wip, beta, active oder deprecated sein
  • Der Schlüssel "exercises.practice" ist erforderlich
  • Der Wert von "exercises.practice" muss ein Array sein
  • Der Schlüssel "exercises.practice[].slug" ist erforderlich
  • Der Wert von "exercises.practice[].slug" muss ein kebab-case-String² mit einer Länge <= 255 sein
  • Der Wert von "exercises.practice[].slug" muss in "exercises.practice[].slug" eindeutig sein und darf nicht in "exercises.concept[].slug" vorkommen
  • Es muss genau einen Wert von "exercises.practice[].slug" geben, der der String hello-world ist
  • Der Schlüssel "exercises.practice[].name" ist erforderlich
  • Der Wert von "exercises.practice[].name" muss ein Title-Case-String³ mit einer Länge <= 255 sein
  • Der Schlüssel "exercises.practice[].uuid" ist erforderlich
  • Der Wert von "exercises.practice[].uuid" muss ein eindeutiger UUID-String der Version 4⁶ sein
  • Der Wert von "exercises.practice[].uuid" darf sich für die jeweilige Übung niemals ändern
  • Der Schlüssel "exercises.practice[].difficulty" ist erforderlich
  • Der Wert von "exercises.practice[].difficulty" muss eine Ganzzahl >= 1 und <= 10 sein
  • Der Schlüssel "exercises.practice[].practices" ist erforderlich
  • Der Wert von "exercises.practice[].practices" muss ein nicht-leeres Array aus Strings sein, wenn "exercises.practice[].status" nicht gleich deprecated ist
  • Der Wert von "exercises.practice[].practices" muss ein leeres Array sein, wenn "exercises.practice[].status" gleich deprecated ist
  • Die Werte von "exercises.practice[].practices" müssen kebab-case-Strings² sein
  • Die Werte von "exercises.practice[].practices" dürfen keine Duplikate enthalten
  • Die Werte von "exercises.practice[].practices" müssen mit der Eigenschaft "concepts[].slug" eines der Konzepte übereinstimmen
  • Die Werte von "exercises.practice[].practices" dürfen sich auf den Slug eines einzelnen Konzepts höchstens 10 Mal beziehen (über alle Übungen hinweg)
  • Der Schlüssel "exercises.practice[].prerequisites" ist erforderlich
  • Der Wert von "exercises.practice[].prerequisites" muss ein nicht-leeres Array aus Strings sein, wenn "exercises.practice[].status" nicht gleich deprecated ist
  • Der Wert von "exercises.practice[].prerequisites" muss ein leeres Array sein, wenn "exercises.practice[].status" gleich deprecated ist
  • Der Wert von "exercises.practice[].prerequisites" muss ein leeres Array sein, wenn "exercises.practice[].slug" gleich hello-world ist
  • Die Werte von "exercises.practice[].prerequisites" müssen kebab-case-Strings² sein
  • Die Werte von "exercises.practice[].prerequisites" dürfen keine Duplikate enthalten
  • Die Werte von "exercises.practice[].prerequisites" müssen mit den Werten von "exercises.concept[].concepts" einer Konzeptübung übereinstimmen
  • Die Werte von "exercises.practice[].prerequisites" müssen mit der Eigenschaft "concepts[].slug" eines der Konzepte übereinstimmen
  • Der Schlüssel "exercises.practice[].status" ist optional
  • Der Wert von "exercises.practice[].status" muss der String wip, beta, active oder deprecated sein
  • Der Wert von "exercises.practice[].status" muss, wenn "exercises.practice[].slug" gleich hello-world ist, entweder weggelassen werden oder der String active sein
  • Der Schlüssel "exercises.foregone" ist optional
  • Der Wert von "exercises.foregone" muss ein Array sein
  • Die Werte von "exercises.foregone" müssen kebab-case-Strings² sein
  • Die Werte von "exercises.foregone" dürfen keine Duplikate enthalten
  • Die Werte von "exercises.foregone" dürfen keinem der Slugs von Konzept- oder Praxisübungen entsprechen
  • Der Schlüssel "concepts" ist erforderlich
  • Der Wert von "concepts" muss ein Array sein
  • Der Schlüssel "concepts[].uuid" ist erforderlich
  • Der Wert von "concepts[].uuid" muss ein eindeutiger UUID-String der Version 4⁶ sein
  • Der Wert von "concepts[].uuid" darf sich für das jeweilige Konzept niemals ändern
  • Der Schlüssel "concepts[].slug" ist erforderlich
  • Der Wert von "concepts[].slug" muss ein kebab-case-String² mit einer Länge <= 255 sein
  • Der Schlüssel "concepts[].name" ist erforderlich
  • Der Wert von "concepts[].name" muss ein Title-Case-String³ mit einer Länge <= 255 sein
  • Der Schlüssel "concepts[].tags" ist optional
  • Der Schlüssel "concepts[].tags.all" ist optional, es sei denn, "concepts[].tags.any" ist leer
  • Der Wert von "concepts[].tags.all" muss ein Array sein
  • Die Werte von "concepts[].tags.all" müssen nicht-leere Tag⁷-Strings mit einer Länge <= 255 sein
  • Die Werte von "concepts[].tags.all" dürfen keine Duplikate enthalten
  • Der Schlüssel "concepts[].tags.any" ist optional, es sei denn, "concepts[].tags.all" ist leer
  • Der Wert von "concepts[].tags.any" muss ein Array sein
  • Die Werte von "concepts[].tags.any" müssen nicht-leere Tag⁷-Strings mit einer Länge <= 255 sein
  • Die Werte von "concepts[].tags.any" dürfen keine Duplikate enthalten
  • Der Schlüssel "concepts[].tags.not" ist optional
  • Der Wert von "concepts[].tags.not" muss ein Array sein
  • Die Werte von "concepts[].tags.not" müssen nicht-leere Tag⁷-Strings mit einer Länge <= 255 sein
  • Die Werte von "concepts[].tags.not" dürfen keine Duplikate enthalten
  • Jeder Wert von "concepts" muss eine Datei concept/<concepts.slug>/about.md haben. Die Linting-Regeln für diese Datei sind unten angegeben.
  • Jeder Wert von "concepts" muss eine Datei concept/<concepts.slug>/introduction.md haben. Die Linting-Regeln für diese Datei sind unten angegeben.
  • Jeder Wert von "concepts" muss eine Datei concept/<concepts.slug>/links.json haben. Die Linting-Regeln für diese Datei sind unten angegeben.
  • Der Schlüssel "key_features" ist optional
  • Der Wert von "key_features" muss ein Array mit der Länge = 6 sein
  • Der Schlüssel "key_features[].icon" ist erforderlich
  • Der Wert von "key_features[].icon" muss einen der vordefinierten Icon-Werte verwenden
  • Der Schlüssel "key_features[].title" ist erforderlich
  • Der Wert von "key_features[].title" muss ein Sentence-Case-String⁴ mit einer Länge <= 25 sein
  • Der Schlüssel "key_features[].content" ist erforderlich
  • Der Wert von "key_features[].content" muss ein nicht-leerer String¹ mit einer Länge <= 100 sein
  • Der Schlüssel "tags" ist erforderlich
  • Der Wert von "tags" muss ein Array aus Strings sein
  • Die Werte von "tags" dürfen keine Duplikate enthalten
  • Die Werte von "tags" müssen einen der vordefinierten Tag-Werte verwenden

Regel: exercises/concept/<slug>/.meta/config.json ist gültig

  • Die Datei muss gültiges JSON sein
  • Die JSON-Wurzel muss ein Objekt sein
  • Der Schlüssel "blurb" ist erforderlich
  • Der Wert von "blurb" muss ein nicht-leerer String¹ mit einer Länge <= 350 sein
  • Der Schlüssel "source" ist optional
  • Der Wert von "source" muss ein nicht-leerer String¹ sein
  • Der Schlüssel "source_url" ist optional
  • Der Wert von "source_url" muss eine URL sein
  • Der Schlüssel "authors" ist erforderlich
  • Der Wert von "authors" muss ein nicht-leeres Array sein
  • Die Werte von "authors" müssen nicht-leere Strings¹ sein
  • Die Werte von "authors" dürfen keine Duplikate enthalten
  • Die Werte von "authors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Der Schlüssel "contributors" ist optional
  • Der Wert von "contributors" muss ein Array sein
  • Die Werte von "contributors" müssen nicht-leere Strings¹ sein
  • Die Werte von "contributors" dürfen keine Duplikate enthalten
  • Die Werte von "contributors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Benutzer dürfen nur in einem der Arrays "authors" oder "contributors" aufgeführt werden (keine Überschneidung)
  • Der Schlüssel "files.solution" ist erforderlich
  • Der Wert von "files.solution" muss ein nicht-leeres Array sein
  • Die Werte von "files.solution" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.test" ist erforderlich
  • Der Wert von "files.test" muss ein nicht-leeres Array sein
  • Die Werte von "files.test" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.exemplar" ist erforderlich
  • Der Wert von "files.exemplar" muss ein nicht-leeres Array sein
  • Die Werte von "files.exemplar" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.editor" ist optional
  • Der Wert von "files.editor" muss ein Array sein
  • Die Werte von "files.editor" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.invalidator" ist optional
  • Der Wert von "files.invalidator" muss ein Array sein
  • Die Werte von "files.invalidator" dürfen keine Duplikate enthalten
  • Die in "files.solution" aufgeführten Dateien müssen existieren
  • Die in "files.test" aufgeführten Dateien müssen existieren
  • Die in "files.exemplar" aufgeführten Dateien müssen existieren
  • Die in "files.editor" aufgeführten Dateien müssen existieren
  • Die in "files.invalidator" aufgeführten Dateien müssen existieren
  • Dateien dürfen nur in einem der Arrays "files.solution", "files.test", "files.exemplar" oder "files.invalidator" aufgeführt werden (keine Überschneidung)
    • Wenn der Track d oder plsql ist, dürfen sich die Dateien in "files.solution" und "files.test" überschneiden
  • Der Schlüssel "forked_from" ist optional
  • Der Wert von "forked_from" muss ein Array sein
  • Die Werte von "forked_from" müssen Strings im Format <track-slug>/<exercise-slug> sein (z. B. fsharp/bird-watcher)
  • Die Werte von "forked_from" müssen auf tatsächlich implementierte Übungen verweisen
  • Die Werte von "forked_from" dürfen keine Duplikate enthalten
  • Der Schlüssel "language_versions" ist optional
  • Der Wert von "language_versions" muss ein String sein
  • Der Schlüssel "representer.version" ist optional
  • Der Wert von "representer.version" muss eine Ganzzahl >= 1 sein
  • Der Schlüssel "icon" ist optional
  • Der Wert von "icon" muss ein kebab-case-String² sein

Regel: exercises/concept/<slug>/.docs/hints.md ist gültig

  • Das Markdown muss den Markdown-Standards entsprechen
  • Alle Überschriften müssen entweder ## General oder ## X. <task> lauten, wobei X der Aufgabennummer in der Überschrift der instructions.md entspricht
  • Alle Hinweise müssen als Markdown-Listeneinträge angegeben werden
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: exercises/concept/<slug>/.docs/instructions.md ist gültig

  • Das Markdown muss den Markdown-Standards entsprechen
  • Alle Aufgaben müssen mit einer Überschrift der zweiten Ebene beginnen, die mit einer Zahl gefolgt von einem Punkt anfängt: ## 1. Do X
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: exercises/concept/<slug>/.docs/instructions.md.tpl ist gültig (falls vorhanden)

  • Das Konzept jedes Konzept-Platzhalters muss mit der Eigenschaft "concepts.slug" eines der Konzepte in der config.json des Tracks übereinstimmen.

Regel: exercises/concept/<slug>/.docs/introduction.md ist gültig

  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: exercises/practice/<slug>/.meta/config.json ist gültig

  • Die Datei muss gültiges JSON sein
  • Die JSON-Wurzel muss ein Objekt sein
  • Der Schlüssel "blurb" ist erforderlich
  • Der Wert von "blurb" muss ein nicht-leerer String¹ mit einer Länge <= 350 sein
  • Der Schlüssel "source" ist optional
  • Der Wert von "source" muss ein nicht-leerer String¹ sein
  • Der Schlüssel "source_url" ist optional
  • Der Wert von "source_url" muss eine URL sein
  • Der Schlüssel "authors" ist optional
  • Der Wert von "authors" muss ein Array sein
  • Die Werte von "authors" müssen nicht-leere Strings¹ sein
  • Die Werte von "authors" dürfen keine Duplikate enthalten
  • Die Werte von "authors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Der Schlüssel "contributors" ist optional
  • Der Wert von "contributors" muss ein Array sein
  • Die Werte von "contributors" müssen nicht-leere Strings¹ sein
  • Die Werte von "contributors" dürfen keine Duplikate enthalten
  • Die Werte von "contributors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Benutzer dürfen nur in einem der Arrays "authors" oder "contributors" aufgeführt werden (keine Überschneidung)
  • Der Schlüssel "files.solution" ist erforderlich
  • Der Wert von "files.solution" muss ein nicht-leeres Array sein
  • Die Werte von "files.solution" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.test" ist erforderlich
  • Der Wert von "files.test" muss ein nicht-leeres Array sein
  • Die Werte von "files.test" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.example" ist erforderlich
  • Der Wert von "files.example" muss ein nicht-leeres Array sein
  • Die Werte von "files.example" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.editor" ist optional
  • Der Wert von "files.editor" muss ein Array sein
  • Die Werte von "files.editor" dürfen keine Duplikate enthalten
  • Der Schlüssel "files.invalidator" ist optional
  • Der Wert von "files.invalidator" muss ein Array sein
  • Die Werte von "files.invalidator" dürfen keine Duplikate enthalten
  • Die in "files.solution" aufgeführten Dateien müssen existieren
  • Die in "files.test" aufgeführten Dateien müssen existieren
  • Die in "files.example" aufgeführten Dateien müssen existieren
  • Die in "files.editor" aufgeführten Dateien müssen existieren
  • Die in "files.invalidator" aufgeführten Dateien müssen existieren
  • Dateien dürfen nur in einem der Arrays "files.solution", "files.test", "files.example oder "files.invalidator" aufgeführt werden (keine Überschneidung)
    • Wenn der Track d oder plsql ist, dürfen sich die Dateien in "files.solution" und "files.test" überschneiden
  • Der Schlüssel "language_versions" ist optional
  • Der Wert von "language_versions" muss ein String sein
  • Der Schlüssel "test_runner" ist optional
  • Der Wert von "test_runner" muss ein boolescher Wert sein
  • Der Schlüssel "representer.version" ist optional
  • Der Wert von "representer.version" muss eine Ganzzahl >= 1 sein
  • Der Schlüssel "icon" ist optional
  • Der Wert von "icon" muss ein kebab-case-String² sein

Regel: exercises/{concept|practice}/<slug>/.approaches/config.json ist gültig

  • Die Datei ist optional, es sei denn, es gibt eine introduction.md oder ein benachbartes Verzeichnis
  • Die Datei muss gültiges JSON sein
  • Die JSON-Wurzel muss ein Objekt sein
  • Der Schlüssel "introduction.authors" ist optional
  • Der Wert von "introduction.authors" muss ein Array sein
  • Die Werte von "introduction.authors" müssen nicht-leere Strings¹ sein
  • Die Werte von "introduction.authors" dürfen keine Duplikate enthalten
  • Die Werte von "introduction.authors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Wenn das Array "introduction.authors" nicht leer ist, muss es eine nicht-leere introduction.md-Datei geben
  • Der Schlüssel "introduction.contributors" ist optional
  • Der Wert von "introduction.contributors" muss ein Array sein
  • Die Werte von "introduction.contributors" müssen nicht-leere Strings¹ sein
  • Die Werte von "introduction.contributors" dürfen keine Duplikate enthalten
  • Die Werte von "introduction.contributors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Wenn das Array "introduction.contributors" nicht leer ist, muss es eine nicht-leere introduction.md-Datei geben
  • Benutzer dürfen nur in einem der Arrays "introduction.authors" oder "introduction.contributors" aufgeführt werden (keine Überschneidung)
  • Der Schlüssel "approaches" ist optional, es sei denn, es gibt ein benachbartes Verzeichnis (das die Dateien des Ansatzes enthält)
  • Der Wert von "approaches" muss ein Array aus Objekten sein
  • Der Schlüssel "approaches[].uuid" ist erforderlich
  • Der Wert von "approaches[].uuid" muss ein eindeutiger UUID-String der Version 4⁶ sein
  • Der Wert von "approaches[].uuid" darf sich für das jeweilige Konzept niemals ändern
  • Der Schlüssel "approaches[].slug" ist erforderlich
  • Der Wert von "approaches[].slug" muss ein kebab-case-String² mit einer Länge <= 255 sein
  • Der Wert von "approaches[].slug" muss eine entsprechende nicht-leere Datei <slug>/content.md haben
  • Der Wert von "approaches[].slug" muss eine entsprechende nicht-leere Datei <slug>/snippet.txt haben
  • Der Schlüssel "approaches[].title" ist erforderlich
  • Der Wert von "approaches[].title" muss ein Title-Case-String³ mit einer Länge <= 255 sein
  • Der Schlüssel "approaches[].blurb" ist erforderlich
  • Der Wert von "approaches[].blurb" muss ein nicht-leerer String¹ mit einer Länge <= 350 sein
  • Der Schlüssel "approaches[].authors" ist erforderlich
  • Der Wert von "approaches[].authors" muss ein nicht-leeres Array sein
  • Die Werte von "approaches[].authors" müssen nicht-leere Strings¹ sein
  • Die Werte von "approaches[].authors" dürfen keine Duplikate enthalten
  • Die Werte von "approaches[].authors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Der Schlüssel "approaches[].contributors" ist optional
  • Der Wert von "approaches[].contributors" muss ein Array sein
  • Die Werte von "approaches[].contributors" müssen nicht-leere Strings¹ sein
  • Die Werte von "approaches[].contributors" dürfen keine Duplikate enthalten
  • Die Werte von "approaches[].contributors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Benutzer dürfen nur in einem der Arrays "approaches[].authors" oder "approaches[].contributors" aufgeführt werden (keine Überschneidung)
  • Der Schlüssel "approaches[].tags" ist optional
  • Der Schlüssel "approaches[].tags.all" ist optional, es sei denn, "approaches[].tags.any" ist leer
  • Der Wert von "approaches[].tags.all" muss ein Array sein
  • Die Werte von "approaches[].tags.all" müssen nicht-leere Tag⁷-Strings mit einer Länge <= 255 sein
  • Die Werte von "approaches[].tags.all" dürfen keine Duplikate enthalten
  • Der Schlüssel "approaches[].tags.any" ist optional, es sei denn, "approaches[].tags.all" ist leer
  • Der Wert von "approaches[].tags.any" muss ein Array sein
  • Die Werte von "approaches[].tags.any" müssen nicht-leere Tag⁷-Strings mit einer Länge <= 255 sein
  • Die Werte von "approaches[].tags.any" dürfen keine Duplikate enthalten
  • Der Schlüssel "approaches[].tags.not" ist optional
  • Der Wert von "approaches[].tags.not" muss ein Array sein
  • Die Werte von "approaches[].tags.not" müssen nicht-leere Tag⁷-Strings mit einer Länge <= 255 sein
  • Die Werte von "approaches[].tags.not" dürfen keine Duplikate enthalten

Regel: exercises/{concept|practice}/<slug>/.approaches/<approach-slug>/content.md ist gültig

  • Die Datei ist erforderlich, wenn ein passender Eintrag "approaches[].slug" in der Datei .approaches/config.json existiert
  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: exercises/{concept|practice}/<slug>/.approaches/<approach-slug>/snippet.<snippet-extension> ist gültig

  • Die Datei ist erforderlich, wenn ein passender Eintrag "approaches[].slug" in der Datei .approaches/config.json existiert
  • Das Snippet darf höchstens 8 Zeilen haben
  • Die Snippet-Erweiterung wird dem Wert approaches.snippet_extension in der config.json des Tracks entnommen

Regel: exercises/{concept|practice}/<slug>/.articles/config.json ist gültig

  • Die Datei ist optional, es sei denn, es gibt ein benachbartes Verzeichnis
  • Die Datei muss gültiges JSON sein
  • Die JSON-Wurzel muss ein Objekt sein
  • Der Schlüssel "articles" ist optional, es sei denn, es gibt ein benachbartes Verzeichnis (das die Dateien des Artikels enthält)
  • Der Wert von "articles" muss ein Array aus Objekten sein
  • Der Schlüssel "articles[].uuid" ist erforderlich
  • Der Wert von "articles[].uuid" muss ein eindeutiger UUID-String der Version 4⁶ sein
  • Der Wert von "articles[].uuid" darf sich für das jeweilige Konzept niemals ändern
  • Der Schlüssel "articles[].slug" ist erforderlich
  • Der Wert von "articles[].slug" muss ein kebab-case-String² mit einer Länge <= 255 sein
  • Der Wert von "articles[].slug" muss eine entsprechende nicht-leere Datei <slug>/content.md haben
  • Der Wert von "articles[].slug" muss eine entsprechende nicht-leere Datei <slug>/snippet.md haben
  • Der Schlüssel "articles[].title" ist erforderlich
  • Der Wert von "articles[].title" muss ein Title-Case-String³ mit einer Länge <= 255 sein
  • Der Schlüssel "articles[].blurb" ist erforderlich
  • Der Wert von "articles[].blurb" muss ein nicht-leerer String¹ mit einer Länge <= 350 sein
  • Der Schlüssel "articles[].authors" ist erforderlich
  • Der Wert von "articles[].authors" muss ein nicht-leeres Array sein
  • Die Werte von "articles[].authors" müssen nicht-leere Strings¹ sein
  • Die Werte von "articles[].authors" dürfen keine Duplikate enthalten
  • Die Werte von "articles[].authors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Der Schlüssel "articles[].contributors" ist optional
  • Der Wert von "articles[].contributors" muss ein Array sein
  • Die Werte von "articles[].contributors" müssen nicht-leere Strings¹ sein
  • Die Werte von "articles[].contributors" dürfen keine Duplikate enthalten
  • Die Werte von "articles[].contributors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Benutzer dürfen nur in einem der Arrays "articles[].authors" oder "articles[].contributors" aufgeführt werden (keine Überschneidung)

Regel: exercises/{concept|practice}/<slug>/.articles/<article-slug>/content.md ist gültig

  • Die Datei ist erforderlich, wenn ein passender Eintrag "articles[].slug" in der Datei .articles/config.json existiert
  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: exercises/{concept|practice}/<slug>/.articles/<article-slug>/snippet.md ist gültig

  • Die Datei ist erforderlich, wenn ein passender Eintrag "articles[].slug" in der Datei .articles/config.json existiert
  • Das Markdown muss den Markdown-Standards entsprechen
  • Das Snippet darf höchstens 8 Zeilen haben (führende und abschließende Code-Fence-Markierungen werden ignoriert)

Regel: exercises/shared/.docs/debug.md ist gültig

  • Die Datei ist optional
  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: exercises/shared/.docs/help.md ist gültig

  • Die Datei ist erforderlich
  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: exercises/shared/.docs/tests.md ist gültig

  • Die Datei ist erforderlich
  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: concepts/<slug>/about.md ist gültig

  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: concepts/<slug>/introduction.md ist gültig

  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)
  • Die Datei muss gültiges JSON sein
  • Die JSON-Wurzel muss ein Array sein
  • Die Eigenschaft "[].url" ist erforderlich
  • Der Wert von "[].url" muss eine URL sein
  • Die Eigenschaft "[].description" ist erforderlich
  • Der Wert von "[].description" muss ein nicht-leerer String¹ sein
  • Die Eigenschaft "[].icon_url" ist optional
  • Der Wert von "[].icon_url" muss eine URL sein

Regel: concept/<slug>/.meta/config.json ist gültig

  • Die Datei muss gültiges JSON sein
  • Die JSON-Wurzel muss ein Objekt sein
  • Der Schlüssel "blurb" ist erforderlich
  • Der Wert von "blurb" muss ein nicht-leerer String¹ mit einer Länge <= 350 sein
  • Der Schlüssel "authors" ist erforderlich
  • Der Wert von "authors" muss ein Array sein
  • Die Werte von "authors" müssen nicht-leere Strings¹ sein
  • Die Werte von "authors" dürfen keine Duplikate enthalten
  • Die Werte von "authors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Der Schlüssel "contributors" ist optional
  • Der Wert von "contributors" muss ein Array sein
  • Die Werte von "contributors" müssen nicht-leere Strings¹ sein
  • Die Werte von "contributors" dürfen keine Duplikate enthalten
  • Die Werte von "contributors" werden ohne Beachtung der Groß-/Kleinschreibung behandelt
  • Benutzer dürfen nur in einem der Arrays "authors" oder "contributors" aufgeführt werden (keine Überschneidung)

Regel: docs/ABOUT.md ist gültig

  • Die Datei ist erforderlich
  • Der Inhalt der Datei darf nicht leer sein
  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: docs/INSTALLATION.md ist gültig

  • Die Datei ist erforderlich
  • Der Inhalt der Datei darf nicht leer sein
  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: docs/LEARNING.md ist gültig

  • Die Datei ist erforderlich
  • Der Inhalt der Datei darf nicht leer sein
  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: docs/RESOURCES.md ist gültig

  • Die Datei ist erforderlich
  • Der Inhalt der Datei darf nicht leer sein
  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Regel: docs/SNIPPET.txt ist gültig

  • Die Datei ist erforderlich
  • Der Inhalt der Datei darf nicht leer sein

Regel: docs/TESTS.md ist gültig

  • Die Datei ist erforderlich
  • Der Inhalt der Datei darf nicht leer sein
  • Das Markdown muss den Markdown-Standards entsprechen
  • Links müssen absolut sein (relative Links sind nicht erlaubt)

Glossar

  1. Nicht-leerer String: ein String, der mindestens ein Zeichen enthält, das kein Leerzeichen ist.

  2. kebab-case-String: ein String, der nur Zeichen aus dem Bereich [a-z0-9] enthält, die optional durch Bindestriche getrennt sind (z. B. „two-fer“). Er muss dem regulären Ausdruck entsprechen: ^[a-z0-9]+(-[a-z0-9]+)*$

  3. Title-Case-String: ein nicht-leerer String, der den folgenden Richtlinien des Chicago Manual of Style folgt:

    • Schreibe das erste und das letzte Wort von Titeln und Untertiteln groß.
    • Schreibe „wichtige“ Wörter groß (Substantive, Pronomen, Verben, Adjektive, Adverbien und einige Konjunktionen).
    • Schreibe die Konjunktionen and, but, for, or und nor klein.
    • Schreibe die Artikel the, a und an klein.
    • Schreibe Präpositionen klein, unabhängig von ihrer Länge, außer wenn sie betont werden, adverbial oder adjektivisch gebraucht werden oder als Konjunktion dienen.
    • Schreibe die Wörter to und as klein.
    • Schreibe den zweiten Teil lateinischer Artnamen klein.
  4. Sentence-Case-String: ein nicht-leerer String, der den folgenden Richtlinien folgt:

    • Schreibe das erste Wort des Satzes groß, ebenso Eigennamen und andere Wörter, die eine spezifischere Regel großschreiben verlangt.
  5. Gültiges files-Muster: Ein nicht-leerer String¹, der den Ort einer in einer Übung verwendeten Datei relativ zum Verzeichnis der Übung angibt. Ein Muster kann einen der folgenden Platzhalter verwenden:

    • %{kebab_slug}: der Übungs-Slug im kebab-case-Format (z. B. bit-manipulation)
    • %{snake_slug}: der Übungs-Slug im snake_case-Format (z. B. bit_manipulation)
    • %{camel_slug}: der Übungs-Slug im camelCase-Format (z. B. bitManipulation)
    • %{pascal_slug}: der Übungs-Slug im PascalCase-Format (z. B. BitManipulation)
  6. Eindeutiger UUID-String der Version 4: Ein String, der alle folgenden Bedingungen erfüllt:

    • Er existiert nur einmal in der config.json auf Track-Ebene eines bestimmten Exercism-Tracks
    • Er existiert nicht in der config.json auf Track-Ebene eines anderen Exercism-Tracks
    • Er existiert in keiner canonical-data.json-Datei unter https://github.com/exercism/problem-specifications
    • Er existiert nirgendwo sonst auf Exercism
    • Er entspricht dem regulären Ausdruck:
    ^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
    

    Zum Beispiel hat die folgende UUID die korrekte Form:

    d334ffe3-657e-4725-a950-290b284b6d9f
    

    Mit configlet uuid kannst du eine passende UUID generieren.

  7. Gültiger Analyzer-tag: Ein nicht-leerer String¹ im Format <category>:<thing>. Der Wert von <category> muss einer der folgenden sein:

  • paradigm (z. B. paradigm:functional)
  • technique (z. B. technique:recursion)
  • construct (z. B. construct:bitwise-and)
  • uses (z. B. uses:DateTime.add_seconds)

Der Wert von <thing> muss ein nicht-leerer String¹ sein.