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" має бути непорожнім рядком тексту (англ. string)¹ довжиною <= 255
  • Ключ "slug" є обовʼязковим
  • Значення "slug" має бути рядком тексту у форматі kebab-case² довжиною <= 255
  • Ключ "active" є обовʼязковим
  • Значення "active" має бути булевим значенням (англ. Boolean)
  • Ключ "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" (без перетинів)
    • Якщо трек - d або plsql, файли з "files.solution" і "files.test" можуть перетинатися
    • Файли з "files.example і "files.exemplar" можуть перетинатися
  • Ключ "test_runner.average_run_time" є обовʼязковим, якщо "status.test_runner" дорівнює true
  • Значення "test_runner.average_run_time" має бути цілим числом > 0
  • Ключ "approaches.snippet_extension" є обовʼязковим, якщо в треку є один або більше підходів
  • Значення "approaches.snippet_extension" має бути непорожнім рядком тексту¹
  • Ключ "exercises" є обовʼязковим
  • Ключ "exercises.concept" є обовʼязковим
  • Значення "exercises.concept" має бути масивом
  • Ключ "exercises.concept[].slug" є обовʼязковим
  • Значення "exercises.concept[].slug" має бути рядком тексту у форматі kebab-case² довжиною <= 255
  • Значення "exercises.concept[].slug" має бути унікальним серед "exercises.concept[].slug" і не може траплятися в "exercises.practice[].slug"
  • Ключ "exercises.concept[].name" є обовʼязковим
  • Значення "exercises.concept[].name" має бути рядком тексту у стилі Title Case³ довжиною <= 255
  • Ключ "exercises.concept[].uuid" є обовʼязковим
  • Значення "exercises.concept[].uuid" має бути унікальним рядком тексту UUID версії 4⁶
  • Значення "exercises.concept[].uuid" для кожної вправи ніколи не має змінюватися
  • Ключ "exercises.concept[].concepts" є обовʼязковим
  • Значення "exercises.concept[].concepts" має бути непорожнім масивом рядків тексту, якщо "exercises.concept[].status" не дорівнює deprecated
  • Значення "exercises.concept[].concepts" має бути порожнім масивом, якщо "exercises.concept[].status" дорівнює deprecated
  • Значення "exercises.concept[].concepts" мають бути рядками тексту у форматі kebab-case²
  • Значення "exercises.concept[].concepts" не мають містити дублікатів
  • Значення "exercises.concept[].concepts" не мають бути у властивості "concepts" жодної іншої концептуальної вправи
  • Значення "exercises.concept[].concepts" мають відповідати властивості "concepts.slug" однієї з концепцій
  • Ключ "exercises.concept[].prerequisites" є обовʼязковим
  • Значення "exercises.concept[].prerequisites" має бути непорожнім масивом рядків тексту, якщо "exercises.concept[].status" не дорівнює deprecated, окрім рівно однієї вправи, якій дозволено мати порожній масив як значення
  • Значення "exercises.concept[].prerequisites" має бути порожнім масивом, якщо "exercises.concept[].status" дорівнює deprecated
  • Значення "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" має бути рядком тексту у форматі kebab-case² довжиною <= 255
  • Значення "exercises.practice[].slug" має бути унікальним серед "exercises.practice[].slug" і не може траплятися в "exercises.concept[].slug"
  • Має бути рівно одне значення "exercises.practice[].slug", яке дорівнює рядку тексту hello-world
  • Ключ "exercises.practice[].name" є обовʼязковим
  • Значення "exercises.practice[].name" має бути рядком тексту у стилі Title Case³ довжиною <= 255
  • Ключ "exercises.practice[].uuid" є обовʼязковим
  • Значення "exercises.practice[].uuid" має бути унікальним рядком тексту UUID версії 4⁶
  • Значення "exercises.practice[].uuid" для кожної вправи ніколи не має змінюватися
  • Ключ "exercises.practice[].difficulty" є обовʼязковим
  • Значення "exercises.practice[].difficulty" має бути цілим числом >= 1 і <= 10
  • Ключ "exercises.practice[].practices" є обовʼязковим
  • Значення "exercises.practice[].practices" має бути непорожнім масивом рядків тексту, якщо "exercises.practice[].status" не дорівнює deprecated
  • Значення "exercises.practice[].practices" має бути порожнім масивом, якщо "exercises.practice[].status" дорівнює deprecated
  • Значення "exercises.practice[].practices" мають бути рядками тексту у форматі kebab-case²
  • Значення "exercises.practice[].practices" не мають містити дублікатів
  • Значення "exercises.practice[].practices" мають відповідати властивості "concepts[].slug" однієї з концепцій
  • Значення "exercises.practice[].practices" мають посилатися на слаг окремої концепції не більше ніж 10 разів (у всіх вправах разом)
  • Ключ "exercises.practice[].prerequisites" є обовʼязковим
  • Значення "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" мають бути рядками тексту у форматі 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" не мають збігатися зі слагами жодної концептуальної чи практичної вправи
  • Ключ "concepts" є обовʼязковим
  • Значення "concepts" має бути масивом
  • Ключ "concepts[].uuid" є обовʼязковим
  • Значення "concepts[].uuid" має бути унікальним рядком тексту UUID версії 4⁶
  • Значення "concepts[].uuid" для кожної концепції ніколи не має змінюватися
  • Ключ "concepts[].slug" є обовʼязковим
  • Значення "concepts[].slug" має бути рядком тексту у форматі kebab-case² довжиною <= 255
  • Ключ "concepts[].name" є обовʼязковим
  • Значення "concepts[].name" має бути рядком тексту у стилі Title Case³ довжиною <= 255
  • Ключ "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. Правила лінтування для цього файлу описано нижче.
  • Кожне значення "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" має бути рядком тексту у стилі Sentence Case⁴ довжиною <= 25
  • Ключ "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" (без перетинів)
    • Якщо трек - 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 (якщо наявний)

