feat: add domain model foundation

This commit is contained in:
김경종
2026-06-08 16:40:04 +09:00
parent e4e2f57808
commit fdeac602f4
38 changed files with 2685 additions and 5 deletions
+56 -1
View File
@@ -87,7 +87,62 @@ class ValidateWorkspaceTests(unittest.TestCase):
with patch.object(validate_workspace.shutil, "which", return_value=None):
env = validate_workspace.validation_environment({"PATH": "C:\\Windows\\System32"})
self.assertTrue(env["PATH"].startswith(str(common_bin)))
path_key = "Path" if os.name == "nt" else "PATH"
self.assertTrue(env[path_key].startswith(str(common_bin)))
def test_common_cmake_install_path_updates_existing_windows_path_key(self):
validate_workspace = load_validate_workspace()
with tempfile.TemporaryDirectory() as tmp:
common_bin = Path(tmp) / "CMake" / "bin"
common_bin.mkdir(parents=True)
(common_bin / "cmake.exe").write_text("", encoding="utf-8")
with patch.object(validate_workspace, "COMMON_CMAKE_BIN", common_bin):
with patch.object(validate_workspace.shutil, "which", return_value=None):
env = validate_workspace.validation_environment({"Path": "C:\\Windows\\System32"})
self.assertIn("Path", env)
self.assertNotIn("PATH", env)
self.assertTrue(env["Path"].startswith(str(common_bin)))
def test_common_cmake_install_path_normalizes_uppercase_path_on_windows(self):
if os.name != "nt":
self.skipTest("Windows-specific subprocess environment behavior")
validate_workspace = load_validate_workspace()
with tempfile.TemporaryDirectory() as tmp:
common_bin = Path(tmp) / "CMake" / "bin"
common_bin.mkdir(parents=True)
(common_bin / "cmake.exe").write_text("", encoding="utf-8")
with patch.object(validate_workspace, "COMMON_CMAKE_BIN", common_bin):
with patch.object(validate_workspace.shutil, "which", return_value=None):
env = validate_workspace.validation_environment({"PATH": "C:\\Windows\\System32"})
self.assertIn("Path", env)
self.assertNotIn("PATH", env)
self.assertTrue(env["Path"].startswith(str(common_bin)))
def test_common_cmake_executable_is_used_when_command_tool_is_not_on_path(self):
validate_workspace = load_validate_workspace()
with tempfile.TemporaryDirectory() as tmp:
common_bin = Path(tmp) / "CMake" / "bin"
common_bin.mkdir(parents=True)
(common_bin / "cmake.exe").write_text("", encoding="utf-8")
with patch.object(validate_workspace, "COMMON_CMAKE_BIN", common_bin):
with patch.object(validate_workspace.shutil, "which", return_value=None):
command = validate_workspace.resolve_validation_command("cmake --version")
self.assertEqual(command, f'"{common_bin / "cmake.exe"}" --version')
def test_common_ctest_executable_is_used_when_command_tool_is_not_on_path(self):
validate_workspace = load_validate_workspace()
with tempfile.TemporaryDirectory() as tmp:
common_bin = Path(tmp) / "CMake" / "bin"
common_bin.mkdir(parents=True)
(common_bin / "ctest.exe").write_text("", encoding="utf-8")
with patch.object(validate_workspace, "COMMON_CMAKE_BIN", common_bin):
with patch.object(validate_workspace.shutil, "which", return_value=None):
command = validate_workspace.resolve_validation_command("ctest --version")
self.assertEqual(command, f'"{common_bin / "ctest.exe"}" --version')
if __name__ == "__main__":
+31 -3
View File
@@ -88,7 +88,27 @@ def discover_commands(root: Path) -> list[str]:
return load_cmake_commands(root)
def resolve_validation_command(command: str) -> str:
parts = command.split(maxsplit=1)
if not parts:
return command
tool = parts[0].lower()
if tool not in {"cmake", "ctest"}:
return command
if shutil.which(tool) is not None:
return command
exe = COMMON_CMAKE_BIN / f"{tool}.exe"
if not exe.exists():
return command
suffix = f" {parts[1]}" if len(parts) > 1 else ""
return f'"{exe}"{suffix}'
def run_command(command: str, root: Path) -> subprocess.CompletedProcess:
command = resolve_validation_command(command)
return subprocess.run(
command,
cwd=root,
@@ -103,17 +123,25 @@ def run_command(command: str, root: Path) -> subprocess.CompletedProcess:
def validation_environment(base_env: os._Environ | dict[str, str]) -> dict[str, str]:
env = dict(base_env)
if shutil.which("cmake") is not None:
path_key = "Path" if os.name == "nt" else "PATH"
path_values = []
for key in list(env):
if key.lower() == "path":
path_values.append(env.pop(key))
current_path = os.pathsep.join(part for part in path_values if part)
env[path_key] = current_path
if shutil.which("cmake", path=current_path) is not None:
return env
cmake_exe = COMMON_CMAKE_BIN / "cmake.exe"
if not cmake_exe.exists():
return env
current_path = env.get("PATH", "")
paths = [part for part in current_path.split(os.pathsep) if part]
common_bin_text = str(COMMON_CMAKE_BIN)
if not any(part.lower() == common_bin_text.lower() for part in paths):
env["PATH"] = common_bin_text + (os.pathsep + current_path if current_path else "")
env[path_key] = common_bin_text + (os.pathsep + current_path if current_path else "")
return env