-
-
Notifications
You must be signed in to change notification settings - Fork 219
Feat: Add support for different Node versions (NVM support) #1357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
bf1fcf8
5b90e61
8bd6e85
3c425cd
312afaf
cbcc0fb
584d661
fd7d57c
3955544
a130a92
cdf79e4
a7cb70b
fc05ca7
eba7db7
fa0a9b5
40c07c1
6e3cb3b
643f801
cb12745
05359be
64f8e9e
432b35b
5e4c0eb
79da7e7
8ba60d9
622223b
57df0b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,13 @@ | ||
| import { mkdtempSync } from "node:fs"; | ||
| import { spawn, spawnSync } from "node:child_process"; | ||
| import { mkdtempSync, readdirSync } from "node:fs"; | ||
| import { arch, platform, tmpdir } from "node:os"; | ||
| import { join } from "node:path"; | ||
| import { delimiter, join } from "node:path"; | ||
| import { | ||
| SDKMAN_TOOL_ALIASES, | ||
| getNvmToolDirectory, | ||
| getOrInstallNvmTool, | ||
| installSdkmanTool, | ||
| isNvmAvailable, | ||
| isSdkmanAvailable, | ||
| } from "./envcontext.js"; | ||
| import { DEBUG_MODE, hasAnyProjectType } from "./utils.js"; | ||
|
|
@@ -26,6 +30,7 @@ export function prepareEnv(filePath, options) { | |
| } | ||
| // Check the pre-requisites for python | ||
| preparePythonEnv(filePath, options); | ||
| prepareNodeEnv(filePath, options); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -91,3 +96,143 @@ export function preparePythonEnv(filePath, options) { | |
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Method to check and prepare the environment for node | ||
| * | ||
| * @param {String} filePath Path | ||
| * @param {Object} options CLI Options | ||
| */ | ||
| export function prepareNodeEnv(filePath, options) { | ||
| // check tool for windows | ||
| for (const pt of options.projectType) { | ||
| const nodeVersion = pt.replace(/\D/g, ""); | ||
| if ( | ||
| pt.startsWith("nodejs") && | ||
| nodeVersion && | ||
| !process.env.NODE_INSTALL_ARGS | ||
| ) { | ||
| if (!isNvmAvailable()) { | ||
| if (process.env.NVM_DIR) { | ||
| // for scenarios where nvm is not present, but | ||
| // we have $NVM_DIR | ||
| // custom logic to find nvmNodePath | ||
| let nvmNodePath; | ||
| const possibleNodeDir = join(process.env.NVM_DIR, "versions", "node"); | ||
|
|
||
| if (!tryLoadNvmAndInstallTool(nodeVersion)) { | ||
| console.log( | ||
| `Could not install Nodejs${nodeVersion}. There is a problem with loading nvm from ${process.env.NVM_DIR}`, | ||
| ); | ||
| return; | ||
| } | ||
|
|
||
| const nodeVersionArray = readdirSync(possibleNodeDir, { | ||
| withFileTypes: true, | ||
| }); | ||
| const nodeRe = new RegExp(`^v${nodeVersion}.`); | ||
| for (const nodeVersionsIter of nodeVersionArray) { | ||
| const fullPath = join(possibleNodeDir, nodeVersionsIter.name); | ||
| if ( | ||
| nodeVersionsIter.isDirectory() && | ||
| nodeRe.test(nodeVersionsIter.name) | ||
| ) { | ||
| nvmNodePath = join(fullPath, "bin"); | ||
| } | ||
| } | ||
| if (nvmNodePath) { | ||
| doNpmInstall(filePath, nvmNodePath); | ||
| } else { | ||
| console.log( | ||
| `"node version ${nodeVersion} was not found. Please install it with 'nvm install ${nodeVersion}"`, | ||
| ); | ||
| return; | ||
| } | ||
| } else { | ||
| console.log( | ||
| "Install nvm by following the instructions at https://github.com/nvm-sh/nvm", | ||
| ); | ||
| return; | ||
| } | ||
| } | ||
| // set path instead of nvm use | ||
| const nvmNodePath = getOrInstallNvmTool(nodeVersion); | ||
| doNpmInstall(filePath, nvmNodePath); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * If NVM_DIR is in path, however nvm command is not loaded. | ||
| * it is possible that required nodeVersion is not installed. | ||
| * This function loads nvm and install the nodeVersion | ||
| * | ||
| * @param {String} nodeVersion required version number | ||
| * | ||
| * @returns {Boolean} true if successful, otherwise false | ||
| */ | ||
| export function tryLoadNvmAndInstallTool(nodeVersion) { | ||
| const NVM_DIR = process.env.NVM_DIR; | ||
|
|
||
| const command = ` | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's ok for this PR, but this won't work in Windows powershell. Maybe this could be added in another PR. |
||
| if [ -f ${NVM_DIR}/nvm.sh ]; then | ||
| . ${NVM_DIR}/nvm.sh | ||
| nvm install ${nodeVersion} | ||
| else | ||
| echo "NVM script not found at ${NVM_DIR}/nvm.sh" | ||
| exit 1 | ||
| fi | ||
| `; | ||
|
|
||
| const spawnedShell = spawnSync(process.env.SHELL || "bash", ["-c", command], { | ||
| encoding: "utf-8", | ||
| shell: process.env.SHELL || true, | ||
| }); | ||
|
|
||
| return result.status === 0; | ||
| } | ||
|
|
||
| /** | ||
| * This method installs and create package-lock.json | ||
| * | ||
| * @param {String} filePath Path | ||
| * @param {String} nvmNodePath Path to node version in nvm | ||
| */ | ||
| export function doNpmInstall(filePath, nvmNodePath) { | ||
| // we do not install if INSTALL_ARGS set false | ||
| if (process.env.NODE_INSTALL_ARGS === false) { | ||
| return; | ||
| } | ||
|
|
||
| const newPath = `${nvmNodePath}${delimiter}${process.env.PATH}`; | ||
|
|
||
| const resultNpmInstall = spawnSync( | ||
| process.env.SHELL || "bash", | ||
| [ | ||
| "-i", | ||
| "-c", | ||
| `export PATH='${nvmNodePath}${delimiter}$PATH' && npm install --package-lock-only`, | ||
aryan-rajoria marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ], | ||
| { | ||
| encoding: "utf-8", | ||
| shell: process.env.SHELL || true, | ||
| cwd: filePath, | ||
| env: { | ||
| ...process.env, | ||
| PATH: newPath, | ||
| }, | ||
| }, | ||
| ); | ||
|
Comment on lines
+209
to
+225
Check warningCode scanning / CodeQL Shell command built from environment values
This shell command depends on an uncontrolled [file name](1).
|
||
|
|
||
| if (resultNpmInstall.status !== 0 || resultNpmInstall.stderr) { | ||
| // There was some problem with NpmInstall | ||
| if (DEBUG_MODE) { | ||
| if (console.stdout) { | ||
| console.log(result.stdout); | ||
| } | ||
| if (console.stderr) { | ||
| console.log(result.stderr); | ||
| } | ||
| } | ||
| } | ||
| } | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.