(home)
| 2959 | } |
| 2960 | |
| 2961 | function ensurePythonRuntime(home) { |
| 2962 | ensureDir(path.join(home, 'runtime')); |
| 2963 | ensureDir(path.join(home, 'runtime', 'bundle')); |
| 2964 | ensureDir(runtimeUvCachePath(home)); |
| 2965 | ensureDir(runtimeUvPythonInstallPath(home)); |
| 2966 | ensureDir(runtimeToolsPath(home)); |
| 2967 | let uvBinary; |
| 2968 | try { |
| 2969 | uvBinary = ensureUvBinary(home); |
| 2970 | } catch (error) { |
| 2971 | printUvInstallGuidance(home, error instanceof Error ? error.message : String(error)); |
| 2972 | process.exit(1); |
| 2973 | } |
| 2974 | const runtimePlan = resolvePythonRuntimePlan(); |
| 2975 | if (runtimePlan.runtimeKind === 'managed') { |
| 2976 | printManagedPythonFallbackNotice({ |
| 2977 | rejectedProbe: runtimePlan.rejectedProbe || null, |
| 2978 | source: runtimePlan.source, |
| 2979 | minimumVersionRequest: runtimePlan.minimumVersionRequest, |
| 2980 | installDir: runtimeUvPythonInstallPath(home), |
| 2981 | }); |
| 2982 | } |
| 2983 | const lockPath = ensureUvLockPresent(); |
| 2984 | const stampPath = path.join(home, 'runtime', 'bundle', 'python-stamp.json'); |
| 2985 | const editable = useEditableProjectInstall(); |
| 2986 | const desiredStamp = { |
| 2987 | runtimeManager: 'uv', |
| 2988 | version: packageJson.version, |
| 2989 | pyprojectHash: sha256File(path.join(repoRoot, 'pyproject.toml')), |
| 2990 | uvLockHash: sha256File(lockPath), |
| 2991 | editable, |
| 2992 | sourceTreeHash: editable ? null : hashPythonSourceTree(), |
| 2993 | uvVersion: resolveUvVersion(uvBinary), |
| 2994 | envPath: runtimePythonEnvPath(home), |
| 2995 | source: |
| 2996 | runtimePlan.runtimeKind === 'system' |
| 2997 | ? { |
| 2998 | kind: 'system', |
| 2999 | source: runtimePlan.selectedProbe.source, |
| 3000 | sourceExecutable: |
| 3001 | runtimePlan.selectedProbe.realExecutable |
| 3002 | || runtimePlan.selectedProbe.executable |
| 3003 | || runtimePlan.selectedProbe.binary, |
| 3004 | sourceVersion: runtimePlan.selectedProbe.version, |
| 3005 | sourceMajorMinor: pythonMajorMinor(runtimePlan.selectedProbe), |
| 3006 | } |
| 3007 | : { |
| 3008 | kind: 'uv-managed', |
| 3009 | minimumVersionRequest: runtimePlan.minimumVersionRequest, |
| 3010 | }, |
| 3011 | }; |
| 3012 | |
| 3013 | for (let attempt = 0; attempt < 2; attempt += 1) { |
| 3014 | const runtimePython = runtimePythonPath(home); |
| 3015 | const currentStamp = readJsonFile(stampPath); |
| 3016 | const runtimeProbe = fs.existsSync(runtimePython) ? probePython(runtimePython) : null; |
| 3017 | const runtimeBroken = !runtimeProbe || !runtimeProbe.ok || !pythonMeetsMinimum(runtimeProbe); |
| 3018 | const stampChanged = JSON.stringify(currentStamp || null) !== JSON.stringify(desiredStamp); |
no test coverage detected