Правило: коректність файлу 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" (без перетинів)
    • Якщо трек - 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" має бути унікальним рядком тексту UUID версії 4⁶
  • Значення "approaches[].uuid" для кожної концепції ніколи не має змінюватися
  • Ключ "approaches[].slug" є обовʼязковим
  • Значення "approaches[].slug" має бути рядком тексту у форматі kebab-case² довжиною <= 255
  • Значення "approaches[].slug" має мати відповідний непорожній файл <slug>/content.md
  • Значення "approaches[].slug" має мати відповідний непорожній файл <slug>/snippet.txt
  • Ключ "approaches[].title" є обовʼязковим
  • Значення "approaches[].title" має бути рядком тексту у стилі Title Case³ довжиною <= 255
  • Ключ "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 рядків
  • Розширення сніпета береться зі значення approaches.snippet_extension у файлі config.json треку

Правило: коректність файлу exercises/{concept|practice}/<slug>/.articles/config.json

  • Наявність файлу необовʼязкова, окрім випадку, коли є сусідній каталог
  • Файл має бути коректним JSON
  • Корінь JSON має бути обʼєктом
  • Ключ "articles" необовʼязковий, окрім випадку, коли наявний сусідній каталог (який містить файли статті)
  • Значення "articles" має бути масивом обʼєктів
  • Ключ "articles[].uuid" є обовʼязковим
  • Значення "articles[].uuid" має бути унікальним рядком тексту UUID версії 4⁶
  • Значення "articles[].uuid" для кожної концепції ніколи не має змінюватися
  • Ключ "articles[].slug" є обовʼязковим
  • Значення "articles[].slug" має бути рядком тексту у форматі kebab-case² довжиною <= 255
  • Значення "articles[].slug" має мати відповідний непорожній файл <slug>/content.md
  • Значення "articles[].slug" має мати відповідний непорожній файл <slug>/snippet.md
  • Ключ "articles[].title" є обовʼязковим
  • Значення "articles[].title" має бути рядком тексту у стилі Title Case³ довжиною <= 255
  • Ключ "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: непорожній рядок тексту, який відповідає наведеним нижче настановам Chicago Manual of Style:

    • Пишіть з великої літери перше й останнє слово заголовків і підзаголовків.
    • Пишіть з великої літери «головні» слова (іменники, займенники, дієслова, прикметники, прислівники та деякі сполучники).
    • Пишіть з малої літери сполучники and, but, for, or та nor.
    • Пишіть з малої літери артиклі the, a та an.
    • Пишіть з малої літери прийменники, незалежно від довжини, крім випадків, коли на них падає наголос, коли вони вживаються як прислівники чи прикметники або як сполучники.
    • Пишіть з малої літери слова to та as.
    • Пишіть з малої літери другу частину латинських назв видів.
  4. Рядок тексту у стилі Sentence Case: непорожній рядок тексту, який відповідає наведеним нижче настановам:

    • Пишіть з великої літери перше слово речення, а також власні назви та інші слова, якщо цього вимагає конкретніше правило.
  5. Коректний шаблон files: непорожній рядок тексту¹, який задає розташування файлу, використаного у вправі, відносно каталогу вправи. Шаблон може використовувати один із таких заповнювачів:

    • %{kebab_slug}: слаг вправи у kebab-case (наприклад, bit-manipulation)
    • %{snake_slug}: слаг вправи у snake_case (наприклад, bit_manipulation)
    • %{camel_slug}: слаг вправи у camelCase (наприклад, bitManipulation)
    • %{pascal_slug}: слаг вправи у PascalCase (наприклад, BitManipulation)
  6. Унікальний рядок тексту UUID версії 4: рядок тексту, який задовольняє всі ці умови:

    • Він трапляється лише один раз у файлі config.json рівня треку для конкретного треку Exercism
    • Він не трапляється у файлі config.json рівня треку жодного іншого треку Exercism
    • Він не трапляється в жодному файлі canonical-data.json у https://github.com/exercism/problem-specifications
    • Він не трапляється більше ніде на 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> має бути непорожнім рядком тексту¹.