Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup Hello World exercise #3

Merged
merged 1 commit into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
20 changes: 20 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: GDScript / Lint

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

jobs:
lint:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

- name: Setup gdtoolkit
uses: Scony/godot-gdscript-toolkit@09af1747fd66629af601b1f14d1ac24203358686

- name: Lint
run: gdlint exercises
12 changes: 4 additions & 8 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# Requires scripts:
# - bin/test

name: <track> / Test
name: GDScript / Test

on:
push:
Expand All @@ -23,17 +23,13 @@ on:

jobs:
ci:
runs-on: <image-name>
runs-on: ubuntu-22.04
container:
image: exercism/gdscript-test-runner

steps:
- name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

- name: Use <setup tooling>
uses: <action to setup tooling>

- name: Install project dependencies
run: <install dependencies>

- name: Verify all exercises
run: bin/verify-exercises
42 changes: 24 additions & 18 deletions bin/verify-exercises
Original file line number Diff line number Diff line change
@@ -1,35 +1,41 @@
#!/usr/bin/env bash

# Synopsis:
# Test the track's exercises.
#
# At a minimum, this file must check if the example/exemplar solution of each
# Practice/Concept Exercise passes the exercise's tests.
#
# To check this, you usually have to (temporarily) replace the exercise's solution files
# with its exemplar/example files.
#
# If your track uses skipped tests, make sure to (temporarily) enable these tests
# before running the tests.
#
# The path to the solution/example/exemplar files can be found in the exercise's
# .meta/config.json file, or possibly inferred from the exercise's directory name.
temp_dir_base=$(mktemp -d)
echo $(godot --version)

# Example:
# ./bin/test
run_test() {
slug=$(basename $1)
temp_dir=${temp_dir_base}/${slug}
mkdir -p ${temp_dir}
# Copy relevant files to the temp directory (replace solution with example)
solution_file_name="$(jq -r '.files.solution[0]' $1/.meta/config.json)"
test_file="$1/$(jq -r '.files.test[0]' $1/.meta/config.json)"
example_file="$1/$(jq -r '.files.example[0]' $1/.meta/config.json)"
cp ${test_file} ${temp_dir}
cp ${example_file} "${temp_dir}/${solution_file_name}"
# Run the tests
(cd /opt/test-runner && bin/run.sh $slug $temp_dir $temp_dir) || exit 1
# Check status
test_status="$(jq -r '.status' $temp_dir/results.json)"
if [ "$test_status" != "pass" ]; then
echo "Tests for $slug have failed:"
cat $temp_dir/results.json
exit 1
fi
}

# Verify the Concept Exercises
for concept_exercise_dir in ./exercises/concept/*/; do
if [ -d $concept_exercise_dir ]; then
echo "Checking $(basename "${concept_exercise_dir}") exercise..."
# TODO: run command to verify that the exemplar solution passes the tests
run_test $concept_exercise_dir
fi
done

# Verify the Practice Exercises
for practice_exercise_dir in ./exercises/practice/*/; do
if [ -d $practice_exercise_dir ]; then
echo "Checking $(basename "${practice_exercise_dir}") exercise..."
# TODO: run command to verify that the example solution passes the tests
run_test $practice_exercise_dir
fi
done
21 changes: 17 additions & 4 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@
"active": false,
"status": {
"concept_exercises": false,
"test_runner": false,
"test_runner": true,
"representer": false,
"analyzer": false
},
"blurb": "TODO: add blurb",
"blurb": "GDScript is a high-level, object-oriented, imperative, and gradually typed programming language built for Godot. It uses an indentation-based syntax similar to languages like Python. Its goal is to be optimized for and tightly integrated with Godot Engine, allowing great flexibility for content creation and integration.",
"version": 3,
"online_editor": {
"indent_style": "space",
"indent_style": "tab",
"indent_size": 4,
"highlightjs_language": "gdscript"
},
"test_runner": {
"average_run_time": 2
},
"files": {
"solution": ["%{snake_slug}.gd"],
"test": ["%{snake_slug}_test.gd"],
Expand All @@ -23,12 +26,22 @@
},
"exercises": {
"concept": [],
"practice": []
"practice": [
{
"uuid": "1adfc420-46f2-4d5b-93a3-165ede1fcd9f",
"slug": "hello-world",
"name": "Hello World",
"practices": [],
"prerequisites": [],
"difficulty": 1
}
]
},
"concepts": [],
"key_features": [],
"tags": [
"paradigm/object_oriented",
"typing/static",
"typing/dynamic",
"execution_mode/interpreted",
"platform/windows",
Expand Down
16 changes: 16 additions & 0 deletions exercises/practice/hello-world/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Instructions

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

["Hello, World!"][hello-world] is the traditional first program for beginning programming in a new language or environment.

The objectives are simple:

- Modify the provided code so that it produces 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.

[hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program
22 changes: 22 additions & 0 deletions exercises/practice/hello-world/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"authors": [
"pfertyk"
],
"contributors": [
"BNAndras"
],
"files": {
"solution": [
"hello_world.gd"
],
"test": [
"hello_world_test.gd"
],
"example": [
".meta/example.gd"
]
},
"blurb": "The classical introductory exercise. Just say \"Hello, World!\".",
"source": "This is an exercise to introduce users to using Exercism",
"source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program"
}
2 changes: 2 additions & 0 deletions exercises/practice/hello-world/.meta/example.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
func hello():
return "Hello, World!"
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!"
2 changes: 2 additions & 0 deletions exercises/practice/hello-world/hello_world.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
func hello():
return "Goodbye, Mars!"
2 changes: 2 additions & 0 deletions exercises/practice/hello-world/hello_world_test.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
func test_hello_world(solution_script):
return ["Hello, World!", solution_script.hello()]
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

Minor nitpick but the indent seems larger here than in hello_world.gd so one of them probably needs to be updated to match the other.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, I've missed this 👍 Since Godot editor uses tabs by default, I think we should use them too (consistently, in all files). I've already changed the files :)

Side note: I think that Godot will accept both types of indentation, as long as they are consistent within a file, but there is no need to confuse GDScript learners :P

Copy link
Sponsor Member

Choose a reason for hiding this comment

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

Okay, I think you just need to ping Erik to take a final look.

Copy link
Sponsor Member

Choose a reason for hiding this comment

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

It might be good to choose a formatter / linter if available to make sure everything is consistent between contributors and PRs. https://github.com/Scony/godot-gdscript-toolkit seems promising since it has both. There's a GitHub Action for static analysis, but we could also use the CI for checking if a PR is well-formatted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added a new workflow with that toolkit. It does detect some errors (e.g. an unnecessary return) but it doesn't detect things like mixed indent (tabs vs spaces). Nevertheless, I think it's a good idea to have the linter already configured, as it might get better in the future, and it already helps a bit. Thanks for this suggestion! ;)