El fichero config.json describe la configuración del track. Contiene información esencial, como los ejercicios y los conceptos del track.
Las siguientes propiedades de nivel superior contienen metadatos generales del track:
language: el lenguaje del track (por ejemplo, "C#"). Su longitud debe ser <= 255. (obligatorio)slug: el lenguaje del track como un string en minúsculas y en kebab-case (por ejemplo, "csharp"). Su longitud debe ser <= 255. (obligatorio)active: un valor boolean que indica si el track está activo (es decir, si los estudiantes pueden unirse al track en el sitio web) (obligatorio)blurb: una descripción breve del lenguaje. Su longitud debe ser <= 400. (obligatorio)version: la versión del fichero config.json (actualmente fijada a 3) (obligatorio)online_editor: un objeto que describe los ajustes que se usan para el editor en línea: (obligatorio)
indent_style: "space" o "tab" (obligatorio)indent_size: el tamaño de la indentación como número entero (por ejemplo, 4) (obligatorio)highlightjs_language: el identificador de lenguaje para Highlight.js (consulta la lista completa de identificadores) (opcional)status: un objeto que describe qué funcionalidades de la v3 deben estar habilitadas: (obligatorio)
concept_exercises: un valor boolean que indica si se han creado los ejercicios de concepto (obligatorio). Cuando es true, la interfaz del sitio web de Exercism cambia para indicar que hay ejercicios de concepto disponibles para el track.test_runner: un valor boolean que indica si se ha implementado un test runner (obligatorio). Cuando es true, hacemos pasar las soluciones enviadas por nuestra infraestructura de pruebas y mostramos los resultados en el sitio web. El sitio web también permite a los estudiantes iniciar una ejecución de pruebas desde el propio editor en línea.representer: un valor boolean que indica si se ha implementado un representer (obligatorio)analyzer: un valor boolean que indica si se ha implementado un analyzer (obligatorio)files: los patrones de las ubicaciones de los ficheros que se usan en un ejercicio, relativos al directorio del ejercicio. (opcional)
solution: patrón de los ficheros de la implementación esqueleto (opcional)test: patrón de los ficheros de pruebas (opcional)example: patrón de los ficheros de la implementación de ejemplo (opcional)exemplar: patrón de los ficheros de la implementación ejemplar (opcional)editor: patrones adicionales de ficheros del editor de solo lectura (opcional)test_runner: un objeto que describe el test runner del track (si lo hay): (obligatorio si status.test_runner es true)
average_run_time: un valor number entero con el número de segundos que tarda el test runner en ejecutarse de media (por ejemplo, 4) (obligatorio si status.test_runner es true)approaches: un objeto con metadatos sobre los enfoques del track: (obligatorio si el track tiene algún enfoque)
snippet_extension: un valor string que se usa como extensión del fichero de fragmento (por ejemplo, rb) (obligatorio si el track tiene algún enfoque)Esta clave se usa para especificar las ubicaciones de los ficheros de todo el track. En lugar de que los mantenedores tengan que establecer manualmente la clave files en los ficheros config.json de los ejercicios, configlet puede rellenarla automáticamente utilizando estos patrones definidos a nivel de track.
Los patrones de ficheros definidos en el objeto files admiten los siguientes marcadores de posición:
%{kebab_slug}: el slug del ejercicio en kebab-case (por ejemplo, bit-manipulation)%{snake_slug}: el slug del ejercicio en snake_case (por ejemplo, bit_manipulation)%{camel_slug}: el slug del ejercicio en camelCase (por ejemplo, bitManipulation)%{pascal_slug}: el slug del ejercicio en PascalCase (por ejemplo, BitManipulation)Se añadirá a configlet la posibilidad de usar estos patrones para rellenar la clave files del fichero .meta/config.json de un ejercicio.
{
"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 clave exercises de nivel superior es un objeto con tres claves posibles:
concept: es un array que enumera los ejercicios de concepto del trackpractice: es un array que enumera los ejercicios de práctica del trackforegone: es un array que enumera los slugs de los ejercicios que el track no va a implementarCada ejercicio de concepto es una entrada del array exercises.concept.
Los ejercicios aparecen en el sitio web en el mismo orden en que se enumeran en este fichero, y este debería coincidir con el orden típico en que conviene resolverlos.
Un ejercicio de concepto se compone de los siguientes campos:
uuid: un UUID v4 que identifica el ejercicio de forma única. El UUID debe ser único tanto dentro del track como en todos los tracks, y no debe cambiar nuncaslug: el slug del ejercicio, que es un string en minúsculas y en kebab-case. El slug debe ser único entre todos los slugs de ejercicios de concepto y de práctica del track. Su longitud debe ser <= 255.name: el nombre del ejercicio. Su longitud debe ser <= 255.concepts: un array de slugs de conceptos que se enseñan con este ejercicio de conceptoprerequisites: un array de slugs de conceptos que deben desbloquearse antes de que un estudiante pueda empezar este ejerciciostatus (opcional): el estado del ejercicio, que es uno de "wip", "beta" "active" o "deprecated"; si no se especifica, su valor predeterminado es "active"
wip: un ejercicio en curso que aún no está listo para el público. Los ejercicios con esta etiqueta no se mostrarán a los estudiantes en la interfaz ni se usarán en la lógica de desbloqueo. Pueden aparecer para los mantenedores.beta: indica que son ejercicios activos, nuevos y sobre los que nos gustaría recibir opiniones. En el sitio mostramos una etiqueta beta para estos ejercicios, con una llamada a la acción: «Danos tu opinión».active: el estado normal de los ejercicios activosdeprecated: ejercicios que ya no se muestran a los estudiantes que no los han empezado (no se pueden usar en esta fase). Consulta Ejercicios obsoletos para obtener más información.{
"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"
},
...
]
}
}
Cada ejercicio de práctica es una entrada del array exercises.practice. Un ejercicio de práctica se compone de los siguientes campos:
uuid: un UUID v4 que identifica el ejercicio de forma única. El UUID debe ser único tanto dentro del track como en todos los tracks, y no debe cambiar nuncaslug: el slug del ejercicio, que es un string en minúsculas y en kebab-case. El slug debe ser único entre todos los slugs de ejercicios de concepto y de práctica del track. Su longitud debe ser <= 255.name: el nombre del ejercicio. Su longitud debe ser <= 255.practices: un array de slugs de conceptos que el ejercicio ayuda a practicar a los estudiantesprerequisites: un array de slugs de conceptos que deben desbloquearse antes de que un estudiante pueda empezar el ejerciciodifficulty: un número que indica la dificultad del ejercicio. El número debe estar en el intervalo de 1 (el más fácil) a 10 (el más difícil). El sitio web interpreta la dificultad de la siguiente manera:
status (opcional): el estado del ejercicio, que es "wip", "beta", "active" o "deprecated"; si no se especifica, su valor predeterminado es "active"
wip: un ejercicio en curso que aún no está listo para el público. Los ejercicios con esta etiqueta no se mostrarán a los estudiantes en la interfaz ni se usarán en la lógica de desbloqueo. Pueden aparecer para los mantenedores.beta: indica que son ejercicios activos, nuevos y sobre los que nos gustaría recibir opiniones. En el sitio mostramos una etiqueta beta para estos ejercicios, con una llamada a la acción: «Danos tu opinión»active: el estado normal de los ejercicios activosdeprecated: ejercicios que ya no se muestran a los estudiantes que no los han empezado (no se pueden usar en esta fase).El «orden recomendado» de los ejercicios de práctica en el sitio web se corresponde con el orden de los ejercicios en el array 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 track sabe que no quiere implementar un ejercicio definido en el repositorio de Problem Specifications, el slug de ese ejercicio se puede añadir a la clave exercises.foregone. configlet ignorará los ejercicios descartados al generar los ejercicios no implementados del track.
Algunos motivos por los que un track podría no querer implementar un ejercicio son:
{
"exercises": {
"foregone": [
"lens-person"
]
}
}
Cada concepto es una entrada del array concepts de nivel superior. Un concepto se compone de los siguientes campos:
uuid: un UUID v4 que identifica el concepto de forma única. El UUID debe ser único tanto dentro del track como en todos los tracks, y no debe cambiar nuncaslug: el slug del concepto, que es un string en minúsculas y en kebab-case. El slug debe ser único entre todos los conceptos del track. Su longitud debe ser <= 255.name: el nombre del concepto. Su longitud debe ser <= 255.tags: especifica las condiciones para que un envío se vincule a un enfoque. (opcional)
all: un array de etiquetas que deben estar todas presentes en un envío (opcional, salvo que any no tenga elementos)any: un array de etiquetas de las que al menos una debe estar presente en un envío (opcional, salvo que all no tenga elementos)not: ninguna de las etiquetas debe estar presente en un envío (opcional){
"concepts": [
{
"uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
"slug": "numbers",
"name": "Numbers",
"tags": {
"all": [
"concept:number"
]
}
}
]
}
Las características clave de un lenguaje describen de forma concisa cuáles son sus aspectos más importantes. Su objetivo es dar a conocer a posibles estudiantes las características más interesantes de un lenguaje. Los títulos deberían usar el menor tecnicismo posible, teniendo en cuenta que es posible que los estudiantes aún no sepan qué significa la jerga específica de un lenguaje antes de aprenderlo.
Las características clave se especifican en el campo key_features de nivel superior, que se define como un array de objetos con los siguientes campos:
title: un encabezado conciso para la característica clave. Su longitud debe ser <= 25. No se admite Markdown.content: una descripción de la característica clave. Su longitud debe ser <= 100. No se admite Markdown.icon: el icono que se muestra para la característica. Puedes elegir el icono que creas que encaja, independientemente de su nombre. Se pueden usar los siguientes iconos:
communityconcurrencycross-platformdocumentationdynamically-typedeasyembeddableevolvingexpressiveextensiblefastfunfunctionalgarbage-collectedgeneral-purposehomoiconicimmutableinteractiveinteropmulti-paradigmportablepowerfulproductivesafescientificsmallstablestatically-typedtoolingwebwidely-usedPuedes ver el aspecto visual de estos iconos en la sección de iconos de características clave.
Se deben especificar exactamente 6 características clave.
{
"key_features": [
{
"title": "Fault-tolerant",
"content": "Elixir runs on the Erlang VM, known for running low-latency, distributed and fault-tolerant systems.",
"icon": "safe"
},
...
],
}
Los tracks se pueden anotar con etiquetas, lo que permite buscar tracks con una determinada combinación de etiquetas.
Un track debería elegir sus etiquetas en función del uso general de su lenguaje. Por ejemplo, imagina a un estudiante pensando: «Quiero hacer aprendizaje automático, ¿qué lenguaje elijo?» o «Quiero aprender programación funcional, ¿qué lenguaje debería elegir?». Si tu lenguaje sería un buen candidato, ponle esa etiqueta. Si tu lenguaje admite algunas ideas funcionales pero rara vez se usan, o hay unas pocas personas que hacen aprendizaje automático con él, pero es poco habitual, no le pongas esas etiquetas.
Las etiquetas se especifican en el campo tags de nivel superior, que se define como un array de strings. Se pueden usar las siguientes etiquetas (agrupadas por categoría):
paradigm/array: el lenguaje es un lenguaje de programación basado en arraysparadigm/declarative: el lenguaje admite un estilo de programación declarativaparadigm/functional: el lenguaje admite un estilo de programación funcionalparadigm/imperative: el lenguaje admite un estilo de programación imperativaparadigm/logic: el lenguaje admite un estilo de programación basado en la lógicaparadigm/object_oriented: el lenguaje admite un estilo de programación orientada a objetosparadigm/procedural: el lenguaje admite un estilo de programación proceduralparadigm/stack-oriented: el lenguaje admite un estilo de programación orientado a la pilatyping/static: el lenguaje usa tipado estáticotyping/gradual: el lenguaje usa tipado gradualtyping/dynamic: el lenguaje usa tipado dinámicotyping/strong: el lenguaje usa tipado fuertetyping/weak: el lenguaje usa tipado débilexecution_mode/compiled: el código se compila antes de ejecutarseexecution_mode/interpreted: el código se interpreta directamenteplatform/windows: se ejecuta en Windowsplatform/mac: se ejecuta en Macplatform/linux: se ejecuta en Linuxplatform/ios: se ejecuta en iOSplatform/android: se ejecuta en Androidplatform/web: se ejecuta en el navegadorruntime/standalone_executable: se ejecuta como ejecutable independienteruntime/language_specific: se ejecuta en un entorno de ejecución específico del lenguajeruntime/clr: se ejecuta en Common Language Runtime (.NET)runtime/jvm: se ejecuta en la JVM (Java)runtime/beam: se ejecuta en BEAM (Erlang)runtime/wasmtime: se ejecuta en Wasmtime (WebAssembly)used_for/artificial_intelligence: inteligencia artificialused_for/backends: backendsused_for/cross_platform_development: desarrollo multiplataformaused_for/embedded_systems: sistemas embebidosused_for/financial_systems: sistemas financierosused_for/frontends: frontendsused_for/games: videojuegosused_for/guis: interfaces gráficas (GUI)used_for/mobile: móvilused_for/robotics: robóticaused_for/scientific_calculations: cálculos científicosused_for/scripts: scriptsused_for/web_development: desarrollo webTen en cuenta que no hay ningún problema en incluir varias etiquetas de una misma categoría.
Ejemplo
{
"tags": [
"paradigm/declarative",
"paradigm/functional",
"paradigm/object_oriented",
"platform/linux",
"platform/windows",
"runtime/jvm"
]
}
Este es un ejemplo de cómo puede ser un fichero config.json válido:
{
"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"
]
}