configlet lint


configlet 最主要的用途是 Lint 檢查:檢查某個 track 的設定檔結構是否正確,包括語法與語意兩方面。設定有誤的 track 可能無法正確同步、在網站上顯示異常,或帶給使用者不佳的體驗,因此 configlet 的檢查機制對於維護 Exercism 的完整性扮演著重要角色。

用法

你可以使用 lint 指令來檢查一個 track。

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]

規則

以下是會檢查的 Lint 規則。

規則:必備檔案皆存在

Lint 工具應檢查是否所有必備檔案都存在。不屬於個別練習的必備檔案包括:

  • 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"(不得重疊)
    • 若 track 為 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 的整數
  • 若該 track 有一個以上的 approach,則 "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" 值必須是唯一的 version 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" 值必須是非空的字串陣列,但恰好有一個練習例外,其值_可以_是空陣列
  • 若 "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" 中
  • 必須恰好有一個 "exercises.practice[].slug" 值為字串 hello-world
  • "exercises.practice[].name" 鍵為必填
  • "exercises.practice[].name" 值必須是長度 <= 255 的 Title Case 字串³
  • "exercises.practice[].uuid" 鍵為必填
  • "exercises.practice[].uuid" 值必須是唯一的 version 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" 值必須是唯一的 version 4 UUID 字串⁶
  • 每個概念的 "concepts[].uuid" 值永遠不得變更
  • "concepts[].slug" 鍵為必填
  • "concepts[].slug" 值必須是長度 <= 255 的 kebab-case 字串²
  • "concepts[].name" 鍵為必填
  • "concepts[].name" 值必須是長度 <= 255 的 Title Case 字串³
  • "concepts[].tags" 鍵為選填
  • "concepts[].tags.all" 鍵為選填,除非 "concepts[].tags.any" 為空
  • "concepts[].tags.all" 值必須是陣列
  • "concepts[].tags.all" 值必須是長度 <= 255 的非空白標籤⁷字串
  • "concepts[].tags.all" 值不得有重複
  • "concepts[].tags.any" 鍵為選填,除非 "concepts[].tags.all" 為空
  • "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 檔案。此檔案的 Lint 規則詳述於下。
  • 每個 "concepts" 值都必須有一個 concept/<concepts.slug>/introduction.md 檔案。此檔案的 Lint 規則詳述於下。
  • 每個 "concepts" 值都必須有一個 concept/<concepts.slug>/links.json 檔案。此檔案的 Lint 規則詳述於下。
  • "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"(不得重疊)
    • 若 track 為 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 標準
  • 所有任務都必須以第二層標題開頭,且該標題為一個數字後接一個句點:## 1. Do X
  • 連結必須是絕對連結(不允許相對連結)

規則:exercises/concept/<slug>/.docs/instructions.md.tpl 有效(若存在)

  • 每個概念佔位符的概念都必須符合該 track 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"(不得重疊)
    • 若 track 為 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" 鍵為選填,除非存在同層目錄(其中包含該 approach 的檔案)
  • "approaches" 值必須是物件陣列
  • "approaches[].uuid" 鍵為必填
  • "approaches[].uuid" 值必須是唯一的 version 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.all" 鍵為選填,除非 "approaches[].tags.any" 為空
  • "approaches[].tags.all" 值必須是陣列
  • "approaches[].tags.all" 值必須是長度 <= 255 的非空白標籤⁷字串
  • "approaches[].tags.all" 值不得有重複
  • "approaches[].tags.any" 鍵為選填,除非 "approaches[].tags.all" 為空
  • "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 行
  • 程式碼片段的副檔名取自該 track config.json 檔中的 approaches.snippet_extension 值

規則:exercises/{concept|practice}/<slug>/.articles/config.json 有效

  • 此檔案為選填,除非存在同層目錄
  • 檔案必須是有效的 JSON
  • JSON 根必須是物件
  • "articles" 鍵為選填,除非存在同層目錄(其中包含該 article 的檔案)
  • "articles" 值必須是物件陣列
  • "articles[].uuid" 鍵為必填
  • "articles[].uuid" 值必須是唯一的 version 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. 非空白字串:至少包含一個非空白字元的字串。

  2. kebab-case 字串:只包含 [a-z0-9] 範圍內字元的字串,可選擇以連字號分隔(例如 "two-fer")。它必須符合以下正規表達式:^[a-z0-9]+(-[a-z0-9]+)*$

  3. Title Case 字串:遵循以下 The Chicago Manual of Style 準則的非空白字串:

    • 標題與副標題的第一個和最後一個字要大寫。
    • 「主要」詞彙(名詞、代名詞、動詞、形容詞、副詞,以及部分連接詞)要大寫。
    • 連接詞 and、but、for、or 和 nor 要小寫。
    • 冠詞 the、a 和 an 要小寫。
    • 介系詞一律小寫,不論長度,除非它們被強調、用作副詞或形容詞,或用作連接詞。
    • to 和 as 要小寫。
    • 拉丁物種名稱的第二部分要小寫。
  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. 唯一的 version 4 UUID 字串:符合下列所有條件的字串:

    • 它在某個 Exercism track 的 track 層級 config.json 檔中只出現一次
    • 它不存在於任何其他 Exercism track 的 track 層級 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
    

    你可以執行 configlet uuid 來產生合適的 UUID。

  7. 有效的 analyzer tag:格式為 <category>:<thing> 的非空白字串¹。 <category> 值必須是下列其中之一:

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

<thing> 值必須是非空白字串¹。