configlet lint


configletの主な用途はリンティングです。トラックの設定ファイルが、構文的にも意味的にも正しく構成されているかを確認します。設定が間違っているトラックは、正しく同期されなかったり、ウェブサイトでの表示がおかしくなったり、ユーザー体験が最適でなくなったりする可能性があります。そのため、configletのチェック機能は、Exercismの整合性を保つうえで重要な役割を果たします。

使い方

lintコマンドを使うと、トラックをリントできます。

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]

ルール

以下は、チェックされるリンティングルールです。

ルール: 必須ファイルが存在する

リンターは、必須ファイルがすべて存在するかどうかをチェックする必要があります。演習に固有でない、存在しなければならないファイルは次のとおりです。

  • 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

コンセプト演習に固有で、存在しなければならないファイルは次のとおりです。

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

プラクティス演習についても同様のリストがありますが、その仕様はまだ定義されていません。

config.jsonにリストされている各コンセプトには、次のファイルが必要です。

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

ルール: config.jsonファイルが有効である

config.jsonファイルは、次のチェックを満たす必要があります。

  • ファイルは有効なJSONでなければなりません
  • "language"キーは必須です
  • "language"の値は、長さ255以下の空でない文字列¹でなければなりません
  • "slug"キーは必須です
  • "slug"の値は、長さ255以下のkebab-case文字列²でなければなりません
  • "active"キーは必須です
  • "active"の値は真偽値でなければなりません
  • "blurb"キーは必須です
  • "blurb"の値は、長さ400以下の空でない文字列¹でなければなりません
  • "version"キーは必須です
  • "version"の値は整数3でなければなりません
  • "status.concept_exercises"キーは必須です
  • "status.concept_exercises"の値は真偽値でなければなりません
  • "status.test_runner"キーは必須です
  • "status.test_runner"の値は真偽値でなければなりません
  • "status.representer"キーは必須です
  • "status.representer"の値は真偽値でなければなりません
  • "status.analyzer"キーは必須です
  • "status.analyzer"の値は真偽値でなければなりません
  • "online_editor.indent_style"キーは必須です
  • "online_editor.indent_style"の値は文字列spaceまたはtabでなければなりません
  • "online_editor.indent_size"キーは必須です
  • "online_editor.indent_size"の値は、0以上8以下の整数でなければなりません
  • "online_editor.highlightjs_language"キーは任意です
  • "online_editor.highlightjs_language"の値は、空でない文字列¹でなければなりません
  • "files"キーは任意です
  • "files"の値はオブジェクトでなければなりません
  • "files.solution"キーは任意です
  • "files.solution"の値は配列でなければなりません
  • "files.solution"の値は有効なパターン⁵でなければなりません
  • "files.solution"の値に重複があってはなりません
  • "files.test"キーは任意です
  • "files.test"の値は配列でなければなりません
  • "files.test"の値は有効なパターン⁵でなければなりません
  • "files.test"の値に重複があってはなりません
  • "files.example"キーは任意です
  • "files.example"の値は配列でなければなりません
  • "files.example"の値は有効なパターン⁵でなければなりません
  • "files.example"の値に重複があってはなりません
  • "files.exemplar"キーは任意です
  • "files.exemplar"の値は配列でなければなりません
  • "files.exemplar"の値は有効なパターン⁵でなければなりません
  • "files.exemplar"の値に重複があってはなりません
  • "files.editor"キーは任意です
  • "files.editor"の値は配列でなければなりません
  • "files.editor"の値は有効なパターン⁵でなければなりません
  • "files.editor"の値に重複があってはなりません
  • "files.invalidator"キーは任意です
  • "files.invalidator"の値は配列でなければなりません
  • "files.invalidator"の値は有効なパターン⁵でなければなりません
  • "files.invalidator"の値に重複があってはなりません
  • パターンは、"files.solution"、"files.test"、"files.example"、"files.exemplar"、"files.editor"、"files.invalidator"のいずれか1つの配列にのみ記載できます(重複は不可)
    • トラックがdまたはplsqlの場合、"files.solution"と"files.test"のファイルは重複して_もかまいません_
    • "files.exampleと"files.exemplar"のファイルは重複して_もかまいません_
  • "status.test_runner"がtrueの場合、"test_runner.average_run_time"キーは必須です
  • "test_runner.average_run_time"の値は、0より大きい整数でなければなりません
  • トラックに1つ以上のアプローチがある場合、"approaches.snippet_extension"キーは必須です
  • "approaches.snippet_extension"の値は、空でない文字列¹でなければなりません
  • "exercises"キーは必須です
  • "exercises.concept"キーは必須です
  • "exercises.concept"の値は配列でなければなりません
  • "exercises.concept[].slug"キーは必須です
  • "exercises.concept[].slug"の値は、長さ255以下のkebab-case文字列²でなければなりません
  • "exercises.concept[].slug"の値は"exercises.concept[].slug"内で一意でなければならず、"exercises.practice[].slug"に存在してはなりません
  • "exercises.concept[].name"キーは必須です
  • "exercises.concept[].name"の値は、長さ255以下のTitle Case文字列³でなければなりません
  • "exercises.concept[].uuid"キーは必須です
  • "exercises.concept[].uuid"の値は、一意なバージョン4のUUID文字列⁶でなければなりません
  • 各演習の"exercises.concept[].uuid"の値は、決して変わってはなりません
  • "exercises.concept[].concepts"キーは必須です
  • "exercises.concept[].status"がdeprecatedでない場合、"exercises.concept[].concepts"の値は空でない文字列の配列でなければなりません
  • "exercises.concept[].status"がdeprecatedの場合、"exercises.concept[].concepts"の値は空の配列でなければなりません
  • "exercises.concept[].concepts"の値はkebab-case文字列²でなければなりません
  • "exercises.concept[].concepts"の値に重複があってはなりません
  • "exercises.concept[].concepts"の値は、他のどのコンセプト演習の"concepts"プロパティにも含まれてはなりません
  • "exercises.concept[].concepts"の値は、いずれかのコンセプトの"concepts.slug"プロパティと一致しなければなりません
  • "exercises.concept[].prerequisites"キーは必須です
  • "exercises.concept[].status"がdeprecatedでない場合、"exercises.concept[].prerequisites"の値は空でない文字列の配列でなければなりません。ただし、値を空の配列にすることが_認められている_演習がちょうど1つだけある場合は除きます
  • "exercises.concept[].status"がdeprecatedの場合、"exercises.concept[].prerequisites"の値は空の配列でなければなりません
  • "exercises.concept[].prerequisites"の値はkebab-case文字列²でなければなりません
  • "exercises.concept[].prerequisites"の値に重複があってはなりません
  • "exercises.concept[].prerequisites"の値は、他のいずれかのコンセプト演習の"concepts"プロパティの値と一致しなければなりません
  • "exercises.concept[].prerequisites"の値は、その演習の"exercises.concept[].concepts"プロパティのどの値とも一致してはなりません
  • "exercises.concept[].prerequisites"の値は、いずれかのコンセプトの"concepts.slug"プロパティと一致しなければなりません
  • "exercises.concept[].concepts"と"exercises.concept[].prerequisites"の間に循環があってはなりません
  • "exercises.concept[].status"キーは任意です
  • "exercises.concept[].status"の値は文字列wip、beta、active、deprecatedのいずれかでなければなりません
  • "exercises.practice"キーは必須です
  • "exercises.practice"の値は配列でなければなりません
  • "exercises.practice[].slug"キーは必須です
  • "exercises.practice[].slug"の値は、長さ255以下のkebab-case文字列²でなければなりません
  • "exercises.practice[].slug"の値は"exercises.practice[].slug"内で一意でなければならず、"exercises.concept[].slug"に存在してはなりません
  • 文字列hello-worldである"exercises.practice[].slug"の値が、ちょうど1つだけ存在しなければなりません
  • "exercises.practice[].name"キーは必須です
  • "exercises.practice[].name"の値は、長さ255以下のTitle Case文字列³でなければなりません
  • "exercises.practice[].uuid"キーは必須です
  • "exercises.practice[].uuid"の値は、一意なバージョン4のUUID文字列⁶でなければなりません
  • 各演習の"exercises.practice[].uuid"の値は、決して変わってはなりません
  • "exercises.practice[].difficulty"キーは必須です
  • "exercises.practice[].difficulty"の値は、1以上10以下の整数でなければなりません
  • "exercises.practice[].practices"キーは必須です
  • "exercises.practice[].status"がdeprecatedでない場合、"exercises.practice[].practices"の値は空でない文字列の配列でなければなりません
  • "exercises.practice[].status"がdeprecatedの場合、"exercises.practice[].practices"の値は空の配列でなければなりません
  • "exercises.practice[].practices"の値はkebab-case文字列²でなければなりません
  • "exercises.practice[].practices"の値に重複があってはなりません
  • "exercises.practice[].practices"の値は、いずれかのコンセプトの"concepts[].slug"プロパティと一致しなければなりません
  • "exercises.practice[].practices"の値は、個々のコンセプトのslugを(すべての演習を通じて)最大10回までしか参照できません
  • "exercises.practice[].prerequisites"キーは必須です
  • "exercises.practice[].status"がdeprecatedでない場合、"exercises.practice[].prerequisites"の値は空でない文字列の配列でなければなりません
  • "exercises.practice[].status"がdeprecatedの場合、"exercises.practice[].prerequisites"の値は空の配列でなければなりません
  • "exercises.practice[].slug"がhello-worldの場合、"exercises.practice[].prerequisites"の値は空の配列でなければなりません
  • "exercises.practice[].prerequisites"の値はkebab-case文字列²でなければなりません
  • "exercises.practice[].prerequisites"の値に重複があってはなりません
  • "exercises.practice[].prerequisites"の値は、いずれかのコンセプト演習の"exercises.concept[].concepts"の値と一致しなければなりません
  • "exercises.practice[].prerequisites"の値は、いずれかのコンセプトの"concepts[].slug"プロパティと一致しなければなりません
  • "exercises.practice[].status"キーは任意です
  • "exercises.practice[].status"の値は文字列wip、beta、active、deprecatedのいずれかでなければなりません
  • "exercises.practice[].slug"がhello-worldの場合、"exercises.practice[].status"の値は、省略するか、文字列activeでなければなりません
  • "exercises.foregone"キーは任意です
  • "exercises.foregone"の値は配列でなければなりません
  • "exercises.foregone"の値はkebab-case文字列²でなければなりません
  • "exercises.foregone"の値に重複があってはなりません
  • "exercises.foregone"の値は、コンセプト演習またはプラクティス演習のどのslugとも一致してはなりません
  • "concepts"キーは必須です
  • "concepts"の値は配列でなければなりません
  • "concepts[].uuid"キーは必須です
  • "concepts[].uuid"の値は、一意なバージョン4のUUID文字列⁶でなければなりません
  • 各コンセプトの"concepts[].uuid"の値は、決して変わってはなりません
  • "concepts[].slug"キーは必須です
  • "concepts[].slug"の値は、長さ255以下のkebab-case文字列²でなければなりません
  • "concepts[].name"キーは必須です
  • "concepts[].name"の値は、長さ255以下のTitle Case文字列³でなければなりません
  • "concepts[].tags"キーは任意です
  • "concepts[].tags.any"が空である場合を除き、"concepts[].tags.all"キーは任意です
  • "concepts[].tags.all"の値は配列でなければなりません
  • "concepts[].tags.all"の値は、長さ255以下の空でないタグ⁷文字列でなければなりません
  • "concepts[].tags.all"の値に重複があってはなりません
  • "concepts[].tags.all"が空である場合を除き、"concepts[].tags.any"キーは任意です
  • "concepts[].tags.any"の値は配列でなければなりません
  • "concepts[].tags.any"の値は、長さ255以下の空でないタグ⁷文字列でなければなりません
  • "concepts[].tags.any"の値に重複があってはなりません
  • "concepts[].tags.not"キーは任意です
  • "concepts[].tags.not"の値は配列でなければなりません
  • "concepts[].tags.not"の値は、長さ255以下の空でないタグ⁷文字列でなければなりません
  • "concepts[].tags.not"の値に重複があってはなりません
  • 各"concepts"の値には、concept/<concepts.slug>/about.mdファイルが必要です。このファイルのリンティングルールは以下で説明します。
  • 各"concepts"の値には、concept/<concepts.slug>/introduction.mdファイルが必要です。このファイルのリンティングルールは以下で説明します。
  • 各"concepts"の値には、concept/<concepts.slug>/links.jsonファイルが必要です。このファイルのリンティングルールは以下で説明します。
  • "key_features"キーは任意です
  • "key_features"の値は、長さが6の配列でなければなりません
  • "key_features[].icon"キーは必須です
  • "key_features[].icon"の値は、事前定義されたアイコンの値のいずれかを使用しなければなりません
  • "key_features[].title"キーは必須です
  • "key_features[].title"の値は、長さ25以下のSentence Case文字列⁴でなければなりません
  • "key_features[].content"キーは必須です
  • "key_features[].content"の値は、長さ100以下の空でない文字列¹でなければなりません
  • "tags"キーは必須です
  • "tags"の値は文字列の配列でなければなりません
  • "tags"の値に重複があってはなりません
  • "tags"の値は、事前定義されたタグの値のいずれかを使用しなければなりません

