Skip to content

Commit

Permalink
feat(backend): show error if NodeJS is not installed (#779)
Browse files Browse the repository at this point in the history
* feat(backend): show error if nodejs installed not installed

* feat(backend): update yarn.lock

* feat(backend): remove await

* feat(backend): add condition for error only when not BAS

* feat(backend): remove sap-ux dep, move check to npm util, update tests, review comments

* feat(backend): updated yarn.lock

* feat(backend): use await in test
  • Loading branch information
docirl authored Oct 12, 2023
1 parent 93b3532 commit cdba893
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 1 deletion.
2 changes: 2 additions & 0 deletions packages/backend/src/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@ export default {
changing_owner_permissions: (globalNpmPath: string) => `Changing permissions of "${globalNpmPath}" folder...`,
timeout_install_generators:
"Some generators were not installed. You can continue to work in SAP Business Application Studio and we will retry next time you restart the dev space.",
nodejs_install_not_found:
"Node.js installation cannot be detected. Please ensure you have installed Node.js before attempting to use Template Wizard",
};
5 changes: 5 additions & 0 deletions packages/backend/src/panels/YeomanUIPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { homedir } from "os";
import { NpmCommand } from "../utils/npm";
import { Constants } from "../utils/constants";
import { notifyGeneratorsInstallationProgress } from "../utils/generators-installation-progress";
import messages from "../messages";

export class YeomanUIPanel extends AbstractWebviewPanel {
public static YEOMAN_UI = "Application Wizard";
Expand All @@ -41,6 +42,10 @@ export class YeomanUIPanel extends AbstractWebviewPanel {
}

public async loadWebviewPanel(uiOptions?: any): Promise<void> {
if (!Constants.IS_IN_BAS && (await NpmCommand.getNodeProcessVersions()).node === undefined) {
void vscode.window.showErrorMessage(messages.nodejs_install_not_found);
return;
}
const genNamespace = uiOptions?.generator;
if (genNamespace) {
const gensNS = await Env.getAllGeneratorNamespaces();
Expand Down
41 changes: 40 additions & 1 deletion packages/backend/src/utils/npm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import * as npmFetch from "npm-registry-fetch";
import { LookupGeneratorMeta } from "yeoman-environment";
import { getConsoleWarnLogger } from "../logger/console-logger";
import { Constants } from "./constants";
import { spawn } from "child_process";
import * as os from "os";

const promisifiedExec = promisify(exec);

Expand Down Expand Up @@ -164,7 +166,10 @@ class Command {
public async getPackagesData(query = "", author = ""): Promise<PackagesData> {
const gensQueryUrl = NpmCommand.getGensQueryURL(query, author);
const queryResult: any = await npmFetch.json(gensQueryUrl);
return { packages: _.get(queryResult, "objects", []), total: queryResult.total };
return {
packages: _.get(queryResult, "objects", []),
total: queryResult.total,
};
}

public async getPackageJsons(gensMeta: LookupGeneratorMeta[]): Promise<any[]> {
Expand Down Expand Up @@ -194,6 +199,40 @@ class Command {
return this.execCommand(command);
}

public async getNodeProcessVersions(): Promise<NodeJS.ProcessVersions> {
try {
const output = await this.spawnCommand("node", ["-p", "JSON.stringify(process.versions)"]);
return JSON.parse(output);
} catch (e) {
getConsoleWarnLogger().error(`Error retrieving NodeJS process versions: ${e.message}`);
return {} as NodeJS.ProcessVersions;
}
}

private spawnCommand(command: string, commandArgs: string[]): Promise<string> {
return new Promise((resolve, reject) => {
const spawnOptions = /^win/.test(process.platform)
? { windowsVerbatimArguments: true, shell: true, cwd: os.homedir() }
: { cwd: os.homedir() };
let output = "";
const spawnProcess = spawn(command, commandArgs, spawnOptions);
spawnProcess.stdout.on("data", (data) => {
const newData = data.toString();
output += newData;
});
spawnProcess.stderr.on("data", (data) => {
const newData = data.toString();
output += newData;
});
spawnProcess.on("exit", () => {
resolve(output);
});
spawnProcess.on("error", (error) => {
reject(error);
});
});
}

public async checkAccessAndSetGeneratorsPath() {
if (!Constants.IS_IN_BAS) {
const accessResult = await this.getAccessResult();
Expand Down
15 changes: 15 additions & 0 deletions packages/backend/test/panels/YeomanUIPanel.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { set } from "lodash";
import { expect } from "chai";
import { join } from "path";
import { homedir } from "os";
import messages from "../../src/messages";

describe("YeomanUIPanel unit test", () => {
let sandbox: SinonSandbox;
Expand Down Expand Up @@ -60,6 +61,7 @@ describe("YeomanUIPanel unit test", () => {
});

it("generator is choosen", () => {
npmUtilsMock.expects("getNodeProcessVersions").resolves({ node: "20.6.0" });
envUtilsMock.expects("getAllGeneratorNamespaces").twice().resolves(["gen1:test", "test:app", "code:app"]);
windowMock.expects("showQuickPick").resolves("test:app");
void panel.runGenerator();
Expand All @@ -69,6 +71,7 @@ describe("YeomanUIPanel unit test", () => {
describe("loadWebviewPanel", () => {
describe("in VSCODE", () => {
beforeEach(() => {
npmUtilsMock.expects("getNodeProcessVersions").resolves({ node: "20.6.0" });
Constants["IS_IN_BAS"] = false;
});

Expand Down Expand Up @@ -130,6 +133,18 @@ describe("YeomanUIPanel unit test", () => {
void panel.loadWebviewPanel({ generator: "test:app" });
});
});

describe("no NodeJS installation is found in VSCode", () => {
beforeEach(() => {
npmUtilsMock.expects("getNodeProcessVersions").resolves({});
Constants["IS_IN_BAS"] = false;
});

it("should show an error message", async () => {
windowMock.expects("showErrorMessage").withExactArgs(messages.nodejs_install_not_found);
await panel.loadWebviewPanel();
});
});
});

describe("toggleOutput", () => {
Expand Down

0 comments on commit cdba893

Please sign in to comment.