Skip to content

Commit

Permalink
Merge branch 'main' into isogram
Browse files Browse the repository at this point in the history
  • Loading branch information
tasxatzial authored Jan 11, 2025
2 parents 67f9480 + 15fe19e commit d6411d9
Show file tree
Hide file tree
Showing 321 changed files with 1,818 additions and 910 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,26 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
path: main

- name: Checkout test runner
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: exercism/clojure-test-runner
path: clojure-test-runner

- name: setup babashka
uses: turtlequeue/setup-babashka@2d4df498c7a578b4f3e906283f9af913590bdec7
uses: turtlequeue/setup-babashka@fda33428c8b62fb5bb9802ca7a2c750a6cc11b5a
with:
babashka-version: 0.8.1

- name: babashka script
id: bb_script
run: bb main/test.clj

# Print the output of the babashka script from the
# `bb_script` step
# `bb_script` step
- name: Get the script output
run: echo "${{ steps.bb_script.outputs.bb_out }}"
48 changes: 19 additions & 29 deletions _generators/list-ops-generator.clj
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
(second
(str/split (:metadata data) #"="))

(defn get-meta
(defn get-meta
"Returns a vector containing the exercise title and blurb"
[data]
(mapv last
(map #(map str/trim (str/split % #"="))
(str/split-lines (:metadata data)))))
(map #(map str/trim (str/split % #"="))
(str/split-lines (:metadata data)))))

(defn init-deps! [data]
(fs/create-dirs (fs/path "exercises" "practice"
Expand All @@ -38,8 +38,7 @@
:exec-fn cognitect.test-runner.api/test}}}"))

(comment
(init-deps! data)
)
(init-deps! data))

(defn init-lein! [data]
(let [slug (:exercise (:canonical-data data))]
Expand All @@ -52,8 +51,7 @@
"))))

(comment
(init-lein! data)
)
(init-lein! data))

(defn test-ns-form [data]
(str "(ns " (:exercise data) "-test
Expand All @@ -67,14 +65,13 @@
(let [[args body] (str/split s #"->")
arg-strs (mapv str (edn/read-string args))
[arg1 op arg2] (str/split (str/trim body) #"\s")]
(str "(fn [" (apply str (interpose " " arg-strs)) "] "
(str "(fn [" (apply str (interpose " " arg-strs)) "] "
"(" op " " arg1 " " arg2 "))")))

(comment
(trans-fn "(x) -> x + 1")
(trans-fn "(x) -> x + 1")
(trans-fn "(x, y) -> x * y")
(trans-fn "(acc, el) -> el * acc")
)
(trans-fn "(acc, el) -> el * acc"))

(defn testing-form [slug test-case]
(let [property (symbol (str slug "/" (:property test-case)))
Expand All @@ -85,8 +82,7 @@
(reverse (into (list property) args)) ")))")))

(comment
(testing-form "list-ops" (first (:cases (first (:cases (:canonical-data data))))))
)
(testing-form "list-ops" (first (:cases (first (:cases (:canonical-data data)))))))

(defn testing-forms
"Outputs a sequence of the test cases for a given property name
Expand All @@ -98,8 +94,7 @@
(map #(testing-form (:exercise (:canonical-data data)) %) test-cases)))

(comment
(testing-forms "append" data)
)
(testing-forms "append" data))

(defn deftest-forms [data]
(for [property (distinct (map :property (mapcat :cases
Expand All @@ -110,8 +105,7 @@
")")))

(comment
(deftest-forms data)
)
(deftest-forms data))

(defn init-tests! [data]
(let [path (fs/path "exercises" "practice"
Expand All @@ -127,8 +121,7 @@
(deftest-forms data)))))))

(comment
(init-tests! data)
)
(init-tests! data))

(defn init-src! [data]
(spit (str (fs/file "exercises" "practice" (:exercise (:canonical-data data)) "src"
Expand All @@ -141,8 +134,7 @@
(str "(defn " property " []\n )")))))))

(comment
(init-src! data)
)
(init-src! data))

(defn init-description! [data]
(let [path ["exercises" "practice" (:exercise (:canonical-data data)) ".docs"]]
Expand All @@ -152,26 +144,24 @@
(:description data)))))

(comment
(init-description! data)
)
(init-description! data))

(defn config [data author blurb]
(let [slug (:exercise (:canonical-data data))]
{:authors [author],
:contributors [],
:files {:solution [(str "src/" (str/replace slug "-" "_") ".clj")],
:test [(str "test/" (str/replace slug "-" "_") "_test.clj")],
:example [".meta/src/example.clj"]},
:files {:solution [(str "src/" (str/replace slug "-" "_") ".clj")],
:test [(str "test/" (str/replace slug "-" "_") "_test.clj")],
:example [".meta/example.clj"]},
:blurb blurb}))