ルール: exercises/concept/<slug>/.meta/config.jsonが有効である

  • ファイルは有効なJSONでなければなりません
  • JSONのルートはオブジェクトでなければなりません
  • "blurb"キーは必須です
  • "blurb"の値は、長さ350以下の空でない文字列¹でなければなりません
  • "source"キーは任意です
  • "source"の値は、空でない文字列¹でなければなりません
  • "source_url"キーは任意です
  • "source_url"の値はURLでなければなりません
  • "authors"キーは必須です
  • "authors"の値は空でない配列でなければなりません
  • "authors"の値は空でない文字列¹でなければなりません
  • "authors"の値に重複があってはなりません
  • "authors"の値は大文字と小文字を区別せずに扱われます
  • "contributors"キーは任意です
  • "contributors"の値は配列でなければなりません
  • "contributors"の値は空でない文字列¹でなければなりません
  • "contributors"の値に重複があってはなりません
  • "contributors"の値は大文字と小文字を区別せずに扱われます
  • ユーザーは、"authors"または"contributors"のいずれか一方の配列にのみ記載できます(重複は不可)
  • "files.solution"キーは必須です
  • "files.solution"の値は空でない配列でなければなりません
  • "files.solution"の値に重複があってはなりません
  • "files.test"キーは必須です
  • "files.test"の値は空でない配列でなければなりません
  • "files.test"の値に重複があってはなりません
  • "files.exemplar"キーは必須です
  • "files.exemplar"の値は空でない配列でなければなりません
  • "files.exemplar"の値に重複があってはなりません
  • "files.editor"キーは任意です
  • "files.editor"の値は配列でなければなりません
  • "files.editor"の値に重複があってはなりません
  • "files.invalidator"キーは任意です
  • "files.invalidator"の値は配列でなければなりません
  • "files.invalidator"の値に重複があってはなりません
  • "files.solution"にリストされているファイルは存在しなければなりません
  • "files.test"にリストされているファイルは存在しなければなりません
  • "files.exemplar"にリストされているファイルは存在しなければなりません
  • "files.editor"にリストされているファイルは存在しなければなりません
  • "files.invalidator"にリストされているファイルは存在しなければなりません
  • ファイルは、"files.solution"、"files.test"、"files.exemplar"、"files.invalidator"のいずれか1つの配列にのみ記載できます(重複は不可)
    • トラックがdまたはplsqlの場合、"files.solution"と"files.test"のファイルは重複して_もかまいません_
  • "forked_from"キーは任意です
  • "forked_from"の値は配列でなければなりません
  • "forked_from"の値は、<track-slug>/<exercise-slug>という形式の文字列でなければなりません(例: fsharp/bird-watcher)
  • "forked_from"の値は、実際に実装されている演習を参照しなければなりません
  • "forked_from"の値に重複があってはなりません
  • "language_versions"キーは任意です
  • "language_versions"の値は文字列でなければなりません
  • "representer.version"キーは任意です
  • "representer.version"の値は、1以上の整数でなければなりません
  • "icon"キーは任意です
  • "icon"の値はkebab-case文字列²でなければなりません

