Skip to content

Commit 0b9eed3

Browse files
committedMar 11, 2025·
verify_snippet: Attempting to add csharp
Moving some bits around for readability
1 parent 030eebd commit 0b9eed3

File tree

1 file changed

+37
-24
lines changed

1 file changed

+37
-24
lines changed
 

‎teachprogramming/lib/verify_snippets/conftest.py

+37-24
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from types import MappingProxyType
99
import subprocess
1010
import logging
11+
import shutil
1112

1213
import pytest
1314

@@ -16,11 +17,28 @@
1617

1718
PATH_PROJECTS = Path("projects").absolute()
1819
PATH_LANGUAGES = Path('languages').absolute()
19-
LOOKUP_LANGUAGE_FOLDER = MappingProxyType({
20+
LANGUAGE_TO_FOLDER_MAPPING = MappingProxyType({
2021
'py': 'python',
2122
'cs': 'csharp',
2223
})
2324

25+
# `tempdir` creates 'secure' temp folders.
26+
# These are not available to other users.
27+
# docker on mac runs as a different user.
28+
# None of the temp folders from env work because again - owned by the user
29+
# environ.get('TMPDIR') or environ.get('TEMP') or environ.get('TMP') or
30+
tempdir = Path('.').joinpath('_language_runner')
31+
tempdir.mkdir(exist_ok=True)
32+
def clear(path: Path):
33+
# https://docs.python.org/3/library/pathlib.html#pathlib.Path.walk
34+
for root, dirs, files in path.walk(top_down=False):
35+
for name in files:
36+
(root / name).unlink()
37+
for name in dirs:
38+
(root / name).rmdir()
39+
40+
41+
# Docker -----------------------------------------------------------------------
2442

2543
def get_built_docker_language_runners() -> set[str]:
2644
result = subprocess.run(
@@ -32,41 +50,30 @@ def get_built_docker_language_runners() -> set[str]:
3250
)
3351
return {container['Tag'] for container in map(json.loads, filter(None, result.stdout.split('\n')))}
3452

35-
BUILT_LANGUAGES = get_built_docker_language_runners()
53+
BUILT_LANGUAGES_RUNNERS = get_built_docker_language_runners()
54+
55+
def get_docker_folder_for_language(language: str) -> Path:
56+
return PATH_LANGUAGES.joinpath(LANGUAGE_TO_FOLDER_MAPPING.get(language, language))
3657

3758
def build_docker_language_runner(language) -> subprocess.CompletedProcess:
3859
return subprocess.run(
39-
("docker", "build", PATH_LANGUAGES.joinpath(LOOKUP_LANGUAGE_FOLDER.get(language, language)), "--tag", f"language_runner:{language}"),
60+
("docker", "build", get_docker_folder_for_language(language), "--tag", f"language_runner:{language}"),
4061
capture_output=True,
4162
timeout=120,
4263
text=True,
4364
check=True,
4465
)
4566

4667

47-
# `tempdir` creates 'secure' temp folders.
48-
# These are not available to other users.
49-
# docker on mac runs as a different user.
50-
# None of the temp folders from env work because again - owned by the user
51-
# environ.get('TMPDIR') or environ.get('TEMP') or environ.get('TMP') or
52-
tempdir = Path('.').joinpath('_language_runner')
53-
tempdir.mkdir(exist_ok=True)
54-
def clear(path: Path):
55-
# https://docs.python.org/3/library/pathlib.html#pathlib.Path.walk
56-
for root, dirs, files in path.walk(top_down=False):
57-
for name in files:
58-
(root / name).unlink()
59-
for name in dirs:
60-
(root / name).rmdir()
61-
68+
# Project Compile --------------------------------------------------------------
6269

6370
class ProjectItemSpec(NamedTuple):
6471
name: str
6572
language: str
6673
version: str
6774
code: str
6875

69-
def exec_language(self, language_args: tuple[str]):
76+
def exec_language(self, language_args: tuple[str]=()):
7077
workdir = f"/{self.language}"
7178
docker_args = (
7279
"docker", "run", "--rm",
@@ -103,15 +110,21 @@ def get_java_main_classname(code: str) -> str:
103110
if match := re.search(r'class (\w+?) .*public static void main', code, re.DOTALL):
104111
return match.group(1)
105112
raise Exception('unable to find top level classname for filename', code)
106-
107113
def compile_test_java(spec: ProjectItemSpec):
108114
path_code_file = tempdir.joinpath(get_java_main_classname(spec.code) + ".java")
109115
path_code_file.write_text(spec.code)
110116
spec.exec_language(("javac", path_code_file.name))
111117

118+
119+
def copy_cs_file_to_workdir(filename: str):
120+
shutil.copyfile(get_docker_folder_for_language('cs').joinpath(filename), tempdir.joinpath(filename))
112121
def compile_test_csharp(spec: ProjectItemSpec):
113-
# csharp create manifest?
114-
raise NotImplementedError('')
122+
copy_cs_file_to_workdir('main.csproj')
123+
copy_cs_file_to_workdir('packages.log.json')
124+
path_code_file = tempdir.joinpath(spec.name)
125+
path_code_file.write_text(spec.code)
126+
# TODO: edit `main.csproj` to point to top level cs class
127+
spec.exec_language() # The containers base command is already `dotnet run`
115128

116129

117130
LANGUAGES: MappingProxyType[str, Callable] = MappingProxyType(
@@ -159,11 +172,11 @@ def pytest_collection_finish(session: pytest.Session):
159172
for item in session.items
160173
if hasattr(item, 'spec')
161174
}
162-
language_runners_to_build = (languages_in_items - BUILT_LANGUAGES) & LANGUAGES.keys()
175+
language_runners_to_build = (languages_in_items - BUILT_LANGUAGES_RUNNERS) & LANGUAGES.keys()
163176
for language in language_runners_to_build:
164177
print(f"docker build --tag language_runner:{language}") #log.info
165178
build_docker_language_runner(language)
166-
BUILT_LANGUAGES.add(language)
179+
BUILT_LANGUAGES_RUNNERS.add(language)
167180

168181

169182
def pytest_sessionfinish(session: pytest.Session, exitstatus: int):

0 commit comments

Comments
 (0)
Please sign in to comment.