Skip to content

Commit 537cda2

Browse files
Add back generators (zipper, list-ops) (#682)
* init list-ops exercise (cherry picked from commit 20fa8ce) * init instructions (cherry picked from commit e60ae25) * create list-ops specific generator (cherry picked from commit 5061d13) * save zipper generator (cherry picked from commit 3cf4390) * create test suite (cherry picked from commit 271ea2c) * translate anonymous functions (cherry picked from commit 104e4a3) * init skeleton src file (cherry picked from commit ce949bb) * move generators to _generators folder --------- Co-authored-by: Bobby Towers <[email protected]>
1 parent 0a8c1a1 commit 537cda2

File tree

4 files changed

+184
-8
lines changed

4 files changed

+184
-8
lines changed
File renamed without changes.
File renamed without changes.

_generators/list-ops-generator.clj

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#!/usr/bin/env bb
2+
3+
(require '[cheshire.core :as json]
4+
'[babashka.fs :as fs]
5+
'[clojure.string :as str]
6+
'[clojure.edn :as edn])
7+
8+
(comment
9+
(def slug "list-ops"))
10+
11+
(def data
12+
(let [url "https://raw.githubusercontent.com/exercism/problem-specifications/main/exercises/"]
13+
{:canonical-data (json/parse-string (slurp (str url "/" slug "/canonical-data.json")) true)
14+
:description (slurp (str url "/" slug "/description.md"))
15+
:metadata (slurp (str url "/" slug "/metadata.toml"))}))
16+
17+
(second
18+
(str/split (:metadata data) #"="))
19+
20+
(defn get-meta
21+
"Returns a vector containing the exercise title and blurb"
22+
[data]
23+
(mapv last
24+
(map #(map str/trim (str/split % #"="))
25+
(str/split-lines (:metadata data)))))
26+
27+
(defn init-deps! [data]
28+
(fs/create-dirs (fs/path "exercises" "practice"
29+
(:exercise (:canonical-data data)) "src"))
30+
(spit (str (fs/file "exercises" "practice"
31+
(:exercise (:canonical-data data))
32+
"deps.edn"))
33+
"{:aliases {:test {:extra-paths [\"test\"]
34+
:extra-deps {io.github.cognitect-labs/test-runner
35+
{:git/url \"https://github.com/cognitect-labs/test-runner.git\"
36+
:sha \"705ad25bbf0228b1c38d0244a36001c2987d7337\"}}
37+
:main-opts [\"-m\" \"cognitect.test-runner\"]
38+
:exec-fn cognitect.test-runner.api/test}}}"))
39+
40+
(comment
41+
(init-deps! data)
42+
)
43+
44+
(defn init-lein! [data]
45+
(let [slug (:exercise (:canonical-data data))]
46+
(spit (str (fs/file "exercises" "practice"
47+
(:exercise (:canonical-data data)) "project.clj"))
48+
(str "(defproject " slug " \"0.1.0-SNAPSHOT\"
49+
:description \"" slug " exercise.\"
50+
:url \"https://github.com/exercism/clojure/tree/main/exercises/" slug "\"
51+
:dependencies [[org.clojure/clojure \"1.10.0\"]])
52+
"))))
53+
54+
(comment
55+
(init-lein! data)
56+
)
57+
58+
(defn test-ns-form [data]
59+
(str "(ns " (:exercise data) "-test
60+
(:require [clojure.test :refer [deftest testing is]]\n "
61+
(:exercise data) "))\n\n"))
62+
63+
(defn src-ns-form [data]
64+
(str "(ns " (:exercise data) ")\n\n"))
65+
66+
(defn trans-fn [s]
67+
(let [[args body] (str/split s #"->")
68+
arg-strs (mapv str (edn/read-string args))
69+
[arg1 op arg2] (str/split (str/trim body) #"\s")]
70+
(str "(fn [" (apply str (interpose " " arg-strs)) "] "
71+
"(" op " " arg1 " " arg2 "))")))
72+
73+
(comment
74+
(trans-fn "(x) -> x + 1")
75+
(trans-fn "(x, y) -> x * y")
76+
(trans-fn "(acc, el) -> el * acc")
77+
)
78+
79+
(defn testing-form [slug test-case]
80+
(let [property (symbol (str slug "/" (:property test-case)))
81+
input (:input test-case)
82+
args (map #(get input %) (keys input))]
83+
(str " (testing \"" (:description test-case) "\"
84+
(is (= " (:expected test-case) " "
85+
(reverse (into (list property) args)) ")))")))
86+
87+
(comment
88+
(testing-form "list-ops" (first (:cases (first (:cases (:canonical-data data))))))
89+
)
90+
91+
(defn testing-forms
92+
"Outputs a sequence of the test cases for a given property name
93+
given its name as a string and the canonical data."
94+
[property data]
95+
(let [test-cases (filter #(= property (:property %))
96+
(mapcat :cases
97+
(:cases (:canonical-data data))))]
98+
(map #(testing-form (:exercise (:canonical-data data)) %) test-cases)))
99+
100+
(comment
101+
(testing-forms "append" data)
102+
)
103+
104+
(defn deftest-forms [data]
105+
(for [property (distinct (map :property (mapcat :cases
106+
(:cases (:canonical-data data)))))]
107+
(str "(deftest " property "-test\n"
108+
(apply str (interpose "\n"
109+
(testing-forms property data)))
110+
")")))
111+
112+
(comment
113+
(deftest-forms data)
114+
)
115+
116+
(defn init-tests! [data]
117+
(let [path (fs/path "exercises" "practice"
118+
(:exercise (:canonical-data data)) "test")]
119+
(when-not (fs/directory? path)
120+
(fs/create-dir path))
121+
(spit (str (fs/file "exercises" "practice"
122+
(:exercise (:canonical-data data)) "test"
123+
(str (str/replace (:exercise (:canonical-data data)) "-" "_")
124+
"_test.clj")))
125+
(str (test-ns-form (:canonical-data data))
126+
(apply str (interpose "\n\n"
127+
(deftest-forms data)))))))
128+
129+
(comment
130+
(init-tests! data)
131+
)
132+
133+
(defn init-src! [data]
134+
(spit (str (fs/file "exercises" "practice" (:exercise (:canonical-data data)) "src"
135+
(str (str/replace (:exercise (:canonical-data data))
136+
"-" "_") ".clj")))
137+
(str (src-ns-form (:canonical-data data))
138+
(apply str (interpose "\n\n"
139+
(for [property (distinct (map :property (mapcat :cases
140+
(:cases (:canonical-data data)))))]
141+
(str "(defn " property " []\n )")))))))
142+
143+
(comment
144+
(init-src! data)
145+
)
146+
147+
(defn init-description! [data]
148+
(let [path ["exercises" "practice" (:exercise (:canonical-data data)) ".docs"]]
149+
(when-not (fs/directory? (apply fs/path path))
150+
(fs/create-dir (apply fs/path path))
151+
(spit (str (apply fs/file (conj path "instructions.md")))
152+
(:description data)))))
153+
154+
(comment
155+
(init-description! data)
156+
)
157+
158+
(defn config [data author blurb]
159+
(let [slug (:exercise (:canonical-data data))]
160+
{:authors [author],
161+
:contributors [],
162+
:files {:solution [(str "src/" (str/replace slug "-" "_") ".clj")],
163+
:test [(str "test/" (str/replace slug "-" "_") "_test.clj")],
164+
:example [".meta/src/example.clj"]},
165+
:blurb blurb}))
166+
167+
(defn init-config! [data]
168+
(let [path ["exercises" "practice" (:exercise (:canonical-data data)) ".meta"]]
169+
(when-not (fs/directory? (apply fs/path path))
170+
(fs/create-dirs (apply fs/path (conj path "src")))
171+
(spit (str (apply fs/file (conj path "config.json")))
172+
(json/generate-string (config data "porkostomus" (last (get-meta data)))
173+
{:pretty true})))))
174+
175+
(comment
176+
(init-config! data)
177+
)

generator.clj renamed to _generators/zipper-generator.clj

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
(second
1717
(str/split (:metadata data) #"="))
1818

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

2626
(defn init-deps [data]
2727
(fs/create-dirs (fs/path "exercises" "practice"
@@ -122,19 +122,18 @@
122122
(let [slug (:exercise (:canonical-data data))]
123123
{:authors [author],
124124
:contributors [],
125-
:files {:solution [(str "src/" (str/replace slug "-" "_") ".clj")],
126-
:test [(str "test/" (str/replace slug "-" "_") "_test.clj")],
125+
:files {:solution [(str "src/" (str/replace slug "-" "_") ".clj")],
126+
:test [(str "test/" (str/replace slug "-" "_") "_test.clj")],
127127
:example [".meta/src/example.clj"]},
128128
:blurb blurb}))
129129

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

138138
(comment
139-
(init-config! data)
140-
)
139+
(init-config! data))

0 commit comments

Comments
 (0)