ルール: exercises/concept/<slug>/.docs/hints.mdが有効である

  • MarkdownはMarkdown標準に準拠しなければなりません
  • すべての見出しは## Generalまたは## X. <task>のいずれかでなければなりません。ここでXはinstructions.mdのタスク番号の見出しと一致します
  • すべてのヒントはMarkdownのリスト項目として記述しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: exercises/concept/<slug>/.docs/instructions.mdが有効である

  • MarkdownはMarkdown標準に準拠しなければなりません
  • すべてのタスクは、数字とそれに続くピリオドで始まるレベル2の見出しで始めなければなりません:## 1. Do X
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: exercises/concept/<slug>/.docs/instructions.md.tplが有効である(存在する場合)

  • 各コンセプトプレースホルダーのコンセプトは、トラックのconfig.jsonにあるいずれかのコンセプトの"concepts.slug"プロパティと一致しなければなりません。

ルール: exercises/concept/<slug>/.docs/introduction.mdが有効である

  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: exercises/practice/<slug>/.meta/config.jsonが有効である

  • ファイルは有効なJSONでなければなりません
  • JSONのルートはオブジェクトでなければなりません
  • "blurb"キーは必須です
  • "blurb"の値は、長さ350以下の空でない文字列¹でなければなりません
  • "source"キーは任意です
  • "source"の値は、空でない文字列¹でなければなりません
  • "source_url"キーは任意です
  • "source_url"の値はURLでなければなりません
  • "authors"キーは任意です
  • "authors"の値は配列でなければなりません
  • "authors"の値は空でない文字列¹でなければなりません
  • "authors"の値に重複があってはなりません
  • "authors"の値は大文字と小文字を区別せずに扱われます
  • "contributors"キーは任意です
  • "contributors"の値は配列でなければなりません
  • "contributors"の値は空でない文字列¹でなければなりません
  • "contributors"の値に重複があってはなりません
  • "contributors"の値は大文字と小文字を区別せずに扱われます
  • ユーザーは、"authors"または"contributors"のいずれか一方の配列にのみ記載できます(重複は不可)
  • "files.solution"キーは必須です
  • "files.solution"の値は空でない配列でなければなりません
  • "files.solution"の値に重複があってはなりません
  • "files.test"キーは必須です
  • "files.test"の値は空でない配列でなければなりません
  • "files.test"の値に重複があってはなりません
  • "files.example"キーは必須です
  • "files.example"の値は空でない配列でなければなりません
  • "files.example"の値に重複があってはなりません
  • "files.editor"キーは任意です
  • "files.editor"の値は配列でなければなりません
  • "files.editor"の値に重複があってはなりません
  • "files.invalidator"キーは任意です
  • "files.invalidator"の値は配列でなければなりません
  • "files.invalidator"の値に重複があってはなりません
  • "files.solution"にリストされているファイルは存在しなければなりません
  • "files.test"にリストされているファイルは存在しなければなりません
  • "files.example"にリストされているファイルは存在しなければなりません
  • "files.editor"にリストされているファイルは存在しなければなりません
  • "files.invalidator"にリストされているファイルは存在しなければなりません
  • ファイルは、"files.solution"、"files.test"、"files.example、"files.invalidator"のいずれか1つの配列にのみ記載できます(重複は不可)
    • トラックがdまたはplsqlの場合、"files.solution"と"files.test"のファイルは重複して_もかまいません_
  • "language_versions"キーは任意です
  • "language_versions"の値は文字列でなければなりません
  • "test_runner"キーは任意です
  • "test_runner"の値は真偽値でなければなりません
  • "representer.version"キーは任意です
  • "representer.version"の値は、1以上の整数でなければなりません
  • "icon"キーは任意です
  • "icon"の値はkebab-case文字列²でなければなりません

