Skip to content

Commit 11ecd7f

Browse files
authored
Refactor UV availability check and command retrieval (Windows)
1 parent f2115f1 commit 11ecd7f

File tree

1 file changed

+45
-23
lines changed

1 file changed

+45
-23
lines changed

src/installer/get-python.js

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -118,22 +118,6 @@ async function isValidPythonVersion(executable) {
118118
}
119119
}
120120

121-
/**
122-
* Check if UV (astral-sh/uv) package manager is available on the system
123-
* UV is a fast Python package installer and resolver written in Rust
124-
* @returns {Promise<boolean>} True if UV is installed and accessible via PATH
125-
*/
126-
async function isUVAvailable() {
127-
try {
128-
await execFile('uv', ['--version'], { timeout: 5000 });
129-
log('info', 'UV is available on system');
130-
return true;
131-
} catch {
132-
log('info', 'UV not found on system');
133-
return false;
134-
}
135-
}
136-
137121
/**
138122
* Get UV executable path after installation
139123
* On Windows, UV is installed to %USERPROFILE%\.local\bin
@@ -146,6 +130,32 @@ function getUVExecutablePath() {
146130
return path.join(homeDir, '.local', 'bin', uvExe);
147131
}
148132

133+
/**
134+
* Check if UV (astral-sh/uv) package manager is available on the system
135+
* UV is a fast Python package installer and resolver written in Rust
136+
* Checks both PATH and the default installation location
137+
* @returns {Promise<boolean>} True if UV is installed and accessible
138+
*/
139+
async function isUVAvailable() {
140+
// First check if UV is in PATH
141+
try {
142+
await execFile('uv', ['--version'], { timeout: 5000 });
143+
log('info', 'UV is available on system PATH');
144+
return true;
145+
} catch {
146+
// UV not in PATH, check default installation location
147+
try {
148+
const uvPath = getUVExecutablePath();
149+
await execFile(uvPath, ['--version'], { timeout: 5000 });
150+
log('info', `UV found at: ${uvPath}`);
151+
return true;
152+
} catch {
153+
log('info', 'UV not found on system');
154+
return false;
155+
}
156+
}
157+
}
158+
149159
/**
150160
* Install UV package manager using official installation scripts
151161
* Downloads and runs platform-specific installer from astral.sh
@@ -182,6 +192,21 @@ async function installUV() {
182192
}
183193
}
184194

195+
/**
196+
* Get the UV command to use - either from PATH or direct path
197+
* @returns {Promise<string>} UV command or path to use
198+
*/
199+
async function getUVCommand() {
200+
// Try UV in PATH first
201+
try {
202+
await execFile('uv', ['--version'], { timeout: 5000 });
203+
return 'uv';
204+
} catch {
205+
// Use direct path to UV installation
206+
return getUVExecutablePath();
207+
}
208+
}
209+
185210
/**
186211
* Install Python using UV package manager
187212
* Creates a virtual environment using `uv venv` with Python 3.13
@@ -195,17 +220,14 @@ async function installPythonWithUV(destinationDir, pythonVersion = '3.13') {
195220
log('info', `Creating Python ${pythonVersion} venv using UV`);
196221

197222
// Ensure UV is available, install if necessary
198-
let uvCommand = 'uv';
199223
if (!(await isUVAvailable())) {
200224
await installUV();
201-
// On Windows, UV might not be in PATH immediately after installation
202-
// Use direct path to UV executable
203-
if (proc.IS_WINDOWS) {
204-
uvCommand = getUVExecutablePath();
205-
log('info', `Using UV from: ${uvCommand}`);
206-
}
207225
}
208226

227+
// Get the correct UV command (from PATH or direct path)
228+
const uvCommand = await getUVCommand();
229+
log('info', `Using UV command: ${uvCommand}`);
230+
209231
// Clean up any existing installation to avoid conflicts
210232
try {
211233
await fs.promises.rm(destinationDir, { recursive: true, force: true });

0 commit comments

Comments
 (0)