(defn init-config! [data]
(let [path ["exercises" "practice" (:exercise (:canonical-data data)) ".meta"]]
(when-not (fs/directory? (apply fs/path path))
(fs/create-dirs (apply fs/path (conj path "src")))
(fs/create-dirs (apply fs/path (conj path "src")))
(spit (str (apply fs/file (conj path "config.json")))
(json/generate-string (config data "porkostomus" (last (get-meta data)))
{:pretty true})))))

(comment
(init-config! data)
)
(init-config! data))
4 changes: 2 additions & 2 deletions _generators/zipper-generator.clj
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
(:exercise (:canonical-data data)) "project.clj"))
(str "(defproject " slug " \"0.1.0-SNAPSHOT\"
:description \"" slug " exercise.\"
:url \"https://github.com/exercism/clojure/tree/master/exercises/" slug "\"
:url \"https://github.com/exercism/clojure/tree/main/exercises/practice/" slug "\"
:dependencies [[org.clojure/clojure \"1.10.0\"]])
"))))

Expand Down Expand Up @@ -124,7 +124,7 @@
:contributors [],
:files {:solution [(str "src/" (str/replace slug "-" "_") ".clj")],
:test [(str "test/" (str/replace slug "-" "_") "_test.clj")],
:example [".meta/src/example.clj"]},
:example [".meta/example.clj"]},
:blurb blurb}))

(defn init-config! [data]
Expand Down
15 changes: 0 additions & 15 deletions _test/check_exercises.clj

This file was deleted.

109 changes: 109 additions & 0 deletions bin/add-practice-exercise
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/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 "Where: 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

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='1'
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}"

if [[ -z "${author}" ]]; then
read -rp 'Your GitHub username: ' author
fi

./bin/fetch-configlet
./bin/configlet create --practice-exercise "${slug}" --author "${author}" --difficulty "${difficulty}"

exercise_dir="exercises/practice/${slug}"
config_json_file="${exercise_dir}/.meta/config.json"
files=$(jq -r --arg dir "${exercise_dir}" '.files | to_entries | map({key: .key, value: (.value | map("'"'"'" + $dir + "/" + . + "'"'"'") | join(" and "))}) | from_entries' "${config_json_file}")

sample_exercise_dir="exercises/practice/acronym"
for sample_file in deps.edn project.clj; do
if [[ ! -f "${sample_exercise_dir}/${sample_file}" ]]; then
die "The sample exercise directory is missing the '${sample_file}' file."
fi

cp "${sample_exercise_dir}/${sample_file}" "${exercise_dir}/${sample_file}"
done

sed -i "s/acronym/${slug}/g" "${exercise_dir}/project.clj"

test_file=$(jq -r '.files.test[0]' "${config_json_file}")
cat >"${exercise_dir}/${test_file}" << TEST_FILE
(ns ${slug}-test
(:require [clojure.test :refer [deftest testing is]]
${slug}))
TEST_FILE

for file_type in solution example; do
solution_file=$(jq -r --arg file_type "${file_type}" '.files[$file_type][0]' "${config_json_file}")
cat >"${exercise_dir}/${solution_file}" << FILE
(ns ${slug})
FILE
done

cat << NEXT_STEPS
Your next steps are:
- Create the test suite in $(jq -r '.test' <<< "${files}")
- The tests should be based on the canonical data at 'https://github.com/exercism/problem-specifications/blob/main/exercises/${slug}/canonical-data.json'
- Any test cases you don't implement, mark them in 'exercises/practice/${slug}/.meta/tests.toml' with "include = false"
- Create the example solution in $(jq -r '.example' <<< "${files}")
- Verify the example solution passes the tests by running 'bin/verify-exercises ${slug}'
- Create the stub solution in $(jq -r '.solution' <<< "${files}")
- Update the 'difficulty' value for the exercise's entry in the 'config.json' file in the repo's root
- Validate CI using 'bin/configlet lint' and 'bin/configlet fmt'
NEXT_STEPS
13 changes: 0 additions & 13 deletions bin/restructure.clj

This file was deleted.

24 changes: 24 additions & 0 deletions bin/verify-exercises
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

# Synopsis:
# Verify that each exercise's example/exemplar solution passes the tests.
# You can either verify all exercises or a single exercise.

# Example: verify all exercises
# bin/verify-exercises

# Example: verify single exercise
# bin/verify-exercises two-fer

set -eo pipefail

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."
}

required_tool bb

bb test.clj "$@"
Loading

0 comments on commit d6411d9

Please sign in to comment.