O ficheiro config.json descreve a configuração do percurso. Contém informações essenciais, como os exercícios e os conceitos do percurso.
As seguintes propriedades de nível superior contêm metadados gerais sobre o percurso:
language: a linguagem do percurso (por exemplo, "C#"). O seu comprimento tem de ser <= 255. (obrigatório)slug: a linguagem do percurso como uma string em minúsculas e em kebab-case (por exemplo, "csharp"). O seu comprimento tem de ser <= 255. (obrigatório)active: um valor boolean que indica se o percurso está ativo (ou seja, se os estudantes podem aderir ao percurso no site) (obrigatório)blurb: uma breve descrição da linguagem. O seu comprimento tem de ser <= 400. (obrigatório)version: a versão do ficheiro config.json (atualmente fixada em 3) (obrigatório)online_editor: um objeto que descreve as configurações usadas no editor online: (obrigatório)
indent_style: "space" ou "tab" (obrigatório)indent_size: o tamanho da indentação, como número inteiro (por exemplo, 4) (obrigatório)highlightjs_language: o identificador de linguagem para o Highlight.js (vê a lista completa de identificadores) (opcional)status: um objeto que descreve que funcionalidades da v3 devem ser ativadas: (obrigatório)
concept_exercises: um valor boolean que indica se foram criados exercícios de conceito (obrigatório). Quando é true, a interface do site do Exercism muda para indicar que o percurso tem exercícios de conceito disponíveis.test_runner: um valor boolean que indica se foi implementado um test runner (obrigatório). Quando é true, submetemos as soluções à nossa infraestrutura de testes e mostramos os resultados no site. O site também permite que os estudantes iniciem uma execução de testes a partir do editor online.representer: um valor boolean que indica se foi implementado um representer (obrigatório)analyzer: um valor boolean que indica se foi implementado um analyzer (obrigatório)files: os padrões para as localizações dos ficheiros usados num exercício, relativos ao diretório do exercício. (opcional)
solution: padrão dos ficheiros de implementação stub (opcional)test: padrão dos ficheiros de teste (opcional)example: padrão dos ficheiros de implementação de exemplo (opcional)exemplar: padrão dos ficheiros de implementação exemplar (opcional)editor: padrões adicionais para os ficheiros do editor apenas de leitura (opcional)test_runner: um objeto que descreve o test runner do percurso (se existir): (obrigatório se status.test_runner for true)
average_run_time: um valor number inteiro para o número de segundos que o test runner demora, em média, a correr (por exemplo, 4) (obrigatório se status.test_runner for true)approaches: um objeto com metadados sobre as abordagens do percurso: (obrigatório se o percurso tiver alguma abordagem)
snippet_extension: um valor de string usado para a extensão do ficheiro de fragmento (por exemplo, rb) (obrigatório se o percurso tiver alguma abordagem)Esta chave é usada para especificar as localizações dos ficheiros à escala do percurso. Em vez de os maintainers terem de definir manualmente a chave files nos ficheiros config.json dos exercícios, o configlet pode preenchê-la automaticamente com estes padrões à escala do percurso.
Os padrões de ficheiros definidos no objeto files suportam os seguintes marcadores:
%{kebab_slug}: o slug do exercício em kebab-case (por exemplo, bit-manipulation)%{snake_slug}: o slug do exercício em snake_case (por exemplo, bit_manipulation)%{camel_slug}: o slug do exercício em camelCase (por exemplo, bitManipulation)%{pascal_slug}: o slug do exercício em PascalCase (por exemplo, BitManipulation)Será adicionado suporte ao configlet para usar estes padrões para preencher a chave files no ficheiro .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 do percursopractice: um array que lista os exercícios de prática do percursoforegone: um array que lista os slugs dos exercícios que o percurso não vai implementarCada exercício de conceito é uma entrada no array exercises.concept.
No site, os exercícios aparecem pela ordem em que estão listados neste ficheiro 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 tem de ser único tanto dentro do percurso como em todos os percursos, e nunca pode mudarslug: o slug do exercício, que é uma string em minúsculas e em kebab-case. O slug tem de ser único entre todos os slugs de exercícios de conceito e de prática do percurso. O seu comprimento tem de ser <= 255.name: o nome do exercício. O seu comprimento tem de ser <= 255.concepts: um array de slugs de conceitos que são ensinados por este exercício de conceitoprerequisites: um array de slugs de conceitos que têm de ser desbloqueados antes de um estudante poder começar este exercíciostatus (opcional): o estado do exercício, que é um de "wip", "beta", "active" ou "deprecated"; assume "active" por predefinição se não for especificado
wip: um exercício em desenvolvimento, ainda não pronto para uso público. Os exercícios com esta etiqueta não são mostrados aos estudantes na interface nem entram na lógica de desbloqueio. Podem aparecer para os maintainers.beta: designa exercícios ativos que são novos e sobre os quais gostaríamos de receber feedback. Mostramos uma etiqueta beta no site para estes exercícios, com um apelo à ação "Dá-nos o teu feedback."active: o estado normal dos exercícios ativosdeprecated: exercícios que já não são mostrados aos estudantes que ainda não os começaram (já não podem ser usados nesta fase). Vê os Exercícios obsoletos 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 tem de ser único tanto dentro do percurso como em todos os percursos, e nunca pode mudarslug: o slug do exercício, que é uma string em minúsculas e em kebab-case. O slug tem de ser único entre todos os slugs de exercícios de conceito e de prática do percurso. O seu comprimento tem de ser <= 255.name: o nome do exercício. O seu comprimento tem de 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 têm de ser desbloqueados antes de um estudante poder começar o exercíciodifficulty: um número que indica a dificuldade do exercício. O número tem de estar no intervalo de 1 (mais fácil) a 10 (mais difícil). O site interpreta a dificuldade da seguinte forma:
status (opcional): o estado do exercício, que é "wip", "beta", "active" ou "deprecated"; assume "active" por predefinição se não for especificado
wip: um exercício em desenvolvimento, ainda não pronto para uso público. Os exercícios com esta etiqueta não são mostrados aos estudantes na interface nem entram na lógica de desbloqueio. Podem aparecer para os maintainers.beta: designa exercícios ativos que são novos e sobre os quais gostaríamos de receber feedback. Mostramos uma etiqueta beta no site para estes exercícios, com um apelo à ação "Dá-nos o teu feedback"active: o estado normal dos exercícios ativosdeprecated: exercícios que já não são mostrados aos estudantes que ainda não os começaram (já não podem ser usados nesta fase).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 um percurso 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 ignora os exercícios preteridos quando apresenta os exercícios não implementados do percurso.
Algumas razões pelas quais um percurso 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 tem de ser único tanto dentro do percurso como em todos os percursos, e nunca pode mudarslug: o slug do conceito, que é uma string em minúsculas e em kebab-case. O slug tem de ser único entre todos os conceitos do percurso. O seu comprimento tem de ser <= 255.name: o nome do conceito. O seu comprimento tem de ser <= 255.tags: especifica as condições em que uma submissão é associada a uma abordagem. (opcional)
all: um array de etiquetas que têm de estar todas presentes numa submissão (opcional, exceto se any não tiver elementos)any: um array de etiquetas das quais pelo menos uma tem de estar presente numa submissão (opcional, exceto se all não tiver elementos)not: nenhuma das etiquetas pode estar presente numa submissão (opcional){
"concepts": [
{
"uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
"slug": "numbers",
"name": "Numbers",
"tags": {
"all": [
"concept:number"
]
}
}
]
}
As características principais da linguagem descrevem de forma sucinta quais são as funcionalidades mais importantes da linguagem. Têm como objetivo dar a conhecer as funcionalidades mais interessantes de uma linguagem a potenciais estudantes. Os títulos devem procurar usar o mínimo possível de jargão técnico, tendo em conta que os estudantes podem não saber o que significa o jargão específico de uma linguagem antes de a aprenderem.
As características principais são especificadas no campo de nível superior key_features, definido como um array de objetos com os seguintes campos:
title: um cabeçalho conciso para a característica principal. O seu comprimento tem de ser <= 25. O Markdown não é suportado.content: uma descrição da característica principal. O seu comprimento tem de ser <= 100. O Markdown não é suportado.icon: o ícone a mostrar para a característica. Podes escolher o ícone que achares adequado, independentemente do seu nome. Podem ser usados os seguintes ícones:
communityconcurrencycross-platformdocumentationdynamically-typedeasyembeddableevolvingexpressiveextensiblefastfunfunctionalgarbage-collectedgeneral-purposehomoiconicimmutableinteractiveinteropmulti-paradigmportablepowerfulproductivesafescientificsmallstablestatically-typedtoolingwebwidely-usedPodes ver o aspeto visual destes ícones na secção dos ícones das características principais.
Têm de ser especificadas exatamente 6 características 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"
},
...
],
}
Os percursos podem ser anotados com etiquetas, o que permite procurar percursos com uma determinada combinação de etiquetas.
Um percurso deve escolher as suas etiquetas com base no uso geral da sua linguagem. Por exemplo, imagina um estudante a pensar: "Gostava de fazer aprendizagem automática, que linguagem devo escolher?", ou "Gostava de aprender programação funcional, que linguagem devo escolher?". Se a tua linguagem for uma boa candidata, atribui-lhe essa etiqueta. Se a tua linguagem suportar algumas ideias funcionais mas raramente forem usadas, ou se poucas pessoas fizerem aprendizagem automática com ela e isso for raro, então não apliques essas etiquetas.
As etiquetas são especificadas no campo de nível superior tags, definido como um array de strings. Podem ser usadas as seguintes etiquetas (agrupadas por categoria):
paradigm/array: a linguagem é uma linguagem de programação de arraysparadigm/declarative: a linguagem suporta um estilo de programação declarativoparadigm/functional: a linguagem suporta um estilo de programação funcionalparadigm/imperative: a linguagem suporta um estilo de programação imperativoparadigm/logic: a linguagem suporta um estilo de programação baseado em lógicaparadigm/object_oriented: a linguagem suporta um estilo de programação orientado a objetosparadigm/procedural: a linguagem suporta um estilo de programação proceduralparadigm/stack-oriented: a linguagem suporta um estilo de programação orientado à pilhatyping/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 é primeiro compilado antes de ser executadoexecution_mode/interpreted: o código é interpretado diretamenteplatform/windows: corre no Windowsplatform/mac: corre no Macplatform/linux: corre no Linuxplatform/ios: corre no iOSplatform/android: corre no Androidplatform/web: corre no navegadorruntime/standalone_executable: corre como executável autónomoruntime/language_specific: corre num runtime específico da linguagemruntime/clr: corre no Common Language Runtime (.NET)runtime/jvm: corre na JVM (Java)runtime/beam: corre no BEAM (Erlang)runtime/wasmtime: corre no Wasmtime (WebAssembly)used_for/artificial_intelligence: Inteligência artificialused_for/backends: Backendsused_for/cross_platform_development: Desenvolvimento multiplataformaused_for/embedded_systems: Sistemas embebidosused_for/financial_systems: Sistemas financeirosused_for/frontends: Frontendsused_for/games: Jogosused_for/guis: Interfaces gráficasused_for/mobile: Dispositivos móveisused_for/robotics: Robóticaused_for/scientific_calculations: Cálculos científicosused_for/scripts: Scriptsused_for/web_development: Desenvolvimento webNota que não há problema nenhum em incluir várias etiquetas de uma só categoria.
Exemplo
{
"tags": [
"paradigm/declarative",
"paradigm/functional",
"paradigm/object_oriented",
"platform/linux",
"platform/windows",
"runtime/jvm"
]
}
Este é um exemplo do que pode ser um ficheiro 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"
]
}