|
5 | 5 | existsSync, |
6 | 6 | lstatSync, |
7 | 7 | mkdirSync, |
| 8 | + realpathSync, |
8 | 9 | readFileSync, |
9 | 10 | symlinkSync, |
10 | 11 | unlinkSync, |
@@ -78,8 +79,12 @@ const parseCommandLineArguments = (commandLine = process.argv) => { |
78 | 79 |
|
79 | 80 | const envCommitRef = useEnvironment ? process.env.CODIFF_COMMIT_REF || '' : ''; |
80 | 81 | const sourceRef = envCommitRef || commitRef; |
| 82 | + const repositoryPathProvided = Boolean( |
| 83 | + repositoryPath || (useEnvironment && process.env.CODIFF_REPOSITORY_PATH), |
| 84 | + ); |
81 | 85 | return { |
82 | 86 | launchOptions: { |
| 87 | + repositoryPathProvided, |
83 | 88 | source: sourceRef |
84 | 89 | ? { |
85 | 90 | ref: sourceRef, |
@@ -196,13 +201,63 @@ const openRepositoryFolder = async (browserWindow) => { |
196 | 201 | }); |
197 | 202 |
|
198 | 203 | if (!result.canceled && result.filePaths[0]) { |
199 | | - createWindow(result.filePaths[0], { walkthrough: false }); |
| 204 | + createWindow(result.filePaths[0], { repositoryPathProvided: true, walkthrough: false }); |
200 | 205 | } |
201 | 206 | }; |
202 | 207 |
|
203 | 208 | const getTerminalHelperSourcePath = () => |
204 | 209 | app.isPackaged ? join(process.resourcesPath, 'app/bin/codiff-app') : join(root, 'bin/codiff.js'); |
205 | 210 |
|
| 211 | +const getTerminalHelperTargetPaths = () => [ |
| 212 | + '/opt/homebrew/bin/codiff', |
| 213 | + '/usr/local/bin/codiff', |
| 214 | + join(app.getPath('home'), '.local/bin/codiff'), |
| 215 | +]; |
| 216 | + |
| 217 | +const getPreferredTerminalHelperTargetPath = () => { |
| 218 | + for (const directory of ['/opt/homebrew/bin', '/usr/local/bin']) { |
| 219 | + try { |
| 220 | + if (existsSync(directory)) { |
| 221 | + accessSync(directory, constants.W_OK); |
| 222 | + return join(directory, 'codiff'); |
| 223 | + } |
| 224 | + } catch { |
| 225 | + // Keep looking for a writable install location. |
| 226 | + } |
| 227 | + } |
| 228 | + |
| 229 | + return join(app.getPath('home'), '.local/bin/codiff'); |
| 230 | +}; |
| 231 | + |
| 232 | +const isInstalledTerminalHelper = (targetPath) => { |
| 233 | + try { |
| 234 | + if (!existsSync(targetPath)) { |
| 235 | + return false; |
| 236 | + } |
| 237 | + |
| 238 | + const target = lstatSync(targetPath); |
| 239 | + if (!target.isSymbolicLink()) { |
| 240 | + return false; |
| 241 | + } |
| 242 | + |
| 243 | + return realpathSync(targetPath) === realpathSync(getTerminalHelperSourcePath()); |
| 244 | + } catch { |
| 245 | + return false; |
| 246 | + } |
| 247 | +}; |
| 248 | + |
| 249 | +const getTerminalHelperStatus = () => { |
| 250 | + const installedPath = getTerminalHelperTargetPaths().find((targetPath) => |
| 251 | + isInstalledTerminalHelper(targetPath), |
| 252 | + ); |
| 253 | + |
| 254 | + return { |
| 255 | + command: 'codiff', |
| 256 | + installed: installedPath != null, |
| 257 | + path: installedPath || getPreferredTerminalHelperTargetPath(), |
| 258 | + }; |
| 259 | +}; |
| 260 | + |
206 | 261 | const getWritableHelperDirectory = () => { |
207 | 262 | for (const directory of ['/opt/homebrew/bin', '/usr/local/bin']) { |
208 | 263 | try { |
@@ -246,13 +301,15 @@ const installTerminalHelper = async (browserWindow) => { |
246 | 301 | message: `Installed codiff at ${targetPath}.`, |
247 | 302 | type: 'info', |
248 | 303 | }); |
| 304 | + return true; |
249 | 305 | } catch (error) { |
250 | 306 | await dialog.showMessageBox(browserWindow ?? undefined, { |
251 | 307 | buttons: ['OK'], |
252 | 308 | detail: error instanceof Error ? error.message : String(error), |
253 | 309 | message: 'Could not install the terminal helper.', |
254 | 310 | type: 'error', |
255 | 311 | }); |
| 312 | + return false; |
256 | 313 | } |
257 | 314 | }; |
258 | 315 |
|
@@ -392,7 +449,10 @@ const buildApplicationMenu = () => |
392 | 449 | }, |
393 | 450 | ]); |
394 | 451 |
|
395 | | -const createWindow = (repositoryPath, launchOptions = { walkthrough: false }) => { |
| 452 | +const createWindow = ( |
| 453 | + repositoryPath, |
| 454 | + launchOptions = { repositoryPathProvided: true, walkthrough: false }, |
| 455 | +) => { |
396 | 456 | const display = screen.getPrimaryDisplay(); |
397 | 457 | const { height, width } = display.workAreaSize; |
398 | 458 | const window = new BrowserWindow({ |
@@ -491,10 +551,18 @@ ipcMain.handle( |
491 | 551 | 'codiff:getLaunchOptions', |
492 | 552 | (event) => |
493 | 553 | windowLaunchOptions.get(event.sender.id) || { |
| 554 | + repositoryPathProvided: false, |
494 | 555 | walkthrough: false, |
495 | 556 | }, |
496 | 557 | ); |
497 | 558 |
|
| 559 | +ipcMain.handle('codiff:getTerminalHelperStatus', () => getTerminalHelperStatus()); |
| 560 | + |
| 561 | +ipcMain.handle('codiff:installTerminalHelper', async (event) => { |
| 562 | + await installTerminalHelper(BrowserWindow.fromWebContents(event.sender)); |
| 563 | + return getTerminalHelperStatus(); |
| 564 | +}); |
| 565 | + |
498 | 566 | ipcMain.handle('codiff:getWalkthrough', async (event, source) => { |
499 | 567 | const repositoryPath = windowRepositories.get(event.sender.id) || getLaunchPath(); |
500 | 568 | const launchOptions = windowLaunchOptions.get(event.sender.id); |
|
0 commit comments