165 lines
6.4 KiB
Markdown
165 lines
6.4 KiB
Markdown
# Contributing Guide
|
|
|
|
This document supplements the [Exercism contributing guide]; all contributors should read that document before proceeding.
|
|
|
|
## Table of Contents
|
|
|
|
- [Contributing Guide](#contributing-guide)
|
|
* [Architecture](#architecture)
|
|
* [Implementing an exercise](#implementing-an-exercise)
|
|
+ [Exercise structure](#exercise-structure)
|
|
+ [Generating Exercise READMEs](#generating-exercise-readmes)
|
|
- [Requirements](#requirements)
|
|
- [Generating all READMEs](#generating-all-readmes)
|
|
- [Generating a single README](#generating-a-single-readme)
|
|
+ [Implementing tests](#implementing-tests)
|
|
+ [Example solutions](#example-solutions)
|
|
+ [config.json](#configjson)
|
|
* [Implementing Track-specific Exercises](#implementing-track-specific-exercises)
|
|
* [Pull Request Tips](#pull-request-tips)
|
|
|
|
|
|
## Architecture
|
|
|
|
Exercism tracks inherit exercise definitions from the [problem-specifications] repository in the form of description files
|
|
(from which exercise READMEs are [generated](#generating-exercise-readmes))
|
|
|
|
|
|
## Implementing an exercise
|
|
|
|
### Exercise structure
|
|
|
|
```Bash
|
|
exercises/[EXERCISE]/
|
|
├── [EXERCISE].py
|
|
├── [EXERCISE]_test.py
|
|
├── example.py
|
|
├── .meta
|
|
│ ├── template.j2
|
|
│ ├── additional_tests.json
|
|
│ └── hints.md
|
|
└── README.md
|
|
```
|
|
|
|
Files:
|
|
|
|
| File | Description | Source |
|
|
|:--- |:--- |:--- |
|
|
| [[EXERCISE].py](exercises/two-fer/two_fer.py) | Solution stub | Manually created by the implementer |
|
|
| [[EXERCISE]_test.py](exercises/two-fer/two_fer_test.py) | Exercise test suite | Automatically generated if `.meta/template.j2` is present, otherwise manually created by the implementer |
|
|
| [example.py](exercises/two-fer/example.py) | Example solution used to automatically verify the `[EXERCISE]_test.py` suite | Manually created by the implementer |
|
|
| [.meta/template.j2](exercises/two-fer/.meta/template.j2) | Test generation template; if present used to automatically generate `[EXERCISE]_test.py` (See [generator documentation](docs/GENERATOR.md)) | Manually created by implementer |
|
|
| [.meta/additional_tests.json](exercises/word-count/.meta/additional_tests.json) | Defines additional track-specific test cases; if `.meta/template.j2` is also present these test will be incorporated into the automatically generated `[EXERCISE]_test.py` | Manually created by the implementer |
|
|
| [.meta/hints.md](exercises/high-scores/.meta/hints.md) | Contains track-specific hints that are automatically included in the generated `README.md` file | Manually created by the implementer |
|
|
| [README.md](exercises/two-fer/README.md) | Exercise README | [Generated by `configlet` tool](#generating-exercise-readmes) |
|
|
|
|
### Generating Exercise READMEs
|
|
|
|
#### Requirements
|
|
- A local clone of the [problem-specifications] repository.
|
|
- [configlet]: may be obtained either by
|
|
- (**Recommended**) Following installation instructions at the above link
|
|
- Running `bin/fetch-configlet` (`configlet` binary will be downloaded to the repository `bin/`)
|
|
|
|
#### Generating all READMEs
|
|
|
|
```
|
|
configlet generate <path/to/track> --spec-path path/to/problem/specifications
|
|
```
|
|
|
|
#### Generating a single README
|
|
|
|
```
|
|
configlet generate <path/to/track> --spec-path path/to/problem/specifications --only example-exercise
|
|
```
|
|
|
|
### Implementing tests
|
|
|
|
If an unimplemented exercise has a `canonical-data.json` file in the [problem-specifications] repository, a generation template must be created. See the [test generator documentation](docs/GENERATOR.md) for more information.
|
|
|
|
If an unimplemented exercise does not have a `canonical-data.json` file, the test file must be written manually (use existing test files for examples).
|
|
|
|
### Example solutions
|
|
|
|
Example solution files serve two purposes:
|
|
|
|
1. Verification of the tests
|
|
2. Example implementation for mentor/student reference
|
|
|
|
### config.json
|
|
|
|
[`config.json`](config.json) is used by the website to determine which exercises to load an in what order. It also contains some exercise metadata, such as difficulty, labels, and if the exercise is a core exercise. New entries should be places just before the first exercise that is marked `"deprecated": true`:
|
|
|
|
```JSON
|
|
{
|
|
"slug": "current-exercise",
|
|
"uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
|
|
"core": false,
|
|
"unlocked_by": null,
|
|
"difficulty": 1,
|
|
"topics": [
|
|
"strings"
|
|
]
|
|
},
|
|
<<< HERE
|
|
{
|
|
"slug": "old-exercise",
|
|
"uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
|
|
"core": false,
|
|
"unlocked_by": null,
|
|
"difficulty": 2,
|
|
"topics": null,
|
|
"status": "deprecated"
|
|
},
|
|
```
|
|
|
|
Fields
|
|
<table>
|
|
<tr>
|
|
<td>slug</td>
|
|
<td>Hyphenated lowercase exercise name</td>
|
|
</tr>
|
|
<tr>
|
|
<td>uuid</td>
|
|
<td>Generate using <code>configlet uuid</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td>core</td>
|
|
<td>Set to <code>false</code>; core exercises are decided by track maintainers</td>
|
|
</tr>
|
|
<tr>
|
|
<td>unlocked_by</td>
|
|
<td>Slug for the core exercise that unlocks the new one</td>
|
|
</tr>
|
|
<tr>
|
|
<td>difficulty</td>
|
|
<td><code>1</code> through <code>10</code>. Discuss with reviewer if uncertain.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>topics</td>
|
|
<td>Array of relevant topics from the <a href="https://github.com/exercism/problem-specifications/blob/master/TOPICS.txt">topics list</a> </td>
|
|
</tr>
|
|
</table>
|
|
|
|
|
|
## Implementing Track-specific Exercises
|
|
|
|
Similar to implementing a canonical exercise that has no `canonical-data.json`, but the exercise README will also need to be written manually. Carefully follow the structure of generated exercise READMEs.
|
|
|
|
|
|
## Pull Request Tips
|
|
|
|
Before committing:
|
|
- Run `configlet fmt` and `configlet lint` before committing if [`config.json`](config.json) has been modified
|
|
- Run [flake8] to ensure all Python code conforms to style standards
|
|
- Run `test/check-exercises.py [EXERCISE]` to check if your test changes function correctly
|
|
- If you modified or created a `hints.md` file, [regenerate the README](#generating-exercise-readmes)
|
|
- If your changes affect multiple exercises, try to break them up into a separate PR for each exercise.
|
|
|
|
|
|
[configlet]: https://github.com/exercism/configlet
|
|
[Exercism contributing guide]: https://github.com/exercism/docs/blob/master/contributing-to-language-tracks/README.md
|
|
[problem-specifications]: https://github.com/exercism/problem-specifications
|
|
[topics list]: https://github.com/exercism/problem-specifications/blob/master/TOPICS.txt
|
|
[flake8]: http://flake8.pycqa.org/
|