ルール: exercises/{concept|practice}/<slug>/.approaches/config.jsonが有効である

  • introduction.mdまたは兄弟ディレクトリが存在する場合を除き、このファイルの存在は任意です
  • ファイルは有効なJSONでなければなりません
  • JSONのルートはオブジェクトでなければなりません
  • "introduction.authors"キーは任意です
  • "introduction.authors"の値は配列でなければなりません
  • "introduction.authors"の値は空でない文字列¹でなければなりません
  • "introduction.authors"の値に重複があってはなりません
  • "introduction.authors"の値は大文字と小文字を区別せずに扱われます
  • "introduction.authors"の配列が空でない場合、空でないintroduction.mdファイルが存在しなければなりません
  • "introduction.contributors"キーは任意です
  • "introduction.contributors"の値は配列でなければなりません
  • "introduction.contributors"の値は空でない文字列¹でなければなりません
  • "introduction.contributors"の値に重複があってはなりません
  • "introduction.contributors"の値は大文字と小文字を区別せずに扱われます
  • "introduction.contributors"の配列が空でない場合、空でないintroduction.mdファイルが存在しなければなりません
  • ユーザーは、"introduction.authors"または"introduction.contributors"のいずれか一方の配列にのみ記載できます(重複は不可)
  • 兄弟ディレクトリ(アプローチのファイルを含む)が存在する場合を除き、"approaches"キーは任意です
  • "approaches"の値は、オブジェクトの配列でなければなりません
  • "approaches[].uuid"キーは必須です
  • "approaches[].uuid"の値は、一意なバージョン4のUUID文字列⁶でなければなりません
  • 各コンセプトの"approaches[].uuid"の値は、決して変わってはなりません
  • "approaches[].slug"キーは必須です
  • "approaches[].slug"の値は、長さ255以下のkebab-case文字列²でなければなりません
  • "approaches[].slug"の値には、対応する空でない<slug>/content.mdファイルがなければなりません
  • "approaches[].slug"の値には、対応する空でない<slug>/snippet.txtファイルがなければなりません
  • "approaches[].title"キーは必須です
  • "approaches[].title"の値は、長さ255以下のTitle Case文字列³でなければなりません
  • "approaches[].blurb"キーは必須です
  • "approaches[].blurb"の値は、長さ350以下の空でない文字列¹でなければなりません
  • "approaches[].authors"キーは必須です
  • "approaches[].authors"の値は空でない配列でなければなりません
  • "approaches[].authors"の値は空でない文字列¹でなければなりません
  • "approaches[].authors"の値に重複があってはなりません
  • "approaches[].authors"の値は大文字と小文字を区別せずに扱われます
  • "approaches[].contributors"キーは任意です
  • "approaches[].contributors"の値は配列でなければなりません
  • "approaches[].contributors"の値は空でない文字列¹でなければなりません
  • "approaches[].contributors"の値に重複があってはなりません
  • "approaches[].contributors"の値は大文字と小文字を区別せずに扱われます
  • ユーザーは、"approaches[].authors"または"approaches[].contributors"のいずれか一方の配列にのみ記載できます(重複は不可)
  • "approaches[].tags"キーは任意です
  • "approaches[].tags.any"が空である場合を除き、"approaches[].tags.all"キーは任意です
  • "approaches[].tags.all"の値は配列でなければなりません
  • "approaches[].tags.all"の値は、長さ255以下の空でないタグ⁷文字列でなければなりません
  • "approaches[].tags.all"の値に重複があってはなりません
  • "approaches[].tags.all"が空である場合を除き、"approaches[].tags.any"キーは任意です
  • "approaches[].tags.any"の値は配列でなければなりません
  • "approaches[].tags.any"の値は、長さ255以下の空でないタグ⁷文字列でなければなりません
  • "approaches[].tags.any"の値に重複があってはなりません
  • "approaches[].tags.not"キーは任意です
  • "approaches[].tags.not"の値は配列でなければなりません
  • "approaches[].tags.not"の値は、長さ255以下の空でないタグ⁷文字列でなければなりません
  • "approaches[].tags.not"の値に重複があってはなりません

