forked from exercism/moonscript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadd-practice-exercise
More file actions
executable file
·139 lines (102 loc) · 4.22 KB
/
add-practice-exercise
File metadata and controls
executable file
·139 lines (102 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env bash
# Synopsis:
# Scaffold the files for a new practice exercise.
# After creating the exercise, follow the instructions in the output.
# Example:
# bin/add-practice-exercise two-fer
# Example with difficulty:
# bin/add-practice-exercise -d 5 two-fer
# Example with author and difficulty:
# bin/add-practice-exercise -a foo -d 3 two-fer
set -euo pipefail
scriptname=$0
help_and_exit() {
echo >&2 "Scaffold the files for a new practice exercise."
echo >&2 "Usage: ${scriptname} [-h] [-a author] [-d difficulty] <exercise-slug>"
echo >&2 "Where: author is the GitHub username of the exercise creator."
echo >&2 " : difficulty is between 1 (easiest) to 10 (hardest)."
exit 1
}
die() { echo >&2 "$*"; exit 1; }
required_tool() {
command -v "${1}" >/dev/null 2>&1 ||
die "${1} is required but not installed. Please install it and make sure it's in your PATH."
}
require_files_template() {
jq -e --arg key "${1}" '.files[$key] | length > 0' config.json > /dev/null ||
die "The '.files.${1}' array in the 'config.json' file is empty. Please add at least one file. See https://exercism.org/docs/building/tracks/config-json#h-files for more information."
}
required_tool jq
required_tool curl
require_files_template "solution"
require_files_template "test"
require_files_template "example"
[[ -f ./bin/fetch-configlet ]] || die "Run this script from the repo's root directory."
author=''
difficulty='4'
while getopts :ha:d: opt; do
case $opt in
h) help_and_exit ;;
a) author=$OPTARG ;;
d) difficulty=$OPTARG ;;
?) echo >&2 "Unknown option: -$OPTARG"; help_and_exit ;;
esac
done
shift "$((OPTIND - 1))"
(( $# >= 1 )) || help_and_exit
slug="${1}"
snake_slug=${1//-/_}
if [[ -z "${author}" ]]; then
read -rp 'Your GitHub username: ' author
fi
./bin/fetch-configlet
./bin/configlet create --practice-exercise "${slug}" --author "${author}" --difficulty "${difficulty}"
filter='.exercises.practice |= sort_by(.difficulty, (.name|ascii_upcase))'
jq "${filter}" config.json > config.sorted && mv config.sorted config.json
exercise_dir="exercises/practice/${slug}"
files=$(
jq -r --arg dir "${exercise_dir}" --arg q "'" '
.files
| to_entries
| map({key: .key, value: (.value | map($q + $dir + "/" + . + $q) | join(" and "))})
| from_entries
' "${exercise_dir}/.meta/config.json"
)
cp exercises/practice/hello-world/.busted "exercises/practice/${slug}/.busted"
mkdir -p canonical-data
github="https://raw.githubusercontent.com/exercism/problem-specifications/refs/heads/main/exercises/${slug}/canonical-data.json"
curl -s -o "canonical-data/${slug}.json" "$github"
camel_slug=$(perl -pe 's/(?:^|-)([a-z])/\u$1/g' <<< "$slug")
cat << SPEC_GENERATOR > exercises/practice/${slug}/.meta/spec_generator.moon
{
module_name: '${camel_slug}',
-- or, module_imports: {'func1', 'func2', ...},
-- optional:
test_helpers: [[
A block of code here, indented 2 spaces
]]
generate_test: (case, level) ->
local lines
-- you may want to "switch case.property" here
lines = {
"result = ${camel_slug}.#{case.property} #{case.input}",
"expected = #{quote case.expected}",
"assert.are.equal expected, result"
}
table.concat [indent line, level for line in *lines], '\n'
}
SPEC_GENERATOR
cat << NEXT_STEPS
Your next steps are:
1. Create the test suite ==> $(jq -r '.test' <<< "${files}")
- A stub test generator awaits you --> 'exercises/practice/${slug}/.meta/spec_generator.moon'
- If you don't want it, delete it.
- Otherwise, populate it and run it --> $ bin/generate-spec ${slug}
- The tests should be based on the canonical data --> ./canonical-data/${slug}.json
- Any test cases you don't implement, mark them in 'exercises/practice/${slug}/.meta/tests.toml' with "include = false"
2. Create the example solution ==> $(jq -r '.example' <<< "${files}")
3. Verify the example solution passes the tests ==> $ bin/verify-exercises ${slug}
4. Create the stub solution ==> $(jq -r '.solution' <<< "${files}")
5. Update the 'difficulty' value for the exercise's entry in the 'config.json' file in the repo's root
6. Validate CI using 'bin/configlet lint' and 'bin/configlet fmt'
NEXT_STEPS