-
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathprobspecs.nim
103 lines (75 loc) · 3.26 KB
/
probspecs.nim
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
import std/[json, options, os, osproc, sequtils, strformat]
import arguments
type
ProbSpecsRepoExercise = object
dir: string
ProbSpecsRepo = object
dir: string
ProbSpecsTestCase* = object
json*: JsonNode
ProbSpecsExercise* = object
slug*: string
testCases*: seq[ProbSpecsTestCase]
proc execCmdException*(cmd: string, message: string) =
if execCmd(cmd) != 0:
quit(message)
proc probSpecsDir: string =
getCurrentDir() / ".problem-specifications"
proc initProbSpecsRepo: ProbSpecsRepo =
result.dir = probSpecsDir()
proc clone(repo: ProbSpecsRepo) =
let cmd = &"git clone --depth 1 https://github.com/exercism/problem-specifications.git {repo.dir}"
execCmdException(cmd, "Could not clone problem-specifications repo")
proc remove(repo: ProbSpecsRepo) =
removeDir(repo.dir)
proc initProbSpecsRepoExercise(dir: string): ProbSpecsRepoExercise =
result.dir = dir
proc exercisesDir(repo: ProbSpecsRepo): string =
repo.dir / "exercises"
proc exercises(repo: ProbSpecsRepo): seq[ProbSpecsRepoExercise] =
for exerciseDir in walkDirs(repo.exercisesDir / "*"):
result.add(initProbSpecsRepoExercise(exerciseDir))
proc canonicalDataFile(repoExercise: ProbSpecsRepoExercise): string =
repoExercise.dir / "canonical-data.json"
proc hasCanonicalDataFile(repoExercise: ProbSpecsRepoExercise): bool =
fileExists(repoExercise.canonicalDataFile())
proc exercisesWithCanonicalData(repo: ProbSpecsRepo): seq[ProbSpecsRepoExercise] =
for repoExercise in repo.exercises().filter(hasCanonicalDataFile):
result.add(repoExercise)
proc slug(repoExercise: ProbSpecsRepoExercise): string =
extractFilename(repoExercise.dir)
proc initProbSpecsTestCase(node: JsonNode): ProbSpecsTestCase =
result.json = node
proc uuid*(testCase: ProbSpecsTestCase): string =
testCase.json["uuid"].getStr()
proc description*(testCase: ProbSpecsTestCase): string =
testCase.json["description"].getStr()
proc reimplementation*(testCase: ProbSpecsTestCase): bool =
testCase.json.hasKey("reimplements")
proc reimplements*(testCase: ProbSpecsTestCase): string =
testCase.json["reimplements"].getStr()
proc initProbSpecsTestCases(node: JsonNode): seq[ProbSpecsTestCase] =
if node.hasKey("uuid"):
result.add(initProbSpecsTestCase(node))
elif node.hasKey("cases"):
for childNode in node["cases"].getElems():
result.add(initProbSpecsTestCases(childNode))
proc parseProbSpecsTestCases(repoExercise: ProbSpecsRepoExercise): seq[ProbSpecsTestCase] =
if repoExercise.slug == "grains":
return
initProbSpecsTestCases(json.parseFile(repoExercise.canonicalDataFile))
proc initPropSpecsExercise(repoExercise: ProbSpecsRepoExercise): ProbSpecsExercise =
result.slug = repoExercise.slug
result.testCases = parseProbSpecsTestCases(repoExercise)
proc findProbSpecsExercises(repo: ProbSpecsRepo, args: Arguments): seq[ProbSpecsExercise] =
for repoExercise in repo.exercisesWithCanonicalData():
if args.exercise.isNone or args.exercise.get() == repoExercise.slug:
result.add(initPropSpecsExercise(repoExercise))
proc findProbSpecsExercises*(args: Arguments): seq[ProbSpecsExercise] =
let probSpecsRepo = initProbSpecsRepo()
try:
probSpecsRepo.remove()
probSpecsRepo.clone()
probSpecsRepo.findProbSpecsExercises(args)
finally:
probSpecsRepo.remove()