| // Copyright 2022 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| import * as vscode from 'vscode'; | |
| import {isChromiumosRoot} from '../common/chromiumos/fs'; | |
| import {hints} from '../services/config'; | |
| import * as sudo from '../services/sudo'; | |
| import {Metrics} from './metrics/metrics'; | |
| /** | |
| * Activates the hint handlers. | |
| * | |
| * When adding hints on user actions, instead of embedding hint logic into | |
| * individual modules, you can provide event emitters there and subscribe | |
| * to them here, by which you can decouple hint logic and individual modules. | |
| */ | |
| export function activate(context: vscode.ExtensionContext): void { | |
| context.subscriptions.push( | |
| sudo.onDidRunSudoWithPassword(onDidRunSudoWithPassword), | |
| vscode.workspace.onDidChangeWorkspaceFolders(onDidChangeWorkspaceFolders) | |
| ); | |
| void onDidChangeWorkspaceFolders({ | |
| added: vscode.workspace.workspaceFolders ?? [], | |
| removed: [], | |
| }); | |
| } | |
| const maxSudoPasswordIntervalInMilli = 3 * 60 * 60 * 1000; // 3 hours | |
| let lastDidRunSudoWithPassword: Date | undefined = undefined; | |
| let didShowSudoHint = false; | |
| /** | |
| * Show a hint to set up sudo to request passwords less frequently | |
| * when the user needed to type passwords twice in a row. | |
| */ | |
| function onDidRunSudoWithPassword(): void { | |
| const now = new Date(); | |
| if (lastDidRunSudoWithPassword !== undefined) { | |
| const elapsed = now.getTime() - lastDidRunSudoWithPassword.getTime(); | |
| if (elapsed < maxSudoPasswordIntervalInMilli) { | |
| if (!didShowSudoHint) { | |
| void (async () => { | |
| const choice = await vscode.window.showInformationMessage( | |
| 'You can set up sudo to request passwords less frequently.', | |
| 'Open Documentation' | |
| ); | |
| if (choice) { | |
| void vscode.env.openExternal( | |
| vscode.Uri.parse( | |
| 'https://chromium.googlesource.com/chromiumos/docs/+/HEAD/tips-and-tricks.md#how-to-make-sudo-a-little-more-permissive' | |
| ) | |
| ); | |
| } | |
| })(); | |
| didShowSudoHint = true; | |
| } | |
| } | |
| } | |
| lastDidRunSudoWithPassword = now; | |
| } | |
| const onDidHandleChangeWorkspaceFoldersEmitter = | |
| new vscode.EventEmitter<void>(); | |
| export const onDidHandleChangeWorkspaceFolders = | |
| onDidHandleChangeWorkspaceFoldersEmitter.event; | |
| async function onDidChangeWorkspaceFolders({ | |
| added, | |
| }: vscode.WorkspaceFoldersChangeEvent): Promise<void> { | |
| for (const dir of added) { | |
| if ( | |
| hints.tooLargeWorkspace.get() && | |
| (await isChromiumosRoot(dir.uri.fsPath)) | |
| ) { | |
| Metrics.send({ | |
| category: 'background', | |
| group: 'hints', | |
| description: 'show chromiumos workspace warning', | |
| name: 'hints_show_chromiumos_workspace_warning', | |
| }); | |
| const openSubdirectory = 'Open subdirectory'; | |
| const dontAskAgain = "Don't ask again"; | |
| const choice = await vscode.window.showWarningMessage( | |
| 'Opening the entire chromiumos directory can cause performance problem; we recommend to open a subdirectory', | |
| openSubdirectory, | |
| dontAskAgain | |
| ); | |
| if (choice === openSubdirectory) { | |
| const folderUri = await vscode.window.showOpenDialog({ | |
| defaultUri: dir.uri, | |
| canSelectMany: false, | |
| openLabel: 'Select', | |
| canSelectFiles: false, | |
| canSelectFolders: true, | |
| }); | |
| if (folderUri) { | |
| void vscode.commands.executeCommand( | |
| 'vscode.openFolder', | |
| folderUri[0] | |
| ); | |
| } | |
| } else if (choice === dontAskAgain) { | |
| await hints.tooLargeWorkspace.update(false); | |
| Metrics.send({ | |
| category: 'interactive', | |
| group: 'hints', | |
| description: 'show chromiumos workspace warning', | |
| name: 'hints_ignore_chromiumos_workspace_warning', | |
| }); | |
| } | |
| } | |
| } | |
| onDidHandleChangeWorkspaceFoldersEmitter.fire(); | |
| } |