config.json


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.

Metadados

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)

Files

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.

Exemplo

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

Exercícios

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 trilha
  • practice: um array que lista os exercícios de prática da trilha
  • foregone: um array que lista os slugs dos exercícios que a trilha não vai implementar

Exercícios de conceito

Cada 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 mudar
  • slug: 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 conceito
  • prerequisites: um array de slugs de conceitos que precisam estar desbloqueados antes de um estudante poder começar este exercício
  • status (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 ativos
    • deprecated: 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.

Exemplo

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

Exemplo de trabalho em andamento

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

Exercícios de prática

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 mudar
  • slug: 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 praticar
  • prerequisites: um array de slugs de conceitos que precisam estar desbloqueados antes de um estudante poder começar o exercício
  • difficulty: 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:
    • 1,2,3: fácil
    • 4,5,6,7: média
    • 8,9,10: difícil
  • 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 ativos
    • deprecated: 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.

Exemplo

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

Exemplo de beta

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

Exercícios preteridos

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:

  • O exercício não pode ser implementado de forma razoável pela linguagem. Por exemplo, o exercício lens-person exige que a linguagem ofereça suporte a lentes.
  • O tema do exercício não combina com a linguagem. Por exemplo, em algumas linguagens de alto nível, um exercício de baixo nível sobre manipulação de bits pode não fazer sentido.

Exemplo

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

Conceitos

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

Exemplo

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

Recursos principais

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

Você pode conferir a aparência visual desses ícones na seção de ícones de recursos principais.

É preciso especificar exatamente 6 recursos principais.

Exemplo

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

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

Paradigmas

  • paradigm/array: a linguagem é uma linguagem de programação de arrays
  • paradigm/declarative: a linguagem oferece suporte a um estilo declarativo de programação
  • paradigm/functional: a linguagem oferece suporte a um estilo funcional de programação
  • paradigm/imperative: a linguagem oferece suporte a um estilo imperativo de programação
  • paradigm/logic: a linguagem oferece suporte a um estilo de programação baseado em lógica
  • paradigm/object_oriented: a linguagem oferece suporte a um estilo orientado a objetos de programação
  • paradigm/procedural: a linguagem oferece suporte a um estilo procedural de programação
  • paradigm/stack-oriented: a linguagem oferece suporte a um estilo orientado a pilha de programação

Tipagem

  • typing/static: a linguagem usa tipagem estática
  • typing/gradual: a linguagem usa tipagem gradual
  • typing/dynamic: a linguagem usa tipagem dinâmica
  • typing/strong: a linguagem usa tipagem forte
  • typing/weak: a linguagem usa tipagem fraca

Modo de execução

  • execution_mode/compiled: o código é compilado antes de ser executado
  • execution_mode/interpreted: o código é interpretado diretamente

Plataforma

  • platform/windows: roda no Windows
  • platform/mac: roda no Mac
  • platform/linux: roda no Linux
  • platform/ios: roda no iOS
  • platform/android: roda no Android
  • platform/web: roda no navegador

Runtime

  • runtime/standalone_executable: roda como executável autônomo
  • runtime/language_specific: roda em um runtime específico da linguagem
  • runtime/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)

Usado para

  • used_for/artificial_intelligence: Inteligência Artificial
  • used_for/backends: Backends
  • used_for/cross_platform_development: Desenvolvimento multiplataforma
  • used_for/embedded_systems: Sistemas embarcados
  • used_for/financial_systems: Sistemas financeiros
  • used_for/frontends: Frontends
  • used_for/games: Jogos
  • used_for/guis: GUIs
  • used_for/mobile: Mobile
  • used_for/robotics: Robótica
  • used_for/scientific_calculations: Cálculos científicos
  • used_for/scripts: Scripts
  • used_for/web_development: Desenvolvimento web

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

Exemplo

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