O arquivo config.json descreve a configuração da trilha. Ele contém informações essenciais, como os exercícios e os conceitos da trilha.
As seguintes propriedades de nível superior contêm metadados gerais da trilha:
language: a linguagem da trilha (ex.: "C#"). O comprimento deve ser <= 255. (obrigatório)slug: a linguagem da trilha como uma string em minúsculas no formato kebab-case (ex.: "csharp"). O comprimento deve ser <= 255. (obrigatório)active: um valor boolean que indica se a trilha está ativa (ou seja, se os estudantes podem entrar na trilha no site) (obrigatório)blurb: uma descrição curta da linguagem. O comprimento deve ser <= 400. (obrigatório)version: a versão do arquivo config.json (atualmente fixada em 3) (obrigatório)online_editor: um objeto que descreve as configurações usadas pelo editor online: (obrigatório)
indent_style: "space" ou "tab" (obrigatório)indent_size: o tamanho da indentação como um número inteiro (ex.: 4) (obrigatório)highlightjs_language: o identificador de linguagem para o Highlight.js (veja a lista completa de identificadores) (opcional)status: um objeto que descreve quais recursos da v3 devem ser habilitados: (obrigatório)
concept_exercises: um valor boolean que indica se os exercícios de conceito foram criados (obrigatório). Quando é true, a interface do site do Exercism muda para indicar que há exercícios de conceito disponíveis para a trilha.test_runner: um valor boolean que indica se um executor de testes foi implementado (obrigatório). Quando é true, enviamos as soluções submetidas à nossa infraestrutura de testes e mostramos os resultados no site. O site também permite que os estudantes iniciem uma execução de testes pelo editor online.representer: um valor boolean que indica se um representador foi implementado (obrigatório)analyzer: um valor boolean que indica se um analisador foi implementado (obrigatório)files: os padrões para os locais dos arquivos usados em um exercício, relativos ao diretório do exercício. (opcional)
solution: padrão dos arquivos de implementação stub (opcional)test: padrão dos arquivos de teste (opcional)example: padrão dos arquivos de implementação de exemplo (opcional)exemplar: padrão dos arquivos de implementação exemplar (opcional)editor: padrões adicionais de arquivos somente leitura do editor (opcional)test_runner: um objeto que descreve o executor de testes da trilha (se houver): (obrigatório se status.test_runner for true)
average_run_time: um valor number inteiro para o número de segundos que o executor de testes leva em média para rodar (ex.: 4) (obrigatório se status.test_runner for true)approaches: um objeto com metadados sobre as abordagens da trilha: (obrigatório se a trilha tiver alguma abordagem)
snippet_extension: um valor string usado para a extensão do arquivo de snippet (ex.: rb) (obrigatório se a trilha tiver alguma abordagem)Essa chave é usada para especificar os locais dos arquivos em toda a trilha. Em vez de os mantenedores terem que definir manualmente a chave files nos arquivos config.json dos exercícios, o configlet pode preenchê-la automaticamente usando esses padrões de toda a trilha.
Os padrões de arquivo definidos no objeto files aceitam os seguintes placeholders:
%{kebab_slug}: o slug do exercício em kebab-case (ex.: bit-manipulation)%{snake_slug}: o slug do exercício em snake_case (ex.: bit_manipulation)%{camel_slug}: o slug do exercício em camelCase (ex.: bitManipulation)%{pascal_slug}: o slug do exercício em PascalCase (ex.: BitManipulation)O suporte será adicionado ao configlet para usar esses padrões a fim de preencher a chave files no arquivo .meta/config.json de um exercício.
{
"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"
]
}
}
A chave de nível superior exercises é um objeto com três chaves possíveis:
concept: um array que lista os exercícios de conceito da trilhapractice: um array que lista os exercícios de prática da trilhaforegone: um array que lista os slugs dos exercícios que a trilha não vai implementarCada exercício de conceito é uma entrada no array exercises.concept.
Os exercícios são ordenados no site na mesma ordem em que aparecem neste arquivo, e devem corresponder à ordem típica em que devem ser resolvidos.
Os seguintes campos compõem um exercício de conceito:
uuid: um UUID V4 que identifica o exercício de forma única. O UUID deve ser único tanto dentro da trilha quanto em todas as trilhas, e nunca deve mudarslug: o slug do exercício, que é uma string em minúsculas no formato kebab-case. O slug deve ser único entre todos os slugs de exercícios de conceito e de prática da trilha. O comprimento deve ser <= 255.name: o nome do exercício. O comprimento deve ser <= 255.concepts: um array de slugs de conceitos ensinados por este exercício de conceitoprerequisites: um array de slugs de conceitos que precisam estar desbloqueados antes de um estudante poder começar este exercíciostatus (opcional): o status do exercício, que é um de "wip", "beta", "active" ou "deprecated"; o padrão é "active" se não for especificado
wip: um exercício em andamento (work in progress) que ainda não está pronto para uso público. Exercícios com esse rótulo não serão mostrados aos estudantes na interface nem usados na lógica de desbloqueio. Eles podem aparecer para os mantenedores.beta: isso indica exercícios ativos que são novos e sobre os quais gostaríamos de receber feedback. Mostramos um rótulo beta no site para esses exercícios, com uma chamada para ação: "Nos dê seu feedback."active: o estado normal dos exercícios ativosdeprecated: exercícios que não são mais mostrados aos estudantes que ainda não os começaram (não são utilizáveis neste estágio). Veja Exercícios descontinuados para mais informações.{
"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 exercício de prática é uma entrada no array exercises.practice. Os seguintes campos compõem um exercício de prática:
uuid: um UUID V4 que identifica o exercício de forma única. O UUID deve ser único tanto dentro da trilha quanto em todas as trilhas, e nunca deve mudarslug: o slug do exercício, que é uma string em minúsculas no formato kebab-case. O slug deve ser único entre todos os slugs de exercícios de conceito e de prática da trilha. O comprimento deve ser <= 255.name: o nome do exercício. O comprimento deve ser <= 255.practices: um array de slugs de conceitos que o exercício ajuda os estudantes a praticarprerequisites: um array de slugs de conceitos que precisam estar desbloqueados antes de um estudante poder começar o exercíciodifficulty: um número que indica a dificuldade do exercício. O número deve estar no intervalo de 1 (mais fácil) a 10 (mais difícil). O site interpreta a dificuldade da seguinte forma:
status (opcional): o status do exercício, que é "wip", "beta", "active" ou "deprecated"; o padrão é "active" se não for especificado
wip: um exercício em andamento (work in progress) que ainda não está pronto para uso público. Exercícios com esse rótulo não serão mostrados aos estudantes na interface nem usados na lógica de desbloqueio. Eles podem aparecer para os mantenedores.beta: isso indica exercícios ativos que são novos e sobre os quais gostaríamos de receber feedback. Mostramos um rótulo beta no site para esses exercícios, com uma chamada para ação: "Nos dê seu feedback"active: o estado normal dos exercícios ativosdeprecated: exercícios que não são mais mostrados aos estudantes que ainda não os começaram (não são utilizáveis neste estágio).A "Ordem recomendada" dos exercícios de prática no site corresponde à ordem dos exercícios no 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"
},
...
]
}
}
Se uma trilha sabe que não quer implementar um exercício definido no repositório Problem Specifications, o slug desse exercício pode ser adicionado à chave exercises.foregone. O configlet vai ignorar os exercícios preteridos ao listar os exercícios não implementados da trilha.
Alguns motivos pelos quais uma trilha pode não querer implementar um exercício:
{
"exercises": {
"foregone": [
"lens-person"
]
}
}
Cada conceito é uma entrada no array de nível superior concepts. Os seguintes campos compõem um conceito:
uuid: um UUID V4 que identifica o conceito de forma única. O UUID deve ser único tanto dentro da trilha quanto em todas as trilhas, e nunca deve mudarslug: o slug do conceito, que é uma string em minúsculas no formato kebab-case. O slug deve ser único entre todos os conceitos da trilha. O comprimento deve ser <= 255.name: o nome do conceito. O comprimento deve ser <= 255.tags: especifique as condições para quando uma submissão é vinculada a uma abordagem. (opcional)
all: um array de tags que devem estar todas presentes em uma submissão (opcional, a menos que any não tenha elementos)any: um array de tags das quais pelo menos uma deve estar presente em uma submissão (opcional, a menos que all não tenha elementos)not: nenhuma das tags pode estar presente em uma submissão (opcional){
"concepts": [
{
"uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
"slug": "numbers",
"name": "Numbers",
"tags": {
"all": [
"concept:number"
]
}
}
]
}
Os recursos principais da linguagem descrevem de forma sucinta quais são as características mais importantes dela. Eles servem para apresentar os recursos mais interessantes de uma linguagem a potenciais estudantes. Os títulos devem usar o mínimo possível de jargão técnico, lembrando que os estudantes podem não saber o que um jargão específico da linguagem significa antes de aprendê-la.
Os recursos principais são especificados no campo de nível superior key_features, definido como um array de objetos com os seguintes campos:
title: um cabeçalho conciso para o recurso principal. O comprimento deve ser <= 25. Não há suporte a Markdown.content: uma descrição do recurso principal. O comprimento deve ser <= 100. Não há suporte a Markdown.icon: o ícone a ser mostrado para o recurso. Você pode escolher um ícone que achar adequado, independentemente do nome dele. Os seguintes ícones podem ser usados:
communityconcurrencycross-platformdocumentationdynamically-typedeasyembeddableevolvingexpressiveextensiblefastfunfunctionalgarbage-collectedgeneral-purposehomoiconicimmutableinteractiveinteropmulti-paradigmportablepowerfulproductivesafescientificsmallstablestatically-typedtoolingwebwidely-usedVocê pode conferir a aparência visual desses ícones na seção de ícones de recursos principais.
É preciso especificar exatamente 6 recursos principais.
{
"key_features": [
{
"title": "Fault-tolerant",
"content": "Elixir runs on the Erlang VM, known for running low-latency, distributed and fault-tolerant systems.",
"icon": "safe"
},
...
],
}
As trilhas podem ser anotadas com tags, o que permite buscar trilhas com uma certa combinação de tags.
Uma trilha deve escolher suas tags com base no uso geral da sua linguagem. Por exemplo, imagine um estudante pensando: "Quero trabalhar com aprendizado de máquina, qual linguagem devo escolher?", ou "Quero aprender programação funcional, qual linguagem devo escolher?". Se a sua linguagem for uma boa candidata, dê essa tag a ela. Se a sua linguagem oferece algumas ideias funcionais, mas elas raramente são usadas, ou se poucas pessoas fazem aprendizado de máquina com ela, mas isso é raro, então não aplique essas tags.
As tags são especificadas no campo de nível superior tags, definido como um array de strings. As seguintes tags podem ser usadas (agrupadas por categoria):
paradigm/array: a linguagem é uma linguagem de programação de arraysparadigm/declarative: a linguagem oferece suporte a um estilo declarativo de programaçãoparadigm/functional: a linguagem oferece suporte a um estilo funcional de programaçãoparadigm/imperative: a linguagem oferece suporte a um estilo imperativo de programaçãoparadigm/logic: a linguagem oferece suporte a um estilo de programação baseado em lógicaparadigm/object_oriented: a linguagem oferece suporte a um estilo orientado a objetos de programaçãoparadigm/procedural: a linguagem oferece suporte a um estilo procedural de programaçãoparadigm/stack-oriented: a linguagem oferece suporte a um estilo orientado a pilha de programaçãotyping/static: a linguagem usa tipagem estáticatyping/gradual: a linguagem usa tipagem gradualtyping/dynamic: a linguagem usa tipagem dinâmicatyping/strong: a linguagem usa tipagem fortetyping/weak: a linguagem usa tipagem fracaexecution_mode/compiled: o código é compilado antes de ser executadoexecution_mode/interpreted: o código é interpretado diretamenteplatform/windows: roda no Windowsplatform/mac: roda no Macplatform/linux: roda no Linuxplatform/ios: roda no iOSplatform/android: roda no Androidplatform/web: roda no navegadorruntime/standalone_executable: roda como executável autônomoruntime/language_specific: roda em um runtime específico da linguagemruntime/clr: roda no Common Language Runtime (.NET)runtime/jvm: roda na JVM (Java)runtime/beam: roda na BEAM (Erlang)runtime/wasmtime: roda no Wasmtime (WebAssembly)used_for/artificial_intelligence: Inteligência Artificialused_for/backends: Backendsused_for/cross_platform_development: Desenvolvimento multiplataformaused_for/embedded_systems: Sistemas embarcadosused_for/financial_systems: Sistemas financeirosused_for/frontends: Frontendsused_for/games: Jogosused_for/guis: GUIsused_for/mobile: Mobileused_for/robotics: Robóticaused_for/scientific_calculations: Cálculos científicosused_for/scripts: Scriptsused_for/web_development: Desenvolvimento webVale notar que não há problema nenhum em incluir várias tags de uma mesma categoria.
Exemplo
{
"tags": [
"paradigm/declarative",
"paradigm/functional",
"paradigm/object_oriented",
"platform/linux",
"platform/windows",
"runtime/jvm"
]
}
Este é um exemplo de como pode ser um arquivo 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"
]
}