( packageManager: PythonPackageManager, )
| 88 | * @returns Result indicating success or failure |
| 89 | */ |
| 90 | export async function installIt2( |
| 91 | packageManager: PythonPackageManager, |
| 92 | ): Promise<It2InstallResult> { |
| 93 | logForDebugging(`[it2Setup] Installing it2 using ${packageManager}`) |
| 94 | |
| 95 | // Run from home directory to avoid reading project-level pip.conf/uv.toml |
| 96 | // which could be maliciously crafted to redirect to an attacker's PyPI server |
| 97 | let result |
| 98 | switch (packageManager) { |
| 99 | case 'uvx': |
| 100 | // uv tool install it2 installs it globally in isolated env |
| 101 | // (uvx is for running, uv tool install is for installing) |
| 102 | result = await execFileNoThrowWithCwd('uv', ['tool', 'install', 'it2'], { |
| 103 | cwd: homedir(), |
| 104 | }) |
| 105 | break |
| 106 | case 'pipx': |
| 107 | result = await execFileNoThrowWithCwd('pipx', ['install', 'it2'], { |
| 108 | cwd: homedir(), |
| 109 | }) |
| 110 | break |
| 111 | case 'pip': |
| 112 | // Use --user to install without sudo |
| 113 | result = await execFileNoThrowWithCwd( |
| 114 | 'pip', |
| 115 | ['install', '--user', 'it2'], |
| 116 | { cwd: homedir() }, |
| 117 | ) |
| 118 | if (result.code !== 0) { |
| 119 | // Try pip3 if pip fails |
| 120 | result = await execFileNoThrowWithCwd( |
| 121 | 'pip3', |
| 122 | ['install', '--user', 'it2'], |
| 123 | { cwd: homedir() }, |
| 124 | ) |
| 125 | } |
| 126 | break |
| 127 | } |
| 128 | |
| 129 | if (result.code !== 0) { |
| 130 | const error = result.stderr || 'Unknown installation error' |
| 131 | logError(new Error(`[it2Setup] Failed to install it2: ${error}`)) |
| 132 | return { |
| 133 | success: false, |
| 134 | error, |
| 135 | packageManager, |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | logForDebugging('[it2Setup] it2 installed successfully') |
| 140 | return { |
| 141 | success: true, |
| 142 | packageManager, |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | /** |
| 147 | * Verifies that it2 is properly configured and can communicate with iTerm2. |
no test coverage detected