config.json


Le fichier config.json décrit la configuration du parcours. Il contient des informations essentielles, comme les exercices et les concepts du parcours.

Métadonnées

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)

Fichiers

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.

Exemple

{
  "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"
    ]
  }
}

Exercices

La clé de premier niveau exercises est un objet qui peut contenir trois clés :

  • concept : un tableau listant les exercices d'apprentissage du parcours
  • practice : un tableau listant les exercices d'entraînement du parcours
  • foregone : un tableau listant les slugs des exercices que le parcours n'implémentera pas

Exercices d'apprentissage

Chaque 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 changer
  • slug : 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'apprentissage
  • prerequisites : un tableau de slugs des concepts qui doivent être déverrouillés avant qu'un apprenant puisse commencer cet exercice
  • 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 actifs
    • deprecated : 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.

Exemple

{
  "exercises": {
    "concept": [
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ]
      },
      ...
    ]
  }
}

Exemple d'exercice en cours de développement

{
  "exercises": {
    "concept": [
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ],
        "status": "wip"
      },
      ...
    ]
  }
}

Exercices d'entraînement

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 changer
  • slug : 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 pratique
  • prerequisites : un tableau de slugs des concepts qui doivent être déverrouillés avant qu'un apprenant puisse commencer l'exercice
  • difficulty : 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 :
    • 1, 2, 3 : facile
    • 4, 5, 6, 7 : moyen
    • 8, 9, 10 : difficile
  • 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 actifs
    • deprecated : 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.

Exemple

{
  "exercises": {
    "practice": [
      {
        "slug": "leap",
        "name": "Leap",
        "uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
        "practices": [
          "if-statements",
          "numbers",
          "operator-precedence"
        ],
        "prerequisites": [
          "if-statements",
          "numbers"
        ],
        "difficulty": 1
      },
      ...
    ]
  }
}

Exemple de statut bêta

{
  "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"
      },
      ...
    ]
  }
}

Exercices écartés

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 :

  • L'exercice ne peut pas raisonnablement être implémenté dans le langage. Par exemple, l'exercice lens-person exige que le langage prenne en charge les lenses.
  • Le thème de l'exercice ne correspond pas au langage. Par exemple, pour certains langages de haut niveau, un exercice de manipulation de bits de bas niveau peut ne pas avoir de sens.

Exemple

{
  "exercises": {
    "foregone": [
      "lens-person"
    ]
  }
}

Concepts

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 changer
  • slug : 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)

Exemple

{
  "concepts": [
    {
      "uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
      "slug": "numbers",
      "name": "Numbers",
      "tags": {
        "all": [
          "concept:number"
        ]
      }
    }
  ]
}

Caractéristiques principales

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 :
    • community
    • concurrency
    • cross-platform
    • documentation
    • dynamically-typed
    • easy
    • embeddable
    • evolving
    • expressive
    • extensible
    • fast
    • fun
    • functional
    • garbage-collected
    • general-purpose
    • homoiconic
    • immutable
    • interactive
    • interop
    • multi-paradigm
    • portable
    • powerful
    • productive
    • safe
    • scientific
    • small
    • stable
    • statically-typed
    • tooling
    • web
    • widely-used

Tu 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.

Exemple

{
  "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

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) :

Paradigmes

  • paradigm/array : le langage est un langage de programmation par tableaux
  • paradigm/declarative : le langage prend en charge un style de programmation déclaratif
  • paradigm/functional : le langage prend en charge un style de programmation fonctionnel
  • paradigm/imperative : le langage prend en charge un style de programmation impératif
  • paradigm/logic : le langage prend en charge un style de programmation basé sur la logique
  • paradigm/object_oriented : le langage prend en charge un style de programmation orienté objet
  • paradigm/procedural : le langage prend en charge un style de programmation procédural
  • paradigm/stack-oriented : le langage prend en charge un style de programmation orienté pile

Typage

  • typing/static : le langage utilise le typage statique
  • typing/gradual : le langage utilise le typage progressif
  • typing/dynamic : le langage utilise le typage dynamique
  • typing/strong : le langage utilise le typage fort
  • typing/weak : le langage utilise le typage faible

Mode d'exécution

  • execution_mode/compiled : le code est d'abord compilé avant d'être exécuté
  • execution_mode/interpreted : le code est interprété directement

Plateforme

  • platform/windows : fonctionne sous Windows
  • platform/mac : fonctionne sous Mac
  • platform/linux : fonctionne sous Linux
  • platform/ios : fonctionne sous iOS
  • platform/android : fonctionne sous Android
  • platform/web : fonctionne dans le navigateur

Environnement d'exécution

  • runtime/standalone_executable : s'exécute comme un exécutable autonome
  • runtime/language_specific : s'exécute sur un environnement d'exécution propre au langage
  • runtime/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)

Utilisé pour

  • used_for/artificial_intelligence : intelligence artificielle
  • used_for/backends : backends
  • used_for/cross_platform_development : développement multiplateforme
  • used_for/embedded_systems : systèmes embarqués
  • used_for/financial_systems : systèmes financiers
  • used_for/frontends : frontends
  • used_for/games : jeux
  • used_for/guis : interfaces graphiques
  • used_for/mobile : mobile
  • used_for/robotics : robotique
  • used_for/scientific_calculations : calculs scientifiques
  • used_for/scripts : scripts
  • used_for/web_development : développement web

Il 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"
  ]
}

Exemple

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"
  ]
}