Файл config.json описує конфігурацію треку. Він містить важливу інформацію, як-от вправи та концепції треку.
Наведені нижче властивості верхнього рівня містять загальні метадані треку:
language: мова треку (наприклад, "C#"). Її довжина має бути <= 255. (обовʼязково)slug: мова треку як рядок тексту (англ. string) у нижньому регістрі з дефісами (kebab-case) (наприклад, "csharp"). Його довжина має бути <= 255. (обовʼязково)active: boolean-значення, яке вказує, чи активний трек (тобто чи можуть студенти приєднатися до треку на сайті) (обовʼязково)blurb: короткий опис мови. Його довжина має бути <= 400. (обовʼязково)version: версія файлу config.json (наразі фіксована на 3) (обовʼязково)online_editor: обʼєкт, що описує налаштування, які використовує онлайн-редактор: (обовʼязково)
indent_style: або "space", або "tab" (обовʼязково)indent_size: розмір відступу як ціле число (наприклад, 4) (обовʼязково)highlightjs_language: ідентифікатор мови для Highlight.js (див. повний список ідентифікаторів) (необовʼязково)status: обʼєкт, що описує, які можливості v3 слід увімкнути: (обовʼязково)
concept_exercises: boolean-значення, яке вказує, чи створено концептуальні вправи (обовʼязково). Коли true, інтерфейс сайту Exercism змінюється, показуючи, що для треку доступні концептуальні вправи.test_runner: boolean-значення, яке вказує, чи реалізовано test runner (обовʼязково). Коли true, ми пропускаємо подані рішення через нашу інфраструктуру тестування й показуємо результати на сайті. Сайт також дає студентам змогу запустити тестування просто з онлайн-редактора.representer: boolean-значення, яке вказує, чи реалізовано representer (обовʼязково)analyzer: boolean-значення, яке вказує, чи реалізовано analyzer (обовʼязково)files: шаблони розташування файлів, які використовуються у вправі, відносно каталогу вправи. (необовʼязково)
solution: шаблон файлів заготовки реалізації (необовʼязково)test: шаблон файлів тестів (необовʼязково)example: шаблон файлів прикладу реалізації (необовʼязково)exemplar: шаблон файлів зразкової реалізації (необовʼязково)editor: додаткові шаблони файлів редактора, доступних лише для читання (необовʼязково)test_runner: обʼєкт, що описує test runner треку (якщо він є): (обовʼязково, якщо status.test_runner має значення true)
average_run_time: ціле number-значення, яке задає кількість секунд, що test runner у середньому витрачає на запуск (наприклад, 4) (обовʼязково, якщо status.test_runner має значення true)approaches: обʼєкт із метаданими про підходи треку: (обовʼязково, якщо трек має якісь підходи)
snippet_extension: значення у вигляді рядка тексту, яке використовується як розширення файлу сніпета (наприклад, rb) (обовʼязково, якщо трек має якісь підходи)Цей ключ використовується, щоб указати розташування файлів у межах усього треку. Замість того щоб мейнтейнери вручну задавали ключ files у файлах config.json вправ, configlet може автоматично заповнювати його за цими загальнотрековими шаблонами.
Шаблони файлів, визначені в обʼєкті files, підтримують такі заповнювачі:
%{kebab_slug}: slug вправи у kebab-case (наприклад, bit-manipulation)%{snake_slug}: slug вправи у snake_case (наприклад, bit_manipulation)%{camel_slug}: slug вправи у camelCase (наприклад, bitManipulation)%{pascal_slug}: slug вправи у PascalCase (наприклад, BitManipulation)Підтримку буде додано до configlet, щоб використовувати ці шаблони для заповнення ключа files у файлі .meta/config.json вправи.
{
"language": "C#",
"slug": "csharp",
"active": true,
"status": {
"concept_exercises": true,
"test_runner": true,
"representer": false,
"analyzer": false
},
"blurb": "C# is a modern, object-oriented language with lots of great features, such as type-inference and async/await. The tooling is excellent, and there is extensive, well-written documentation.",
"version": 3,
"online_editor": {
"indent_style": "space",
"indent_size": 4,
"highlightjs_language": "csharp"
},
"test_runner": {
"average_run_time": 2
},
"files": {
"solution": [
"%{pascal_slug}.cs"
],
"test": [
"%{pascal_slug}Tests.cs"
],
"example": [
".meta/Example.cs"
],
"exemplar": [
".meta/Exemplar.cs"
]
}
}
Ключ exercises верхнього рівня є обʼєктом із трьома можливими ключами:
concept: це масив, що перелічує концептуальні вправи трекуpractice: це масив, що перелічує практичні вправи трекуforegone: це масив, що перелічує slug вправ, які трек не впроваджуватимеКожна концептуальна вправа є елементом масиву exercises.concept.
На сайті вправи впорядковано в тому самому порядку, у якому вони перелічені в цьому файлі, і він має відповідати типовому порядку їх розвʼязування.
Концептуальну вправу складають такі поля:
uuid: UUID версії 4, який однозначно ідентифікує вправу. UUID має бути унікальним як у межах треку, так і в межах усіх треків, і ніколи не повинен змінюватисяslug: slug вправи, тобто рядок тексту в нижньому регістрі з дефісами. Slug має бути унікальним серед усіх slug концептуальних і практичних вправ у межах треку. Його довжина має бути <= 255.name: назва вправи. Її довжина має бути <= 255.concepts: масив slug концепцій, яких навчає ця концептуальна вправаprerequisites: масив slug концепцій, які мають бути розблоковані, перш ніж студент зможе почати цю вправуstatus (необовʼязково): статус вправи, один із "wip", "beta", "active" або "deprecated"; якщо його не вказано, типово "active"
wip: вправа в процесі роботи, ще не готова для загального використання. Вправи з цим тегом не показуватимуть студентам в інтерфейсі й не використовуватимуть у логіці розблокування. Їх можуть бачити мейнтейнери.beta: позначає активні вправи, які є новими й щодо яких ми хотіли б отримати відгук. Для таких вправ ми показуємо на сайті мітку beta із закликом до дії «Будь ласка, дайте нам відгук».active: звичайний стан активних вправdeprecated: вправи, які більше не показують студентам, які їх не почали (на цьому етапі вони недоступні). Докладніше див. у розділі Застарілі вправи.{
"exercises": {
"concept": [
{
"slug": "cars-assemble",
"name": "Cars, Assemble!",
"uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
"concepts": [
"if-statements",
"numbers"
],
"prerequisites": [
"basics"
]
},
...
]
}
}
{
"exercises": {
"concept": [
{
"slug": "cars-assemble",
"name": "Cars, Assemble!",
"uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
"concepts": [
"if-statements",
"numbers"
],
"prerequisites": [
"basics"
],
"status": "wip"
},
...
]
}
}
Кожна практична вправа є елементом масиву exercises.practice. Практичну вправу складають такі поля:
uuid: UUID версії 4, який однозначно ідентифікує вправу. UUID має бути унікальним як у межах треку, так і в межах усіх треків, і ніколи не повинен змінюватисяslug: slug вправи, тобто рядок тексту в нижньому регістрі з дефісами. Slug має бути унікальним серед усіх slug концептуальних і практичних вправ у межах треку. Його довжина має бути <= 255.name: назва вправи. Її довжина має бути <= 255.practices: масив slug концепцій, які вправа допомагає студентам відпрацюватиprerequisites: масив slug концепцій, які мають бути розблоковані, перш ніж студент зможе почати вправуdifficulty: число, що вказує складність вправи. Число має бути в діапазоні від 1 (найлегша) до 10 (найскладніша). Сайт тлумачить складність так:
status (необовʼязково): статус вправи, один із "wip", "beta", "active" або "deprecated"; якщо його не вказано, типово "active"
wip: вправа в процесі роботи, ще не готова для загального використання. Вправи з цим тегом не показуватимуть студентам в інтерфейсі й не використовуватимуть у логіці розблокування. Їх можуть бачити мейнтейнери.beta: позначає активні вправи, які є новими й щодо яких ми хотіли б отримати відгук. Для таких вправ ми показуємо на сайті мітку beta із закликом до дії «Будь ласка, дайте нам відгук»active: звичайний стан активних вправdeprecated: вправи, які більше не показують студентам, які їх не почали (на цьому етапі вони недоступні).«Рекомендований порядок» практичних вправ на сайті відповідає порядку вправ у масиві practice.
{
"exercises": {
"practice": [
{
"slug": "leap",
"name": "Leap",
"uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
"practices": [
"if-statements",
"numbers",
"operator-precedence"
],
"prerequisites": [
"if-statements",
"numbers"
],
"difficulty": 1
},
...
]
}
}
{
"exercises": {
"practice": [
{
"slug": "leap",
"name": "Leap",
"uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
"practices": [
"if-statements",
"numbers",
"operator-precedence"
],
"prerequisites": [
"if-statements",
"numbers"
],
"difficulty": 1,
"status": "beta"
},
...
]
}
}
Якщо трек знає, що не хоче впроваджувати вправу, визначену в репозиторії Problem Specifications, slug цієї вправи можна додати до ключа exercises.foregone. configlet ігноруватиме відкинуті вправи, коли виводитиме невпроваджені вправи треку.
Причинами, чому трек може не хотіти впроваджувати вправу, можуть бути:
{
"exercises": {
"foregone": [
"lens-person"
]
}
}
Кожна концепція є елементом масиву concepts верхнього рівня. Концепцію складають такі поля:
uuid: UUID версії 4, який однозначно ідентифікує концепцію. UUID має бути унікальним як у межах треку, так і в межах усіх треків, і ніколи не повинен змінюватисяslug: slug концепції, тобто рядок тексту в нижньому регістрі з дефісами. Slug має бути унікальним серед усіх концепцій у межах треку. Його довжина має бути <= 255.name: назва концепції. Її довжина має бути <= 255.tags: укажіть умови, за яких рішення повʼязують із підходом. (необовʼязково)
all: масив тегів, які всі мають бути присутні в рішенні (необовʼязково, якщо any не містить елементів)any: масив тегів, з яких принаймні один має бути присутній у рішенні (необовʼязково, якщо all не містить елементів)not: жоден із тегів не має бути присутній у рішенні (необовʼязково){
"concepts": [
{
"uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
"slug": "numbers",
"name": "Numbers",
"tags": {
"all": [
"concept:number"
]
}
}
]
}
Ключові можливості мови стисло описують найважливіші її можливості. Вони покликані показати потенційним студентам цікавіші можливості мови. У заголовках варто прагнути якнайменше технічного жаргону, зважаючи на те, що студенти можуть бути не знайомі з тим, що означає жаргон, специфічний для мови, перш ніж почнуть її вивчати.
Ключові можливості задають у полі key_features верхнього рівня, яке визначене як масив обʼєктів із такими полями:
title: стислий заголовок ключової можливості. Його довжина має бути <= 25. Markdown не підтримується.content: опис ключової можливості. Його довжина має бути <= 100. Markdown не підтримується.icon: іконка для показу цієї можливості. Можна вибрати іконку, яка видається доречною, незалежно від її назви. Можна використовувати такі іконки:
communityconcurrencycross-platformdocumentationdynamically-typedeasyembeddableevolvingexpressiveextensiblefastfunfunctionalgarbage-collectedgeneral-purposehomoiconicimmutableinteractiveinteropmulti-paradigmportablepowerfulproductivesafescientificsmallstablestatically-typedtoolingwebwidely-usedЯкий вигляд мають ці іконки, можна подивитися в розділі з іконками ключових можливостей.
Потрібно вказати рівно 6 ключових можливостей.
{
"key_features": [
{
"title": "Fault-tolerant",
"content": "Elixir runs on the Erlang VM, known for running low-latency, distributed and fault-tolerant systems.",
"icon": "safe"
},
...
],
}
Треки можна позначати тегами, що дає змогу шукати треки з певною комбінацією тегів.
Трек має вибирати свої теги, виходячи із загального використання мови. Наприклад, уявімо студента, який думає: «Хочу займатися машинним навчанням, яку мову вибрати?» або «Хочу вивчати функціональне програмування, яку мову обрати?». Якщо мова добре підходить для цього, додаймо їй цей тег. Якщо мова підтримує деякі функціональні ідеї, але їх рідко використовують, або машинним навчанням нею займається лише кілька людей, і це рідкість, то такі теги не додаваймо.
Теги задають у полі tags верхнього рівня, яке визначене як масив рядків тексту. Можна використовувати такі теги (згруповані за категоріями):
paradigm/array: мова є мовою масивного програмуванняparadigm/declarative: мова підтримує декларативний стиль програмуванняparadigm/functional: мова підтримує функціональний стиль програмуванняparadigm/imperative: мова підтримує імперативний стиль програмуванняparadigm/logic: мова підтримує логічний стиль програмуванняparadigm/object_oriented: мова підтримує обʼєктно-орієнтований стиль програмуванняparadigm/procedural: мова підтримує процедурний стиль програмуванняparadigm/stack-oriented: мова підтримує стек-орієнтований стиль програмуванняtyping/static: мова використовує статичну типізаціюtyping/gradual: мова використовує поступову типізаціюtyping/dynamic: мова використовує динамічну типізаціюtyping/strong: мова використовує сильну типізаціюtyping/weak: мова використовує слабку типізаціюexecution_mode/compiled: код спершу компілюється, а вже потім виконуєтьсяexecution_mode/interpreted: код інтерпретується безпосередньоplatform/windows: працює у Windowsplatform/mac: працює на Macplatform/linux: працює у Linuxplatform/ios: працює на iOSplatform/android: працює на Androidplatform/web: працює у браузеріruntime/standalone_executable: працює як окремий виконуваний файлruntime/language_specific: працює на середовищі виконання, специфічному для мовиruntime/clr: працює на Common Language Runtime (.NET)runtime/jvm: працює на JVM (Java)runtime/beam: працює на BEAM (Erlang)runtime/wasmtime: працює на Wasmtime (WebAssembly)used_for/artificial_intelligence: штучний інтелектused_for/backends: Backendsused_for/cross_platform_development: кросплатформна розробкаused_for/embedded_systems: вбудовані системиused_for/financial_systems: фінансові системиused_for/frontends: Frontendsused_for/games: ігриused_for/guis: графічні інтерфейси користувача (GUI)used_for/mobile: мобільні застосункиused_for/robotics: робототехнікаused_for/scientific_calculations: наукові обчисленняused_for/scripts: скриптиused_for/web_development: веброзробкаЗауважмо, що цілком нормально включати кілька тегів з однієї категорії.
Приклад
{
"tags": [
"paradigm/declarative",
"paradigm/functional",
"paradigm/object_oriented",
"platform/linux",
"platform/windows",
"runtime/jvm"
]
}
Ось приклад того, як може мати вигляд коректний файл config.json:
{
"language": "C#",
"slug": "csharp",
"active": true,
"status": {
"concept_exercises": true,
"test_runner": true,
"representer": false,
"analyzer": false
},
"blurb": "C# is a modern, object-oriented language with lots of great features, such as type-inference and async/await. The tooling is excellent, and there is extensive, well-written documentation.",
"version": 3,
"online_editor": {
"indent_style": "space",
"indent_size": 4,
"highlightjs_language": "csharp"
},
"test_runner": {
"average_run_time": 2
},
"files": {
"solution": [
"%{pascal_slug}.cs"
],
"test": [
"%{pascal_slug}Tests.cs"
],
"example": [
".meta/Example.cs"
],
"exemplar": [
".meta/Exemplar.cs"
]
},
"exercises": {
"concept": [
{
"slug": "lucians-luscious-lasagna",
"name": "Lucian's Luscious Lasagna",
"uuid": "7d358894-4fbd-4c91-b49f-d68f1c5aa6bc",
"concepts": [
"basics"
],
"prerequisites": []
},
{
"slug": "cars-assemble",
"name": "Cars, Assemble!",
"uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
"concepts": [
"if-statements",
"numbers"
],
"prerequisites": [
"basics"
],
"status": "wip"
}
],
"practice": [
{
"slug": "hello-world",
"name": "Hello, World!",
"uuid": "6c88f46b-5acb-4fae-a6ec-b48ae3f8168f",
"practices": [
"strings"
],
"prerequisites": [
"basics"
],
"difficulty": 1
},
{
"slug": "leap",
"name": "Leap",
"uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
"practices": [
"if-statements",
"numbers",
"operator-precedence"
],
"prerequisites": [
"if-statements",
"numbers"
],
"difficulty": 2,
"status": "beta"
}
]
},
"concepts": [
{
"uuid": "2eb4a463-355f-46ef-ac55-a75ec5afdf86",
"slug": "basics",
"name": "Basics"
},
{
"uuid": "4466e33e-dcd2-4b1f-9d9d-2c4315bf5188",
"slug": "if-statements",
"name": "If Statements"
},
{
"uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
"slug": "numbers",
"name": "Numbers"
},
{
"uuid": "7a86561d-173b-45c0-a53c-1ffd7b9ff259",
"slug": "strings",
"name": "Strings"
}
],
"key_features": [
{
"title": "Modern",
"content": "C# is a modern, fast-evolving language.",
"icon": "expressive"
},
{
"title": "Cross-platform",
"content": "C# runs on almost any platform and chipset.",
"icon": "cross-platform"
},
{
"title": "Multi-paradigm",
"content": "C# is primarily an object-oriented language, but also has lots of functional features.",
"icon": "multi-paradigm"
},
{
"title": "General purpose",
"content": "C# can be used for a wide variety of workloads, like websites, console applications, and even games.",
"icon": "general-purpose"
},
{
"title": "Tooling",
"content": "C# has excellent tooling, with linting and advanced refactoring options built-in.",
"icon": "tooling"
},
{
"title": "Documentation",
"content": "Documentation is excellent and exhaustive, making it easy to get started with C#.",
"icon": "documentation"
}
],
"tags": [
"paradigm/declarative",
"paradigm/functional",
"paradigm/object_oriented",
"platform/linux",
"platform/windows",
"runtime/jvm"
]
}