Le fichier config.json décrit la configuration du parcours. Il contient des informations essentielles, comme les exercices et les concepts du parcours.
Les propriétés de premier niveau suivantes contiennent les métadonnées générales du parcours :
language : le langage du parcours (par exemple "C#"). Sa longueur doit être <= 255. (obligatoire)slug : le langage du parcours sous forme de chaîne en kebab-case, en minuscules (par exemple "csharp"). Sa longueur doit être <= 255. (obligatoire)active : une valeur boolean indiquant si le parcours est actif (c'est-à-dire si les apprenants peuvent rejoindre le parcours sur le site) (obligatoire)blurb : une brève description du langage. Sa longueur doit être <= 400. (obligatoire)version : la version du fichier config.json (actuellement fixée à 3) (obligatoire)online_editor : un objet décrivant les paramètres utilisés pour l'éditeur en ligne : (obligatoire)
indent_style : soit "space", soit "tab" (obligatoire)indent_size : la taille de l'indentation sous forme de nombre entier (par exemple 4) (obligatoire)highlightjs_language : l'identifiant de langage pour Highlight.js (voir la liste complète des identifiants) (facultatif)status : un objet décrivant quelles fonctionnalités de la v3 doivent être activées : (obligatoire)
concept_exercises : une valeur boolean indiquant si des exercices d'apprentissage ont été créés (obligatoire). Lorsqu'elle vaut true, l'interface du site Exercism change pour indiquer que des exercices d'apprentissage sont disponibles pour le parcours.test_runner : une valeur boolean indiquant si un exécuteur de tests a été implémenté (obligatoire). Lorsqu'elle vaut true, nous faisons passer les solutions soumises par notre infrastructure de test et affichons les résultats sur le site. Le site permet également aux apprenants de lancer une exécution de tests depuis l'éditeur en ligne.representer : une valeur boolean indiquant si un representer a été implémenté (obligatoire)analyzer : une valeur boolean indiquant si un analyseur a été implémenté (obligatoire)files : les motifs d'emplacement des fichiers utilisés dans un exercice, relatifs au répertoire de l'exercice. (facultatif)
solution : motif du ou des fichiers d'implémentation de départ (facultatif)test : motif du ou des fichiers de test (facultatif)example : motif du ou des fichiers d'implémentation d'exemple (facultatif)exemplar : motif du ou des fichiers d'implémentation exemplaire (facultatif)editor : motifs supplémentaires des fichiers d'éditeur en lecture seule (facultatif)test_runner : un objet décrivant l'exécuteur de tests du parcours (le cas échéant) : (obligatoire si status.test_runner vaut true)
average_run_time : une valeur number entière correspondant au nombre de secondes que l'exécuteur de tests met en moyenne à s'exécuter (par exemple 4) (obligatoire si status.test_runner vaut true)approaches : un objet contenant les métadonnées des approches du parcours : (obligatoire si le parcours propose des approches)
snippet_extension : une valeur de type string utilisée pour l'extension du fichier d'extrait (par exemple rb) (obligatoire si le parcours propose des approches)Cette clé sert à préciser les emplacements de fichiers à l'échelle du parcours. Plutôt que de demander aux mainteneurs de définir manuellement la clé files dans les fichiers config.json des exercices, configlet peut la remplir automatiquement à partir de ces motifs valables pour l'ensemble du parcours.
Les motifs de fichiers définis dans l'objet files prennent en charge les espaces réservés suivants :
%{kebab_slug} : le slug d'exercice en kebab-case (par exemple bit-manipulation)%{snake_slug} : le slug d'exercice en snake_case (par exemple bit_manipulation)%{camel_slug} : le slug d'exercice en camelCase (par exemple bitManipulation)%{pascal_slug} : le slug d'exercice en PascalCase (par exemple BitManipulation)Une prise en charge sera ajoutée à configlet pour utiliser ces motifs afin de remplir la clé files dans le fichier .meta/config.json d'un exercice.
{
"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"
]
}
}
La clé de premier niveau exercises est un objet qui peut contenir trois clés :
concept : un tableau listant les exercices d'apprentissage du parcourspractice : un tableau listant les exercices d'entraînement du parcoursforegone : un tableau listant les slugs des exercices que le parcours n'implémentera pasChaque exercice d'apprentissage est une entrée du tableau exercises.concept.
Les exercices sont affichés sur le site dans l'ordre où ils sont listés dans ce fichier, et cet ordre doit correspondre à l'ordre habituel dans lequel ils doivent être résolus.
Un exercice d'apprentissage est composé des champs suivants :
uuid : un UUID v4 qui identifie l'exercice de manière unique. L'UUID doit être unique à la fois au sein du parcours et sur l'ensemble des parcours, et ne doit jamais changerslug : le slug de l'exercice, à savoir une chaîne en kebab-case, en minuscules. Le slug doit être unique parmi tous les slugs d'exercices d'apprentissage et d'entraînement du parcours. Sa longueur doit être <= 255.name : le nom de l'exercice. Sa longueur doit être <= 255.concepts : un tableau de slugs des concepts enseignés par cet exercice d'apprentissageprerequisites : un tableau de slugs des concepts qui doivent être déverrouillés avant qu'un apprenant puisse commencer cet exercicestatus (facultatif) : le statut de l'exercice, qui vaut "wip", "beta", "active" ou "deprecated" ; il vaut "active" par défaut s'il n'est pas précisé
wip : un exercice en cours de développement, pas encore prêt à être publié. Les exercices portant ce statut ne sont pas montrés aux apprenants dans l'interface et ne sont pas pris en compte par la logique de déverrouillage. Ils peuvent apparaître pour les mainteneurs.beta : désigne des exercices actifs qui sont nouveaux et sur lesquels nous aimerions avoir des retours. Nous affichons une étiquette bêta sur le site pour ces exercices, avec un appel à l'action : « Donnez-nous votre avis. »active : l'état normal des exercices actifsdeprecated : des exercices qui ne sont plus montrés aux apprenants qui ne les ont pas commencés (ils ne sont pas utilisables à ce stade). Voir la page Exercices obsolètes pour plus d'informations.{
"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"
},
...
]
}
}
Chaque exercice d'entraînement est une entrée du tableau exercises.practice. Un exercice d'entraînement est composé des champs suivants :
uuid : un UUID v4 qui identifie l'exercice de manière unique. L'UUID doit être unique à la fois au sein du parcours et sur l'ensemble des parcours, et ne doit jamais changerslug : le slug de l'exercice, à savoir une chaîne en kebab-case, en minuscules. Le slug doit être unique parmi tous les slugs d'exercices d'apprentissage et d'entraînement du parcours. Sa longueur doit être <= 255.name : le nom de l'exercice. Sa longueur doit être <= 255.practices : un tableau de slugs des concepts que l'exercice aide les apprenants à mettre en pratiqueprerequisites : un tableau de slugs des concepts qui doivent être déverrouillés avant qu'un apprenant puisse commencer l'exercicedifficulty : un nombre indiquant la difficulté de l'exercice. Ce nombre doit être compris entre 1 (le plus facile) et 10 (le plus difficile). Le site interprète la difficulté comme suit :
status (facultatif) : le statut de l'exercice, qui vaut "wip", "beta", "active" ou "deprecated" ; il vaut "active" par défaut s'il n'est pas précisé
wip : un exercice en cours de développement, pas encore prêt à être publié. Les exercices portant ce statut ne sont pas montrés aux apprenants dans l'interface et ne sont pas pris en compte par la logique de déverrouillage. Ils peuvent apparaître pour les mainteneurs.beta : désigne des exercices actifs qui sont nouveaux et sur lesquels nous aimerions avoir des retours. Nous affichons une étiquette bêta sur le site pour ces exercices, avec un appel à l'action : « Donnez-nous votre avis »active : l'état normal des exercices actifsdeprecated : des exercices qui ne sont plus montrés aux apprenants qui ne les ont pas commencés (ils ne sont pas utilisables à ce stade).L'« Ordre recommandé » des exercices d'entraînement sur le site correspond à l'ordre des exercices dans le tableau 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"
},
...
]
}
}
Si un parcours sait qu'il ne souhaite pas implémenter un exercice défini dans le dépôt Problem Specifications, le slug de cet exercice peut être ajouté à la clé exercises.foregone. configlet ignorera les exercices écartés lorsqu'il produira la liste des exercices non implémentés du parcours.
Les raisons pour lesquelles un parcours pourrait ne pas vouloir implémenter un exercice peuvent être les suivantes :
{
"exercises": {
"foregone": [
"lens-person"
]
}
}
Chaque concept est une entrée du tableau de premier niveau concepts. Un concept est composé des champs suivants :
uuid : un UUID v4 qui identifie le concept de manière unique. L'UUID doit être unique à la fois au sein du parcours et sur l'ensemble des parcours, et ne doit jamais changerslug : le slug du concept, à savoir une chaîne en kebab-case, en minuscules. Le slug doit être unique parmi tous les concepts du parcours. Sa longueur doit être <= 255.name : le nom du concept. Sa longueur doit être <= 255.tags : précise les conditions dans lesquelles une soumission est associée à une approche. (facultatif)
all : un tableau de tags qui doivent tous être présents sur une soumission (facultatif, sauf si any ne contient aucun élément)any : un tableau de tags dont au moins un doit être présent sur une soumission (facultatif, sauf si all ne contient aucun élément)not : aucun des tags ne doit être présent sur une soumission (facultatif){
"concepts": [
{
"uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
"slug": "numbers",
"name": "Numbers",
"tags": {
"all": [
"concept:number"
]
}
}
]
}
Les caractéristiques principales d'un langage décrivent de façon concise ses aspects les plus importants. Elles servent à mettre en avant les aspects les plus intéressants d'un langage auprès des futurs apprenants. Les titres doivent employer le moins de jargon technique possible, en gardant à l'esprit que les apprenants ne connaissent peut-être pas encore le jargon propre au langage avant de l'apprendre.
Les caractéristiques principales sont définies dans le champ de premier niveau key_features, qui est un tableau d'objets comportant les champs suivants :
title : un intitulé concis pour la caractéristique. Sa longueur doit être <= 25. Markdown n'est pas pris en charge.content : une description de la caractéristique. Sa longueur doit être <= 100. Markdown n'est pas pris en charge.icon : l'icône à afficher pour la caractéristique. Tu peux choisir l'icône qui te semble convenir, quel que soit son nom. Les icônes suivantes peuvent être utilisées :
communityconcurrencycross-platformdocumentationdynamically-typedeasyembeddableevolvingexpressiveextensiblefastfunfunctionalgarbage-collectedgeneral-purposehomoiconicimmutableinteractiveinteropmulti-paradigmportablepowerfulproductivesafescientificsmallstablestatically-typedtoolingwebwidely-usedTu peux voir l'apparence visuelle de ces icônes dans la section sur les icônes des caractéristiques.
Exactement 6 caractéristiques principales doivent être définies.
{
"key_features": [
{
"title": "Fault-tolerant",
"content": "Elixir runs on the Erlang VM, known for running low-latency, distributed and fault-tolerant systems.",
"icon": "safe"
},
...
],
}
Les parcours peuvent être annotés avec des tags, ce qui permet de rechercher les parcours ayant une certaine combinaison de tags.
Un parcours doit choisir ses tags en fonction de l'usage général de son langage. Par exemple, imagine un apprenant qui se dit : « J'aimerais faire de l'apprentissage automatique, quel langage choisir ? », ou « J'aimerais apprendre la programmation fonctionnelle, quel langage choisir ? ». Si ton langage est un bon candidat, attribue-lui ce tag. Si ton langage prend en charge quelques idées fonctionnelles mais qu'elles sont rarement utilisées, ou que quelques personnes font de l'apprentissage automatique avec, mais que c'est rare, alors n'applique pas ces tags.
Les tags sont définis dans le champ de premier niveau tags, qui est un tableau de strings. Les tags suivants peuvent être utilisés (regroupés par catégorie) :
paradigm/array : le langage est un langage de programmation par tableauxparadigm/declarative : le langage prend en charge un style de programmation déclaratifparadigm/functional : le langage prend en charge un style de programmation fonctionnelparadigm/imperative : le langage prend en charge un style de programmation impératifparadigm/logic : le langage prend en charge un style de programmation basé sur la logiqueparadigm/object_oriented : le langage prend en charge un style de programmation orienté objetparadigm/procedural : le langage prend en charge un style de programmation procéduralparadigm/stack-oriented : le langage prend en charge un style de programmation orienté piletyping/static : le langage utilise le typage statiquetyping/gradual : le langage utilise le typage progressiftyping/dynamic : le langage utilise le typage dynamiquetyping/strong : le langage utilise le typage forttyping/weak : le langage utilise le typage faibleexecution_mode/compiled : le code est d'abord compilé avant d'être exécutéexecution_mode/interpreted : le code est interprété directementplatform/windows : fonctionne sous Windowsplatform/mac : fonctionne sous Macplatform/linux : fonctionne sous Linuxplatform/ios : fonctionne sous iOSplatform/android : fonctionne sous Androidplatform/web : fonctionne dans le navigateurruntime/standalone_executable : s'exécute comme un exécutable autonomeruntime/language_specific : s'exécute sur un environnement d'exécution propre au langageruntime/clr : s'exécute sur le Common Language Runtime (.NET)runtime/jvm : s'exécute sur la JVM (Java)runtime/beam : s'exécute sur la BEAM (Erlang)runtime/wasmtime : s'exécute sur Wasmtime (WebAssembly)used_for/artificial_intelligence : intelligence artificielleused_for/backends : backendsused_for/cross_platform_development : développement multiplateformeused_for/embedded_systems : systèmes embarquésused_for/financial_systems : systèmes financiersused_for/frontends : frontendsused_for/games : jeuxused_for/guis : interfaces graphiquesused_for/mobile : mobileused_for/robotics : robotiqueused_for/scientific_calculations : calculs scientifiquesused_for/scripts : scriptsused_for/web_development : développement webIl est tout à fait possible d'inclure plusieurs tags d'une même catégorie.
Exemple
{
"tags": [
"paradigm/declarative",
"paradigm/functional",
"paradigm/object_oriented",
"platform/linux",
"platform/windows",
"runtime/jvm"
]
}
Voici un exemple de ce à quoi peut ressembler un fichier config.json valide :
{
"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"
]
}