* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as vscode from 'vscode';
import * as path from 'path';
import { getDefaultShell, getProjectType } from './utils';
export async function buildCjmpProject(): Promise<void> {
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
if (workspaceRoot) {
console.log('The root directory of the workspace: ', workspaceRoot);
} else {
vscode.window.showErrorMessage('No folder or workspace is opened.');
return;
}
const projectType = getProjectType();
if (projectType === 'app') {
await buildAppProject(workspaceRoot);
} else if (projectType === 'logic-module' || projectType === 'module') {
await buildLogicOrModuleProject(workspaceRoot);
} else {
return;
}
}
function getTargetPlatformOptions(type: string): string[] | undefined {
const platformMap = new Map<string, string[]>([
['apk', ['android-arm64']],
['hap', ['ohos-arm64']],
['ios', ['ios-arm64']],
['ipa', ['ios-arm64']],
['ios-sim', ['ios-sim-arm64']],
['aar', ['android-arm64']],
['har', ['ohos-arm64']],
['framework', ['ios-arm64']],
['framework-sim', ['ios-sim-arm64']]
]);
return platformMap.get(type);
}
async function buildAppProject(workspaceRoot: string) {
let targetPlatformOptions;
const modeOptions = ['debug', 'release'];
const types = process.platform === 'darwin' ? ['apk', 'hap', 'ios', 'ipa', 'ios-sim'] : ['apk', 'hap'];
const type = await vscode.window.showQuickPick(types, {
placeHolder: 'Select the app type',
});
if (!type) {
vscode.window.showWarningMessage('Build canceled: No type selected.');
return;
}
targetPlatformOptions = getTargetPlatformOptions(type);
if (!targetPlatformOptions) {
vscode.window.showWarningMessage('Build canceled: No platform options available.');
return;
}
const targetPlatform = await vscode.window.showQuickPick(targetPlatformOptions, {
placeHolder: 'Select the platform',
});
if (!targetPlatform) {
vscode.window.showWarningMessage('Build canceled: No platform selected.');
return;
}
const mode = await vscode.window.showQuickPick(modeOptions, {
placeHolder: 'Select the build mode',
});
if (!mode) {
vscode.window.showWarningMessage('Build canceled: No build mode selected.');
return;
}
await cjmpBuildWithSpawn(workspaceRoot, type, targetPlatform, mode);
}
async function buildLogicOrModuleProject(workspaceRoot: string) {
let targetPlatformOptions;
const modeOptions = ['debug', 'release'];
const types = process.platform === 'darwin' ? ['aar', 'har', 'framework', 'framework-sim'] : ['aar', 'har'];
const type = await vscode.window.showQuickPick(types, {
placeHolder: 'Select the package type',
});
if (!type) {
vscode.window.showWarningMessage('Build canceled: No type selected.');
return;
}
targetPlatformOptions = getTargetPlatformOptions(type);
if (!targetPlatformOptions) {
vscode.window.showWarningMessage('Build canceled: No platform options available.');
return;
}
const targetPlatform = await vscode.window.showQuickPick(targetPlatformOptions, {
placeHolder: 'Select the platform',
});
if (!targetPlatform) {
vscode.window.showWarningMessage('Build canceled: No platform selected.');
return;
}
const mode = await vscode.window.showQuickPick(modeOptions, {
placeHolder: 'Select the build mode',
});
if (!mode) {
vscode.window.showWarningMessage('Build canceled: No build mode selected.');
return;
}
await cjmpBuildWithSpawn(workspaceRoot, type, targetPlatform, mode);
}
const cjmpBuildWithSpawn = async (localPath: string | undefined, type: string, target_platform: string, mode: string): Promise<void> => {
return new Promise((resolve, reject) => {
try {
const cjmpSdkPath = vscode.workspace.getConfiguration().get<string>('CJMP.sdkPath');
if (!cjmpSdkPath) {
vscode.window.showErrorMessage('CJMP SDK path is not configured in settings. Please set "CJMP.sdkPath" first.');
reject(new Error('CJMP SDK path is not configured.'));
return;
}
const isWindows = process.platform === 'win32';
const shellPath = isWindows ? 'cmd.exe' : getDefaultShell();
const buildCommand = `${path.join(cjmpSdkPath, 'keels')} build ${type} --platform ${target_platform} --${mode} -v`;
const terminal = vscode.window.createTerminal({
name: 'CJMP Build Terminal',
shellPath: shellPath,
cwd: localPath,
});
terminal.show();
terminal.sendText(`${buildCommand}`);
} catch (error) {
vscode.window.showErrorMessage(`Error building ${type}. : ${error instanceof Error ? error.message : String(error)}`);
reject(error);
}
});
};