From f102fed52288afe0f1ab31cca27381d1c2cbcc65 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 11:09:08 +0100 Subject: [PATCH 01/11] improve developer docs in readme --- README.md | 136 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 102 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 27760f9..95ecfde 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,94 @@ Exercism exercises in ReScript. +## Installation + +The exercises in this langauge are written in [ReScript] v12. + +### Prerequisites + +- [Node.js] >= 22 +- A package manager of your choice e.g. NPM (pre-installed with Node.js), PNPM etc. +- [make](https://www.gnu.org/software/make/) - look up OS specific installation guides + +### Setting up the development environment + +Run the following commands to install the required tools: + +```shell +npm install +git submodule update --init --recursive +``` + +If you have format on save enabled for JSON files, it is recommended to disable this feature. Alternatively save JSON files with `Ctrl+K s` to save without applying formatting rules. + +### Running the development environment + +Open up two terminals. By running the commands below, files will compile on save and re-run the test suite. + +```shell +# Terminal 1 +npm run res:start + +# Terminal 2 +npm run test +``` + +## Coding Style + +Use `PascalCase.res` for Reason implementation file names. +A ReScript interface file (`.resi`) should be included with every exercise to help the user get started. + +Run `make format` on your code before pushing. + +If you are using VS Code, install the official [ReScript VS Code extension](https://marketplace.visualstudio.com/items?itemName=chenglou92.rescript-vscode) for syntax highlighting and code formatting. + +## Adding Exercises + +New practice exercises can be added via: + +```shell +bin/add-practice-exercise + +# Optionally, you can also specify the exercise's difficulty (via `-d`) and/or author's GitHub username (via `-a`): +bin/add-practice-exercise -a foobar -d 3 +``` + +Now complete the following steps: + +- `config.json` - ensure that the new exercise data is correctly placed in order of difficulty and then alphabetically within that difficulty rating. +- implement exercise test cases, detailed in the [testing](#testing) section below. +- `exercises/practice//.meta/.res` - write an example of code here that will pass all test cases. This does not need to be the finest example of how to complete this exercise, but it must pass all the test cases. Update the interface file with the exposed function signatures in the `.resi` file. +- `exercises/practice//wrc/.res` - create an exercise stub here which returns `panic("'' has not been implemented")`. Update the interface file with the function signatures, so that the student has a reference to what names and types are used. + ## Testing -To test all exercises, run `./bin/verify-exercises`. -This command will iterate over all exercises and check to see if their exemplar/example implementation passes all the tests. +Tests are written using [rescript-test](https://bloodyowl.github.io/rescript-test/). There is a test templating system in place to reduce the amount of work needed by a developer. Follow these steps when writing tests: -To test a single exercise, run `./bin/verify-exercises `. +- `exercises/practice//.meta/tests.toml` - if any of these test cases are not relevant to the language, add `ignore = true` on a newline below the description +- `exercises/practice//.meta/testTemplate.js` - edit this file to allow the test generator to automatically create test files. + - you must write your comparator functions - https://bloodyowl.github.io/rescript-test/assertions. + - common assertions with comparator functions are located at `test_generator/assertions.js`. Pass the required ones into the `assertionFunctions` array. + - edit the `template` function so that it will generate the test cases. The `c` variable refers to a test case in `problem-specifications/exercises//canonical-data.json`. Look at other exercise test templates for inspiration. -### Using Docker +Run all exercise tests: + +```shell +make test +``` + +This command will iterate over all exercises and check to see if their example implementation passes all the tests. + +To test that all exercises will pass in the CI/CD environment, run: + +```shell +./bin/verify-exercises + +# test a single exercise: +./bin/verify-exercises +``` + + -### Linting +## Linting & Formatting [`configlet`](https://exercism.org/docs/building/configlet) is an Exercism-wide tool for working with tracks. You can download it by running: ```shell -$ ./bin/fetch-configlet +./bin/fetch-configlet ``` -Run its [`lint` command](https://exercism.org/docs/building/configlet/lint) to verify if exercises have the required files and if config files are correct: +Run the [`lint` command][configlet-link-link] to verify if exercises have the required files and if config files are correct. Address any issues before pushing your changes: ```shell -$ ./bin/configlet lint - -The lint command is under development. -Please re-run this command regularly to see if your track passes the latest linting rules. - -Basic linting finished successfully: -- config.json exists and is valid JSON -- config.json has these valid fields: - language, slug, active, blurb, version, status, online_editor, key_features, tags -- Every concept has the required .md files -- Every concept has a valid links.json file -- Every concept has a valid .meta/config.json file -- Every concept exercise has the required .md files -- Every concept exercise has a valid .meta/config.json file -- Every practice exercise has the required .md files -- Every practice exercise has a valid .meta/config.json file -- Required track docs are present -- Required shared exercise docs are present +./bin/configlet lint ``` -## Adding exercises - -New (practice) exercises can be added via: +Run the [`fmt` command][configlet-fmt-link] to verify if exercises and configuration files are formatted correctly. Address any issues before pushing your changes: ```shell -bin/add-practice-exercise -``` +./bin/configlet fmt -Optionally, you can also specify the exercise's difficulty (via `-d`) and/or author's GitHub username (via `-a`): +# check a single exercise +./bin/configlet -e -```shell -bin/add-practice-exercise -a foobar -d 3 +# auto format files +./bin/configlet fmt -u ``` + +If you are auto formatting files, only commit the files relevant to your pull request. + +[ReScript]: https://rescript-lang.org/ +[Node.js]: https://nodejs.org/ +[configlet-lint-link]: https://exercism.org/docs/building/configlet/lint +[configlet-fmt-link]: https://exercism.org/docs/building/configlet/fmt From 810695da12f681252ae66024493412e67c652a4f Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 11:16:35 +0100 Subject: [PATCH 02/11] add fork and clone info --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 95ecfde..5fd8ce9 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,16 @@ The exercises in this langauge are written in [ReScript] v12. ### Setting up the development environment -Run the following commands to install the required tools: +Make a fork of the ReScript languge track GitHub [repository]. Clone your fork onto your machine: + +```shell +# assuming you didn't change the repository name +git clone https://github.com//rescript.git +cd rescript +vscode . +``` + +Run the following commands from inside to install the required tools: ```shell npm install @@ -133,5 +142,6 @@ If you are auto formatting files, only commit the files relevant to your pull re [ReScript]: https://rescript-lang.org/ [Node.js]: https://nodejs.org/ +[repository]: https://github.com/exercism/rescript [configlet-lint-link]: https://exercism.org/docs/building/configlet/lint [configlet-fmt-link]: https://exercism.org/docs/building/configlet/fmt From a926a2c8d95b57a76b89cf20e3a38acd42f10fe1 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 11:19:01 +0100 Subject: [PATCH 03/11] add feedback, copied form ocaml track --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 5fd8ce9..0ba7ec7 100644 --- a/README.md +++ b/README.md @@ -140,8 +140,13 @@ Run the [`fmt` command][configlet-fmt-link] to verify if exercises and configura If you are auto formatting files, only commit the files relevant to your pull request. +## Feedback + +If you find this documentation is inaccurate or incomplete, or can be improved in any way, please don't hesitate to raise an [issue][issue-link] or submit a pull request. + [ReScript]: https://rescript-lang.org/ [Node.js]: https://nodejs.org/ [repository]: https://github.com/exercism/rescript +[issue-link]: https://github.com/exercism/rescript/issues [configlet-lint-link]: https://exercism.org/docs/building/configlet/lint [configlet-fmt-link]: https://exercism.org/docs/building/configlet/fmt From 96c6523f7a55571b3904560063ed8960f982c65f Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 11:28:44 +0100 Subject: [PATCH 04/11] add relevant exercism doc links --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ba7ec7..8a0e469 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ cd rescript vscode . ``` -Run the following commands from inside to install the required tools: +Run the following commands from inside the project root directory to install the required tools: ```shell npm install @@ -57,6 +57,8 @@ If you are using VS Code, install the official [ReScript VS Code extension](http ## Adding Exercises +Documentation on contributing to Exercism can be found [here][exercism-contributing-docs-link]. + New practice exercises can be added via: ```shell @@ -140,6 +142,14 @@ Run the [`fmt` command][configlet-fmt-link] to verify if exercises and configura If you are auto formatting files, only commit the files relevant to your pull request. +## Pull Requests + +Familiarise yourself with the Exercism [documentation][exercism-pr-docs-link] on pull requests. + +Make sure your work is commited on a new branch. When you are ready to submit your changes, push your changes to your forked repository and open a pull request on the language track [repository]. + +More details on how to create pull requests from a fork can be found [here][github-fork-pr-link]. + ## Feedback If you find this documentation is inaccurate or incomplete, or can be improved in any way, please don't hesitate to raise an [issue][issue-link] or submit a pull request. @@ -150,3 +160,6 @@ If you find this documentation is inaccurate or incomplete, or can be improved i [issue-link]: https://github.com/exercism/rescript/issues [configlet-lint-link]: https://exercism.org/docs/building/configlet/lint [configlet-fmt-link]: https://exercism.org/docs/building/configlet/fmt +[github-fork-pr-link]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork +[exercism-pr-docs-link]: https://exercism.org/docs/building/github/contributors-pull-request-guide +[exercism-contributing-docs-link]: https://exercism.org/docs/building From a36589c7c78f3c06df71915677a6ba5dcd3818eb Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 12 Mar 2026 12:03:42 +0100 Subject: [PATCH 05/11] remove repo fork info --- README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/README.md b/README.md index 8a0e469..fb54f8a 100644 --- a/README.md +++ b/README.md @@ -16,15 +16,6 @@ The exercises in this langauge are written in [ReScript] v12. ### Setting up the development environment -Make a fork of the ReScript languge track GitHub [repository]. Clone your fork onto your machine: - -```shell -# assuming you didn't change the repository name -git clone https://github.com//rescript.git -cd rescript -vscode . -``` - Run the following commands from inside the project root directory to install the required tools: ```shell From bd1b5fc22081a1d1545850579455fe5040f992bd Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 12 Mar 2026 12:04:21 +0100 Subject: [PATCH 06/11] update configlet fmt typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fb54f8a..146f48d 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ Run the [`fmt` command][configlet-fmt-link] to verify if exercises and configura ./bin/configlet fmt # check a single exercise -./bin/configlet -e +./bin/configlet fmt -e # auto format files ./bin/configlet fmt -u From b0009526195282809824c2458c575cc8b38c2b60 Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 12 Mar 2026 12:09:45 +0100 Subject: [PATCH 07/11] update installation / prerequisites section --- README.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 146f48d..8385697 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,7 @@ Exercism exercises in ReScript. ## Installation -The exercises in this langauge are written in [ReScript] v12. - -### Prerequisites - -- [Node.js] >= 22 -- A package manager of your choice e.g. NPM (pre-installed with Node.js), PNPM etc. -- [make](https://www.gnu.org/software/make/) - look up OS specific installation guides +Track exercises target [Rescript] 12.2.0 using the [ReScript Test][ReScriptTest] testing framework on [Node.js] 22+. If you're contributing to the track, you will also need [make](https://www.gnu.org/software/make/). ### Setting up the development environment @@ -146,6 +140,7 @@ More details on how to create pull requests from a fork can be found [here][gith If you find this documentation is inaccurate or incomplete, or can be improved in any way, please don't hesitate to raise an [issue][issue-link] or submit a pull request. [ReScript]: https://rescript-lang.org/ +[ReScriptTest]: https://bloodyowl.github.io/rescript-test/ [Node.js]: https://nodejs.org/ [repository]: https://github.com/exercism/rescript [issue-link]: https://github.com/exercism/rescript/issues From cd3e0d96bf01c9109dbd6a26f7dafcb4cd9e008d Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 12 Mar 2026 12:18:08 +0100 Subject: [PATCH 08/11] add submodule explanation --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8385697..81dad4f 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,11 @@ Run the following commands from inside the project root directory to install the ```shell npm install -git submodule update --init --recursive +git submodule update --init --recursive # add/update a local copy of the problem-specification submodule ``` +To automate the creation of practice exercise tests, our track tooling consumes data from the the [problem specifications][exercism-problem-specifications-link] submodule. Because these specifications serve as the canonical source for all Exercism tracks, any upstream updates ensure our test cases remain consistent with the global exercise standard. + If you have format on save enabled for JSON files, it is recommended to disable this feature. Alternatively save JSON files with `Ctrl+K s` to save without applying formatting rules. ### Running the development environment @@ -149,3 +151,4 @@ If you find this documentation is inaccurate or incomplete, or can be improved i [github-fork-pr-link]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork [exercism-pr-docs-link]: https://exercism.org/docs/building/github/contributors-pull-request-guide [exercism-contributing-docs-link]: https://exercism.org/docs/building +[exercism-problem-specifications-link]: https://github.com/exercism/problem-specifications From 78056de164fbc17f368174904e53c631ff0f1110 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 31 Mar 2026 09:26:05 +0200 Subject: [PATCH 09/11] basic changes --- README.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 81dad4f..487290c 100644 --- a/README.md +++ b/README.md @@ -36,11 +36,18 @@ npm run test ## Coding Style Use `PascalCase.res` for Reason implementation file names. -A ReScript interface file (`.resi`) should be included with every exercise to help the user get started. +A ReScript [interface file][rescript-interface-file-link] (`.resi`) should be included with every exercise to help the user get started. +For example: + +```shell +# exercises/practice//.meta/Example.resi +let add: (int, int) => int +``` Run `make format` on your code before pushing. -If you are using VS Code, install the official [ReScript VS Code extension](https://marketplace.visualstudio.com/items?itemName=chenglou92.rescript-vscode) for syntax highlighting and code formatting. +If you are using VS Code, install the official [ReScript VS Code extension](https://marketplace.visualstudio.com/items?itemName=chenglou92.rescript-vscode) for syntax highlighting and code formatting. Unofficial plugins exist for JetBrains products. +Terminal based text editors often work with the [ReScript Language Server][rescript-language-server-link] installed. Refer to the documentation of your text editor / IDE for further instructions ## Adding Exercises @@ -60,7 +67,7 @@ Now complete the following steps: - `config.json` - ensure that the new exercise data is correctly placed in order of difficulty and then alphabetically within that difficulty rating. - implement exercise test cases, detailed in the [testing](#testing) section below. - `exercises/practice//.meta/.res` - write an example of code here that will pass all test cases. This does not need to be the finest example of how to complete this exercise, but it must pass all the test cases. Update the interface file with the exposed function signatures in the `.resi` file. -- `exercises/practice//wrc/.res` - create an exercise stub here which returns `panic("'' has not been implemented")`. Update the interface file with the function signatures, so that the student has a reference to what names and types are used. +- `exercises/practice//src/.res` - create an exercise stub here which returns `panic("'' has not been implemented")`. Update the interface file with the function signatures, so that the student has a reference to what names and types are used. ## Testing @@ -72,7 +79,7 @@ Tests are written using [rescript-test](https://bloodyowl.github.io/rescript-tes - common assertions with comparator functions are located at `test_generator/assertions.js`. Pass the required ones into the `assertionFunctions` array. - edit the `template` function so that it will generate the test cases. The `c` variable refers to a test case in `problem-specifications/exercises//canonical-data.json`. Look at other exercise test templates for inspiration. -Run all exercise tests: +Run all exercise's tests: ```shell make test @@ -80,7 +87,7 @@ make test This command will iterate over all exercises and check to see if their example implementation passes all the tests. -To test that all exercises will pass in the CI/CD environment, run: +To test that the example solution will pass the test suite, run: ```shell ./bin/verify-exercises @@ -152,3 +159,5 @@ If you find this documentation is inaccurate or incomplete, or can be improved i [exercism-pr-docs-link]: https://exercism.org/docs/building/github/contributors-pull-request-guide [exercism-contributing-docs-link]: https://exercism.org/docs/building [exercism-problem-specifications-link]: https://github.com/exercism/problem-specifications +[rescript-language-server-link]: https://www.npmjs.com/package/@rescript/language-server +[rescript-interface-file-link]: https://rescript-lang.org/docs/manual/module#every-resi-file-is-a-signature From 6912de78cc0ce5e2cb93a3c02d7cc24c0842ed60 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 1 Apr 2026 11:18:13 +0200 Subject: [PATCH 10/11] add instructions for running a single exercise's tests --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 487290c..d779364 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,12 @@ Tests are written using [rescript-test](https://bloodyowl.github.io/rescript-tes - common assertions with comparator functions are located at `test_generator/assertions.js`. Pass the required ones into the `assertionFunctions` array. - edit the `template` function so that it will generate the test cases. The `c` variable refers to a test case in `problem-specifications/exercises//canonical-data.json`. Look at other exercise test templates for inspiration. +Run a single exercise's tests: + +```shell +make test EXERCISE= +``` + Run all exercise's tests: ```shell From e2f1db15587636e1a7113d00627421872bcdc8bb Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 1 Apr 2026 13:02:26 +0200 Subject: [PATCH 11/11] new exercise creation workflow - draft 1 --- README.md | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 100 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d779364..2de07ac 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ npm run test ## Coding Style Use `PascalCase.res` for Reason implementation file names. + A ReScript [interface file][rescript-interface-file-link] (`.resi`) should be included with every exercise to help the user get started. For example: @@ -47,13 +48,20 @@ let add: (int, int) => int Run `make format` on your code before pushing. If you are using VS Code, install the official [ReScript VS Code extension](https://marketplace.visualstudio.com/items?itemName=chenglou92.rescript-vscode) for syntax highlighting and code formatting. Unofficial plugins exist for JetBrains products. + Terminal based text editors often work with the [ReScript Language Server][rescript-language-server-link] installed. Refer to the documentation of your text editor / IDE for further instructions -## Adding Exercises +## Contributing to Exercises + +Contributing to the exercises in this track can involve: adding a new exercise, updating an existing one, or managing the test suite. Documentation on contributing to Exercism can be found [here][exercism-contributing-docs-link]. -New practice exercises can be added via: +### Adding a new exercise + +To introduce a brand new practice exercise to the track, follow these steps: + +- **Initialise the exercise:** Run the generator script to create the folder structure and boilerplate. ```shell bin/add-practice-exercise @@ -62,6 +70,91 @@ bin/add-practice-exercise bin/add-practice-exercise -a foobar -d 3 ``` +- **Register the exercise:** Open the root `config.json` file. Update the difficulty rating of the exercise, and then ensure that that exercise is correctly placed in order of difficulty and then alphabetically within that difiiculty rating. + +- **Create the stub:** In `exercises/practice//src/`, modify the .res file to return `panic("'' has not been implemented")`. + +- **Define the interface:** Update the .resi (interface) file in `exercises/practice//src/` and `exercises/practice//.meta/` directories to include the function signatures. This provides students with the necessary type hints. + +- **Generate test cases:** Follow the steps in the [Generating and managing tests](#generating-and-managing-tests) subsection below. + +- **Provide an example solution:** In `exercises/practice//.meta/`, implement a working solution in the .res file. This does not need to be an exemplar solution, but must pass all test cases. + +### Generating and managing tests + +We use a templating system to keep tests consistent with Exercism's canonical data found in the problem-specification git submodule. + +Tests are written using [rescript-test](https://bloodyowl.github.io/rescript-test/). Follow these steps when writing tests: + +- **Filter canonical data:** Open `exercises/practice//.meta/tests.toml`. If a specific canonical test case is not applicable to ReScript, add ignore = true below its description. E.g. + +```toml +[7ee45d52-5d35-4fbd-b6f1-5c8cd8a67f18] +description = "Seven-digit number that is not an Armstrong number" + +[5ee2fdf8-334e-4a46-bb8d-e5c19c02c148] +description = "Armstrong number containing seven zeroes" +include = false + +[12ffbf10-307a-434e-b4ad-c925680e1dd4] +description = "The largest and last Armstrong number" +include = false +``` + +- **Configure the test template:** Edit `test_templates/_template.res`. Delete and uncomment the code where indicated. Use previous templates as examples of how to achieve what you need. Common comparator functions are found in `test_generator/Assertions.res` + +- **Generate and run tests:** To build the test file and run it, run `make test EXERCISE=`. Your generated test cases are found in `exercises//tests/_test.res`. Verify that the test cases accept and return the correct data. + +- **Creating new comparator functions:** If none of the comparator functions satisfy the exercise's test requirements, you can write a new one in `test_generator/Assertions.res` and `test_generator/AssersionGenerators.res`, following the guidelines at https://bloodyowl.github.io/rescript-test/assertions. The function should be returned as a string, so that our templating system can inject the code into the generated tests. + +### Updating an existing exercise + +When syncing with upstream changes or fixing bugs: + +- **Update an exercise:** Modify the exercise files within the `.meta/` folder to reflect changes to the exercise, such as ignored tests or signature changes. + +- **Sync interface files:** If the function signature changes, ensure both the stub interface at `src/_.resi` and the example interface at `.meta/_.resi` are updated to match. + +- **Verify integrity:** Run the full test suite to ensure no regressions with `make test`. + +### Running tests + +- Run a single exercise's tests: + +```shell +make test EXERCISE= +``` + +- Run all exercise's tests: + +```shell +make test +``` + +This command will iterate over all exercises and check to see if their example implementation passes all the tests. + +- It is worth running the below commands to test if the code will likely pass CI checks for test cases: + +````shell +./bin/verify-exercises + +# test a single exercise: +./bin/verify-exercises +``` --> + + @@ -148,6 +241,8 @@ Familiarise yourself with the Exercism [documentation][exercism-pr-docs-link] on Make sure your work is commited on a new branch. When you are ready to submit your changes, push your changes to your forked repository and open a pull request on the language track [repository]. +When committing your changes to version control, ensure that only the files relevant to the current pull request are committed. + More details on how to create pull requests from a fork can be found [here][github-fork-pr-link]. ## Feedback