ルール: exercises/{concept|practice}/<slug>/.approaches/<approach-slug>/content.mdが有効である

  • .approaches/config.jsonファイルに一致する"approaches[].slug"のエントリが存在する場合、このファイルの存在は必須です
  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: exercises/{concept|practice}/<slug>/.approaches/<approach-slug>/snippet.<snippet-extension>が有効である

  • .approaches/config.jsonファイルに一致する"approaches[].slug"のエントリが存在する場合、このファイルの存在は必須です
  • スニペットは最大8行でなければなりません
  • スニペットの拡張子は、トラックのconfig.jsonファイルにあるapproaches.snippet_extensionの値から取得します

ルール: exercises/{concept|practice}/<slug>/.articles/config.jsonが有効である

  • 兄弟ディレクトリが存在する場合を除き、このファイルの存在は任意です
  • ファイルは有効なJSONでなければなりません
  • JSONのルートはオブジェクトでなければなりません
  • 兄弟ディレクトリ(記事のファイルを含む)が存在する場合を除き、"articles"キーは任意です
  • "articles"の値は、オブジェクトの配列でなければなりません
  • "articles[].uuid"キーは必須です
  • "articles[].uuid"の値は、一意なバージョン4のUUID文字列⁶でなければなりません
  • 各コンセプトの"articles[].uuid"の値は、決して変わってはなりません
  • "articles[].slug"キーは必須です
  • "articles[].slug"の値は、長さ255以下のkebab-case文字列²でなければなりません
  • "articles[].slug"の値には、対応する空でない<slug>/content.mdファイルがなければなりません
  • "articles[].slug"の値には、対応する空でない<slug>/snippet.mdファイルがなければなりません
  • "articles[].title"キーは必須です
  • "articles[].title"の値は、長さ255以下のTitle Case文字列³でなければなりません
  • "articles[].blurb"キーは必須です
  • "articles[].blurb"の値は、長さ350以下の空でない文字列¹でなければなりません
  • "articles[].authors"キーは必須です
  • "articles[].authors"の値は空でない配列でなければなりません
  • "articles[].authors"の値は空でない文字列¹でなければなりません
  • "articles[].authors"の値に重複があってはなりません
  • "articles[].authors"の値は大文字と小文字を区別せずに扱われます
  • "articles[].contributors"キーは任意です
  • "articles[].contributors"の値は配列でなければなりません
  • "articles[].contributors"の値は空でない文字列¹でなければなりません
  • "articles[].contributors"の値に重複があってはなりません
  • "articles[].contributors"の値は大文字と小文字を区別せずに扱われます
  • ユーザーは、"articles[].authors"または"articles[].contributors"のいずれか一方の配列にのみ記載できます(重複は不可)

ルール: exercises/{concept|practice}/<slug>/.articles/<article-slug>/content.mdが有効である

  • .articles/config.jsonファイルに一致する"articles[].slug"のエントリが存在する場合、このファイルの存在は必須です
  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: exercises/{concept|practice}/<slug>/.articles/<article-slug>/snippet.mdが有効である

  • .articles/config.jsonファイルに一致する"articles[].slug"のエントリが存在する場合、このファイルの存在は必須です
  • MarkdownはMarkdown標準に準拠しなければなりません
  • スニペットは最大8行でなければなりません(先頭と末尾のコードフェンスのマーカーは無視します)

ルール: exercises/shared/.docs/debug.mdが有効である

  • このファイルの存在は任意です
  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: exercises/shared/.docs/help.mdが有効である

  • このファイルの存在は必須です
  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: exercises/shared/.docs/tests.mdが有効である

  • このファイルの存在は必須です
  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: concepts/<slug>/about.mdが有効である

  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: concepts/<slug>/introduction.mdが有効である

  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)
  • ファイルは有効なJSONでなければなりません
  • JSONのルートは配列でなければなりません
  • "[].url"プロパティは必須です
  • "[].url"の値はURLでなければなりません
  • "[].description"プロパティは必須です
  • "[].description"の値は、空でない文字列¹でなければなりません
  • "[].icon_url"プロパティは任意です
  • "[].icon_url"の値はURLでなければなりません

