Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 7 additions & 14 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,20 @@ on:

jobs:
verify_exercises:
# TODO: replace with another image if required to run the tests (optional)
runs-on: ubuntu-24.04

steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332

# TODO: setup any tooling that is required to run the tests (optional)
# E.g. install a specific version of a programming language
# E.g. install packages via apt/apk/yum/etc.
# Find GitHub Actions to setup tooling here:
# - https://github.com/actions/?q=setup&type=&language=
# - https://github.com/actions/starter-workflows/tree/main/ci
# - https://github.com/marketplace?type=actions&query=setup
# - name: Use <setup tooling>
# uses: <action to setup tooling>
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 24.x
cache: "npm"

# TODO: install any dependencies (optional)
# E.g. npm install, bundle install, etc.
# - name: Install project dependencies
# run: <install dependencies>
- name: Install dependencies
run: npm ci

- name: Verify all exercises
run: bin/verify-exercises
5 changes: 5 additions & 0 deletions .gitignore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This .gitignore is for the students, correct? It probably should only be for build artifacts like node_modules then. There's extra stuff in here they wouldn't be using like configlet

Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ bin/configlet.exe
bin/latest-configlet.tar.gz
bin/latest-configlet.zip
bin/configlet.zip
node_modules

tmp
exercises/**/.gitignore
lib
57 changes: 57 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
.DEFAULT_GOAL := test

EXERCISE ?= ""
EXERCISES = $(shell find ./exercises/practice -maxdepth 1 -mindepth 1 -type d | cut -s -d '/' -f4 | sort)
OUTDIR ?= "tmp"

# check all package.json and package-lock.json are matching
check-package-files:
@echo "Validation package.json files..."
@for pkg in $(PKG_FILES); do \
! ./bin/md5-hash $$pkg | grep -qv $(SOURCE_PKG_MD5) || { echo "$$pkg does not match main package.json. Please run 'make sync-package-files' locally and commit the results."; exit 1; }; \
done
@echo "Validation package-lock.json files..."
@for pkg in $(PKG_LOCK_FILES); do \
! ./bin/md5-hash $$pkg | grep -qv $(SOURCE_PKG_LOCK_MD5) || { echo "$$pkg does not match main package.json. Please run 'make sync-package-files' locally and commit the results."; exit 1; }; \
done
@echo "package-file check complete..."

# copy package.json and package-lock.json for single exercise
copy-package-file:
@cp package.json exercises/practice/$(EXERCISE)/package.json
@cp package-lock.json exercises/practice/$(EXERCISE)/package-lock.json
@cp rescript.json exercises/practice/$(EXERCISE)/rescript.json

# copy package files to all exercise directories
sync-package-files:
@echo "Syncing package.json and package-lock.json..."
@for exercise in $(EXERCISES); do EXERCISE=$$exercise $(MAKE) -s copy-package-file || exit 1; done

