Skip to content

Commit 2582460

Browse files
cmccandlessBethanyG
authored andcommitted
update template_status.py for v3
1 parent 6ec59be commit 2582460

4 files changed

Lines changed: 36 additions & 37 deletions

File tree

.github/workflows/ci-workflow.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,4 @@ jobs:
6969

7070
- name: Check exercises
7171
run: |
72-
./bin/test-exercises.py
72+
./bin/test_exercises.py

bin/data.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,11 @@ def meta_dir(self):
6565
def exemplar_file(self):
6666
if self.type == 'concept':
6767
return self.meta_dir / 'exemplar.py'
68-
# return self.meta_dir / 'example.py'
69-
return self.path / 'example.py'
68+
return self.meta_dir / 'example.py'
7069

7170
@property
7271
def template_path(self):
73-
return self.meta_dir / '.template.j2'
72+
return self.meta_dir / 'template.j2'
7473

7574

7675
@dataclass

bin/template_status.py

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
from fnmatch import fnmatch
55
import json
66
import logging
7-
import os
7+
from pathlib import Path
88
import shlex
99
from subprocess import check_call, DEVNULL, CalledProcessError
1010
import sys
1111

12-
DEFAULT_SPEC_LOCATION = os.path.join("..", "problem-specifications")
12+
from data import Config, ExerciseInfo
13+
from test_exercises import check_assignment
14+
15+
DEFAULT_SPEC_LOCATION = Path('spec')
1316

1417
logging.basicConfig(format="%(levelname)s:%(message)s")
1518
logger = logging.getLogger("generator")
@@ -26,16 +29,6 @@ def __lt__(self, other):
2629
return self.value < other.value
2730

2831

29-
with open("config.json") as f:
30-
config = json.load(f)
31-
32-
exercises_dir = os.path.abspath("exercises")
33-
34-
35-
def get_template_path(exercise):
36-
return os.path.join(exercises_dir, exercise, ".meta", "template.j2")
37-
38-
3932
def exec_cmd(cmd):
4033
try:
4134
args = shlex.split(cmd)
@@ -49,22 +42,20 @@ def exec_cmd(cmd):
4942
return False
5043

5144

52-
def generate_template(exercise, spec_path):
53-
script = os.path.abspath("bin/generate_tests.py")
54-
return exec_cmd(f'{script} --verbose --spec-path "{spec_path}" {exercise}')
45+
def generate_template(exercise: ExerciseInfo, spec_path: Path) -> bool:
46+
script = Path('bin/generate_tests.py')
47+
return exec_cmd(f'{script} --verbose --spec-path "{spec_path}" {exercise.slug}')
5548

5649

57-
def run_tests(exercise):
58-
script = os.path.abspath("test/check-exercises.py")
59-
return exec_cmd(f"{script} {exercise}")
50+
def run_tests(exercise: ExerciseInfo) -> bool:
51+
return check_assignment(exercise, quiet=True) == 0
6052

6153

62-
def get_status(exercise, spec_path):
63-
template_path = get_template_path(exercise)
64-
if os.path.isfile(template_path):
54+
def get_status(exercise: ExerciseInfo, spec_path: Path):
55+
if exercise.template_path.is_file():
6556
if generate_template(exercise, spec_path):
6657
if run_tests(exercise):
67-
logging.info(f"{exercise}: OK")
58+
logging.info(f"{exercise.slug}: OK")
6859
return TemplateStatus.OK
6960
else:
7061
return TemplateStatus.TEST_FAILURE
@@ -84,6 +75,7 @@ def get_status(exercise, spec_path):
8475
"-p",
8576
"--spec-path",
8677
default=DEFAULT_SPEC_LOCATION,
78+
type=Path,
8779
help=(
8880
"path to clone of exercism/problem-specifications " "(default: %(default)s)"
8981
),
@@ -96,10 +88,10 @@ def get_status(exercise, spec_path):
9688
elif opts.verbose >= 1:
9789
logger.setLevel(logging.INFO)
9890

99-
if not os.path.isdir(opts.spec_path):
91+
if not opts.spec_path.is_dir():
10092
logger.error(f"{opts.spec_path} is not a directory")
10193
sys.exit(1)
102-
opts.spec_path = os.path.abspath(opts.spec_path)
94+
opts.spec_path = opts.spec_path.absolute()
10395
logger.debug(f"problem-specifications path is {opts.spec_path}")
10496

10597
result = True
@@ -108,20 +100,24 @@ def get_status(exercise, spec_path):
108100
TemplateStatus.INVALID: [],
109101
TemplateStatus.TEST_FAILURE: [],
110102
}
103+
config = Config.load()
111104
for exercise in filter(
112-
lambda e: fnmatch(e["slug"], opts.exercise_pattern), config["exercises"]
105+
lambda e: fnmatch(e.slug, opts.exercise_pattern),
106+
config.exercises.all()
113107
):
114-
if exercise.get('deprecated', False):
108+
if exercise.deprecated:
109+
continue
110+
if exercise.type == 'concept':
111+
# Concept exercises are not generated
115112
continue
116-
slug = exercise["slug"]
117-
status = get_status(slug, opts.spec_path)
113+
status = get_status(exercise, opts.spec_path)
118114
if status == TemplateStatus.OK:
119-
logger.info(f"{slug}: {status.name}")
115+
logger.info(f"{exercise.slug}: {status.name}")
120116
else:
121-
buckets[status].append(slug)
117+
buckets[status].append(exercise.slug)
122118
result = False
123119
if opts.stop_on_failure:
124-
logger.error(f"{slug}: {status.name}")
120+
logger.error(f"{exercise.slug}: {status.name}")
125121
break
126122

127123
if not opts.quiet and not opts.stop_on_failure:
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
ALLOW_SKIP = ['alphametics', 'largest-series-product']
1313

1414

15-
def check_assignment(exercise: ExerciseInfo) -> int:
15+
def check_assignment(exercise: ExerciseInfo, quiet=False) -> int:
1616
# Returns the exit code of the tests
1717
workdir = Path(tempfile.mkdtemp(exercise.slug))
1818
solution_file = exercise.solution_stub.name
@@ -27,7 +27,11 @@ def check_assignment(exercise: ExerciseInfo) -> int:
2727
with test_file_out.open('w') as dst_file:
2828
dst_file.writelines(lines)
2929
shutil.copyfile(exercise.exemplar_file, workdir / solution_file)
30-
return subprocess.call([sys.executable, test_file_out])
30+
kwargs = {}
31+
if quiet:
32+
kwargs['stdout'] = subprocess.DEVNULL
33+
kwargs['stderr'] = subprocess.DEVNULL
34+
return subprocess.run([sys.executable, test_file_out], **kwargs).returncode
3135
finally:
3236
shutil.rmtree(workdir)
3337

0 commit comments

Comments
 (0)