ルール: concept/<slug>/.meta/config.jsonが有効である

  • ファイルは有効なJSONでなければなりません
  • JSONのルートはオブジェクトでなければなりません
  • "blurb"キーは必須です
  • "blurb"の値は、長さ350以下の空でない文字列¹でなければなりません
  • "authors"キーは必須です
  • "authors"の値は配列でなければなりません
  • "authors"の値は空でない文字列¹でなければなりません
  • "authors"の値に重複があってはなりません
  • "authors"の値は大文字と小文字を区別せずに扱われます
  • "contributors"キーは任意です
  • "contributors"の値は配列でなければなりません
  • "contributors"の値は空でない文字列¹でなければなりません
  • "contributors"の値に重複があってはなりません
  • "contributors"の値は大文字と小文字を区別せずに扱われます
  • ユーザーは、"authors"または"contributors"のいずれか一方の配列にのみ記載できます(重複は不可)

ルール: docs/ABOUT.mdが有効である

  • このファイルの存在は必須です
  • このファイルの内容は空であってはなりません
  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: docs/INSTALLATION.mdが有効である

  • このファイルの存在は必須です
  • このファイルの内容は空であってはなりません
  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: docs/LEARNING.mdが有効である

  • このファイルの存在は必須です
  • このファイルの内容は空であってはなりません
  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: docs/RESOURCES.mdが有効である

  • このファイルの存在は必須です
  • このファイルの内容は空であってはなりません
  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

