| // Copyright 2024 The Fuchsia Authors. All rights reserved. |
| // 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 { window } from 'vscode'; |
| import { Setup } from './extension'; |
| |
| /** |
| * initialize fuchsia workflow interaction commands |
| */ |
| export function setUpWorkflowInteraction(ctx: vscode.ExtensionContext, setup: Setup) { |
| vscode.commands.registerCommand( |
| 'fuchsia.fx.set', |
| async (product?: string, board?: string, packages?: string) => { |
| if (!product) { |
| await getList('list-products').then(async (list) => { |
| product = await window.showQuickPick(list); |
| }); |
| } |
| |
| if (!board) { |
| await getList('list-boards').then(async (list) => { |
| board = await window.showQuickPick(list); |
| }); |
| } |
| |
| if (!packages) { |
| packages = await window.showInputBox({ |
| placeHolder: '(e.g. //examples //examples:tests)', |
| prompt: 'Enter packages to include in universe' |
| }); |
| } |
| |
| if (!product || !board) { |
| return; |
| } |
| |
| let args = ['set', `${product?.trimEnd()}.${board?.trimEnd()}`]; |
| if (packages) { |
| let packageList = packages?.split(' '); |
| packageList?.forEach(packageItem => { |
| args.push('--with'); |
| args.push(packageItem); |
| }); |
| } |
| |
| void window.withProgress({ |
| location: vscode.ProgressLocation.Notification, |
| title: 'fx set', |
| cancellable: true |
| }, async (progress, token) => { |
| let cmd = setup.fx.runAsync( |
| args, |
| () => void window.showInformationMessage('fx set completed'), |
| handleErr |
| ); |
| |
| token.onCancellationRequested(() => { |
| console.log('User canceled fx build operation'); |
| cmd?.stop(); |
| }); |
| |
| let exitCode = await cmd?.exitCode; |
| return exitCode === 0 ? Promise.resolve() : Promise.reject(exitCode); |
| }); |
| |
| /** |
| * get list of results from fx command |
| * @param args fx command to run |
| */ |
| async function getList(arg: string) { |
| let data: string[] = []; |
| let cmd = setup.fx.runAsync( |
| [arg], |
| (buffer: Buffer) => { |
| const msg = new TextDecoder().decode(buffer); |
| if (msg.includes('ERROR')) { |
| void window.showErrorMessage(msg); |
| } else { |
| data.push.apply(data, msg.split('\n').filter(item => item)); |
| } |
| }, |
| handleErr); |
| let exitCode = await cmd?.exitCode; |
| return exitCode === 0 ? Promise.resolve(data) : Promise.reject(exitCode); |
| } |
| |
| // TODO(https://fxbug.dev/369839772): handle errs w/ task problem matcher |
| /** |
| * handle errs from callback |
| */ |
| function handleErr(buffer: Buffer) { |
| const msg = new TextDecoder().decode(buffer); |
| void window.showErrorMessage(msg); |
| } |
| } |
| ); |
| |
| vscode.commands.registerCommand('fuchsia.fx.build', () => { |
| void window.withProgress({ |
| location: vscode.ProgressLocation.Notification, |
| title: 'fx build', |
| cancellable: true |
| }, async (progress, token) => { |
| let cmd = setup.fx.runAsync(['build'], handleData, handleData); |
| let percentage: number; |
| |
| token.onCancellationRequested(() => { |
| console.log('User canceled fx build operation'); |
| cmd?.stop(); |
| }); |
| |
| /** |
| * callback to handle buffer from process |
| */ |
| function handleData(buffer: Buffer) { |
| const msg = new TextDecoder().decode(buffer); |
| // TODO(https://fxbug.dev/369839772): handle errs w/ task problem matcher |
| if (msg.includes('ERROR') || msg.includes('credentials')) { |
| void window.showErrorMessage(msg); |
| } |
| if (msg.includes('Locked')) { |
| void window.showWarningMessage(msg); |
| } |
| if (msg.includes('no work to do')) { |
| void window.showInformationMessage(msg); |
| } |
| // TODO(https://fxbug.dev/375234893): move msg to output window |
| if (msg.includes('%')) { |
| let match = msg.match(/\d+%/); |
| if (match) { |
| let lastPercent = percentage ?? 0; |
| percentage = parseInt(match[0]); |
| progress.report({ increment: percentage - lastPercent, message: `\n ${msg}` }); |
| } |
| } |
| if (msg.includes('actions')) { |
| progress.report({ message: `${msg}` }); |
| } |
| } |
| |
| let exitCode = await cmd?.exitCode; |
| return exitCode === 0 ? Promise.resolve() : Promise.reject(exitCode); |
| }); |
| }); |
| } |