blob: 0432d12f787585ca2c86f5947c44bdcce8f5eb7e [file]
// 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);
});
});
}