ルール: docs/SNIPPET.txtが有効である

  • このファイルの存在は必須です
  • このファイルの内容は空であってはなりません

ルール: docs/TESTS.mdが有効である

  • このファイルの存在は必須です
  • このファイルの内容は空であってはなりません
  • MarkdownはMarkdown標準に準拠しなければなりません
  • リンクは絶対リンクでなければなりません(相対リンクは使用できません)

用語集

  1. 空でない文字列: 少なくとも1つの空白以外の文字を含む文字列。

  2. kebab-case文字列: [a-z0-9]の範囲の文字のみを含み、任意でダッシュで区切られる文字列(例: "two-fer")。次の正規表現に一致しなければなりません: ^[a-z0-9]+(-[a-z0-9]+)*$

  3. Title Case文字列: 以下のChicago Manual of Styleのガイドラインに従う空でない文字列:

    • タイトルとサブタイトルの最初と最後の単語を大文字で始めます。
    • 「主要な」単語(名詞、代名詞、動詞、形容詞、副詞、および一部の接続詞)を大文字で始めます。
    • 接続詞 and、but、for、or、nor は小文字にします。
    • 冠詞 the、a、an は小文字にします。
    • 前置詞は、長さにかかわらず小文字にします。ただし、強調されている場合、副詞的または形容詞的に使われている場合、あるいは接続詞として使われている場合を除きます。
    • 単語 to と as は小文字にします。
    • ラテン語の種名の2番目の部分は小文字にします。
  4. Sentence Case文字列: 以下のガイドラインに従う空でない文字列:

    • 文の最初の単語、および固有名詞や、より具体的なルールで求められるその他の単語を大文字で始めます。
  5. 有効なfilesパターン: 演習で使用されるファイルの位置を、その演習のディレクトリからの相対パスで指定する、空でない文字列¹。パターンでは、次のプレースホルダーのいずれかを使用できます:

    • %{kebab_slug}: kebab-caseの演習slug(例: bit-manipulation)
    • %{snake_slug}: snake_caseの演習slug(例: bit_manipulation)
    • %{camel_slug}: camelCaseの演習slug(例: bitManipulation)
    • %{pascal_slug}: PascalCaseの演習slug(例: BitManipulation)
  6. 一意なバージョン4のUUID文字列: 次の条件をすべて満たす文字列:

    • 特定のExercismトラックのトラックレベルのconfig.jsonファイルに1回だけ存在します
    • 他のどのExercismトラックのトラックレベルのconfig.jsonファイルにも存在しません
    • https://github.com/exercism/problem-specifications のどのcanonical-data.jsonファイルにも存在しません
    • Exercismの他のどこにも存在しません
    • 次の正規表現に一致します:
    ^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
    

    たとえば、以下のUUIDは正しい形式です:

    d334ffe3-657e-4725-a950-290b284b6d9f
    

    適切なUUIDを生成するには、configlet uuidを実行します。

  7. 有効なアナライザーのtag: <category>:<thing>という形式の空でない文字列¹。 <category>の値は、次のいずれかでなければなりません:

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

<thing>の値は、空でない文字列¹でなければなりません。