add uncommitted files

This commit is contained in:
KOKO\Mimi
2026-07-29 23:32:26 +09:00
parent fb0f8f39a0
commit f5379472ce
80 changed files with 7461 additions and 1 deletions
+169
View File
@@ -0,0 +1,169 @@
import os
import shutil
import subprocess
import time
from pathlib import Path
from .models import ProjectKind, Toolchain
VC_WORKLOAD = "Microsoft.VisualStudio.Component.VC.Tools.x86.x64"
VS_CMAKE_RELATIVE = Path(
"Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin"
)
class ToolchainError(RuntimeError):
pass
def _decode(value):
if isinstance(value, str):
return value
return (value or b"").decode("utf-8", errors="replace")
def _first_path(result, label, argv, cwd):
text = _decode(result.stdout).strip()
if result.returncode != 0:
diagnostic = (
_decode(result.stdout) + "\n" + _decode(result.stderr)
).rstrip()[-8000:]
diagnostic = diagnostic.replace("\r\n", " | ").replace("\n", " | ")
message = (
f"{label} probe failed with exit code {result.returncode}; "
f"argv={argv!r}; cwd={str(cwd)!r}"
)
if diagnostic:
message = f"{message}; output tail: {diagnostic}"
raise ToolchainError(
f"{message}; install Visual Studio Desktop development with C++"
)
if not text:
raise ToolchainError(
f"{label} probe returned no path; argv={argv!r}; cwd={str(cwd)!r}; "
"install Visual Studio Desktop development with C++"
)
path = Path(text.splitlines()[0]).resolve()
if not path.exists():
diagnostic = (
_decode(result.stdout) + "\n" + _decode(result.stderr)
).rstrip()[-8000:]
diagnostic = diagnostic.replace("\r\n", " | ").replace("\n", " | ")
message = (
f"{label} probe returned nonexistent path with exit code 0; "
f"argv={argv!r}; cwd={str(cwd)!r}"
)
if diagnostic:
message = f"{message}; output tail: {diagnostic}"
raise ToolchainError(
f"{message}; install or repair Visual Studio Desktop development with C++"
)
return path
def _require_path(path, label):
if path is None or not path.exists():
raise ToolchainError(f"{label} not found")
return path.resolve()
def _remaining(deadline, clock, label):
if deadline is None:
return None
remaining = deadline - clock()
if remaining <= 0:
raise ToolchainError(f"{label} probe timed out before it could start")
return remaining
def _probe(run, argv, label, *, deadline, clock):
cwd = Path.cwd().resolve()
kwargs = {
"cwd": cwd,
"capture_output": True,
"check": False,
"shell": False,
}
remaining = _remaining(deadline, clock, label)
if remaining is not None:
kwargs["timeout"] = remaining
try:
return run(argv, **kwargs)
except subprocess.TimeoutExpired as exc:
raise ToolchainError(
f"{label} probe timed out; argv={argv!r}; cwd={str(cwd)!r}; "
"install or repair Visual Studio Desktop development with C++"
) from exc
def discover_toolchain(
kind: ProjectKind,
*,
env=None,
which=shutil.which,
run=subprocess.run,
deadline=None,
clock=time.monotonic,
) -> Toolchain:
environment = os.environ if env is None else env
vswhere_path = which("vswhere.exe")
if vswhere_path is None:
program_files = environment.get("ProgramFiles(x86)")
if program_files:
candidate = Path(program_files) / "Microsoft Visual Studio/Installer/vswhere.exe"
vswhere_path = str(candidate) if candidate.exists() else None
vswhere = _require_path(
Path(vswhere_path) if vswhere_path else None,
"vswhere.exe; install Visual Studio Desktop development with C++",
)
install_argv = [
str(vswhere), "-latest", "-products", "*", "-requires", VC_WORKLOAD,
"-property", "installationPath",
]
install_result = _probe(
run,
install_argv,
"Visual Studio installation",
deadline=deadline,
clock=clock,
)
probe_cwd = Path.cwd().resolve()
installation = _require_path(
_first_path(
install_result,
"Visual Studio installation",
install_argv,
probe_cwd,
),
"Visual Studio installation",
)
msbuild_argv = [
str(vswhere), "-latest", "-products", "*", "-requires", VC_WORKLOAD,
"-find", r"MSBuild\**\Bin\MSBuild.exe",
]
msbuild_result = _probe(
run,
msbuild_argv,
"MSBuild",
deadline=deadline,
clock=clock,
)
msbuild = _require_path(
_first_path(msbuild_result, "MSBuild", msbuild_argv, probe_cwd),
"MSBuild.exe",
)
if kind is not ProjectKind.CMAKE:
return Toolchain(installation=installation, msbuild=msbuild)
bundled_cmake_dir = installation / VS_CMAKE_RELATIVE
cmake = _require_path(
Path(which("cmake.exe")) if which("cmake.exe") else bundled_cmake_dir / "cmake.exe",
"cmake.exe",
)
ctest = _require_path(
Path(which("ctest.exe")) if which("ctest.exe") else bundled_cmake_dir / "ctest.exe",
"ctest.exe",
)
return Toolchain(installation=installation, msbuild=msbuild, cmake=cmake, ctest=ctest)