copy-exercise:
if [ -f exercises/practice/$(EXERCISE)/src/*.res ]; then \
echo "Copying $(EXERCISE)"; \
cp exercises/practice/$(EXERCISE)/.meta/*.res $(OUTDIR)/src/; \
cp exercises/practice/$(EXERCISE)/tests/*.res $(OUTDIR)/tests/; \
fi

copy-all-exercises:
@echo "Copying exercises for testing..."
@mkdir -p $(OUTDIR)/src
@mkdir -p $(OUTDIR)/tests
@for exercise in $(EXERCISES); do EXERCISE=$$exercise $(MAKE) -s copy-exercise || exit 1; done

# Remove the OUTDIR
clean:
@echo "Cleaning tmp directory..."
@rm -rf $(OUTDIR)

# Format all ReScript files in the project
format:
@echo "Formatting ReScript files..."
@find . -name "node_modules" -prune -o -name "*.res" -print -o -name "*.resi" -print | xargs npx rescript format

test:
$(MAKE) -s clean
$(MAKE) -s check-package-files
$(MAKE) -s copy-all-exercises
npm run ci
17 changes: 8 additions & 9 deletions bin/verify-exercises
Original file line number Diff line number Diff line change
Expand Up @@ -42,33 +42,32 @@ unskip_tests() {
}

run_tests() {
noop # TODO: replace this with the command to run the tests for the exercise.
# Note: this function runs from within an exercise directory.
# Note: the exercise directory is a temporary directory, so feel
# free to modify its files as needed.
# Note: return a zero exit code if all tests pass, otherwise non-zero.
# Example: `npm test`
# Example: `python3 -m pytest two_fer_test.py`
node_modules/.bin/rescript
node_modules/.bin/retest tests/*.js
}

verify_exercise() {
local dir
local slug
local tmp_dir
local root_dir

root_dir=$(realpath .) # capture project root before cd-ing away
dir=$(realpath "${1}")
slug=$(basename "${dir}")
tmp_dir=$(mktemp -d -t "exercism-verify-${slug}-XXXXX")

echo "Verifying ${slug} exercise..."

(
trap 'rm -rf "$tmp_dir"' EXIT # remove tempdir when subshell ends
trap 'rm -rf "$tmp_dir"' EXIT
cp -r "${dir}/." "${tmp_dir}"
cd "${tmp_dir}"

ln -s "${root_dir}/node_modules" "${tmp_dir}/node_modules"

copy_example_or_examplar_to_solution
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
copy_example_or_examplar_to_solution
copy_example_or_exemplar_to_solution

unskip_tests
#unskip_tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we committing to having all tests run every time? I believe we can still test.skip every test after the first one.

run_tests
)
}
Expand Down
92 changes: 80 additions & 12 deletions config.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,98 @@
{
"language": "ReScript",
"slug": "rescript",
"active": false,
"active": true,
"status": {
"concept_exercises": false,
"test_runner": false,
"representer": false,
"analyzer": false
},
"blurb": "TODO: add blurb",
"blurb": "ReScript is a strongly typed functional language which compiles to both Javascript and native.",
"version": 3,
"online_editor": {
"indent_style": "space",
"indent_size": 4
"indent_size": 2,
"highlightjs_language": "reasonml"
},
"test_runner": {
"average_run_time": 7
},
"files": {
"solution": [],
"test": [],
"example": [],
"exemplar": []
"solution": [
"src/%{pascal_slug}.re"
],
"test": [
"__tests__/%{pascal_slug}_test.re"
],
"example": [
"src/Example.re"
],
"exemplar": [
".meta/src/Exemplar.re"
],
"editor": [
"src/%{pascal_slug}.rei"
]
},
"exercises": {
"concept": [],
"practice": []
"practice": [
{
"slug": "hello-world",
"name": "Hello World",
"uuid": "63d72b81-c7a4-4a94-8224-69f4c68cc374",
"practices": [],
"prerequisites": [],
"difficulty": 1,
"topics": [
"setting_up_reasonml_dev_environment",
"strings"
]
}
]
},
"concepts": [],
"key_features": [],
"tags": []
"key_features": [
{
"title": "OCaml's type system",
"content": "ReScript brings OCaml's battle-tested powerful type system to Javascript.",
"icon": "stable"
},
{
"title": "Inferred types",
"content": "No need to specify types, types are inferred by ReScript compiler and are guaranteed to be correct.",
"icon": "immutable"
},
{
"title": "Functional Programming",
"content": "Like OCaml, ReScript is a functional programming language with pattern matching, variants and more.",
"icon": "functional"
},
{
"title": "Easy javascript interop",
"content": "Javascript interop is easy allowing advatange of existing javascript packages and ecosystem.",
"icon": "interop"
},
{
"title": "Fast compiler",
"content": "ReScript compilation times are super fast which means fast iteration cycles.",
"icon": "fast"
},
{
"title": "Refactor with ease",
"content": "Compiler guides you through all places that need to be fixed during refactor until it just works.",
"icon": "fun"
}
],
"tags": [
"execution_mode/compiled",
"paradigm/functional",
"platform/linux",
"platform/mac",
"platform/web",
"platform/windows",
"typing/static",
"typing/strong",
"used_for/frontends",
"used_for/web_development"
]
}
15 changes: 15 additions & 0 deletions exercises/practice/hello-world/.docs/instructions.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an old set of instructions. We don't need to do it right this moment, but before launch, let's make sure to have configlet sync docs and metadata for everything.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Instructions

The classical introductory exercise. Just say "Hello, World!".

["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is
the traditional first program for beginning programming in a new language
or environment.

The objectives are simple:

- Write a function that returns the string "Hello, World!".
- Run the test suite and make sure that it succeeds.
- Submit your solution and check it at the website.

If everything goes well, you will be ready to fetch your first real exercise.
1 change: 1 addition & 0 deletions exercises/practice/hello-world/.meta/HelloWorld.res
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let hello = () => "Hello, World!"
25 changes: 25 additions & 0 deletions exercises/practice/hello-world/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"authors": [
"tejasbubane"
],
"contributors": [
"naartjie",
"ohana54",
"son1112",
"stevejb71"
],
"files": {
"solution": [
"src/HelloWorld.res"
],
"test": [
"tests/HelloWorld_test.res"
],
"example": [
".meta/HelloWorld.res"
]
},
"blurb": "The classical introductory exercise. Just say \"Hello, World!\"",
"source": "This is an exercise to introduce users to using Exercism",
"source_url": "http://en.wikipedia.org/wiki/%22Hello,_world!%22_program"
}
13 changes: 13 additions & 0 deletions exercises/practice/hello-world/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[af9ffe10-dc13-42d8-a742-e7bdafac449d]
description = "Say Hi!"
21 changes: 21 additions & 0 deletions exercises/practice/hello-world/LICENSE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this LICENSE file?

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 Exercism

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading