@rushstack/rush-sdk
Advanced tools
Comparing version 5.62.0-pr3059 to 5.62.0
104
lib/index.js
@@ -28,5 +28,10 @@ "use strict"; | ||
const RUSH_LIB_NAME = '@microsoft/rush-lib'; | ||
const verboseEnabled = typeof process !== 'undefined' && process.env.RUSH_SDK_DEBUG === '1'; | ||
const terminal = new node_core_library_1.Terminal(new node_core_library_1.ConsoleTerminalProvider({ | ||
verboseEnabled | ||
})); | ||
// SCENARIO 1: Rush's PluginManager has initialized "rush-sdk" with Rush's own instance of rush-lib. | ||
// The Rush host process will assign "global.___rush___rushLibModule" before loading the plugin. | ||
let rushLibModule = global.___rush___rushLibModule; | ||
let rushLibModule = global.___rush___rushLibModule || global.___rush___rushLibModuleFromInstallAndRunRush; | ||
let errorMessage = ''; | ||
// SCENARIO 2: The project importing "rush-sdk" has installed its own instance of "rush-lib" | ||
@@ -47,11 +52,9 @@ // as a package.json dependency. For example, this is used by the Jest tests for Rush plugins. | ||
// Try to resolve rush-lib from the caller's folder | ||
terminal.writeVerboseLine(`Try to load ${RUSH_LIB_NAME} from caller package`); | ||
try { | ||
const rushLibModulePath = node_core_library_1.Import.resolveModule({ | ||
modulePath: RUSH_LIB_NAME, | ||
baseFolderPath: callerPackageFolder | ||
}); | ||
rushLibModule = require(rushLibModulePath); | ||
rushLibModule = requireRushLibUnderFolderPath(callerPackageFolder); | ||
} | ||
catch (error) { | ||
// If we fail to resolve it, ignore the error | ||
terminal.writeVerboseLine(`Failed to load ${RUSH_LIB_NAME} from caller package`); | ||
} | ||
@@ -61,5 +64,5 @@ // If two different libraries invoke `rush-sdk`, and one of them provides "rush-lib" | ||
if (rushLibModule !== undefined) { | ||
// TODO: When we implement Scenario 3, we should also add some diagnostic state | ||
// to track which scenario is active and how it got initialized. | ||
global.___rush___rushLibModule = rushLibModule; | ||
terminal.writeVerboseLine(`Loaded ${RUSH_LIB_NAME} from caller`); | ||
} | ||
@@ -72,9 +75,58 @@ } | ||
// In this case, we can use install-run-rush.js to obtain the appropriate rush-lib version for the monorepo. | ||
// | ||
// NOT IMPLEMENTED YET | ||
if (rushLibModule === undefined) { | ||
try { | ||
const rushJsonPath = tryFindRushJsonLocation(process.cwd()); | ||
if (!rushJsonPath) { | ||
throw new Error('Unable to find rush.json in the current folder or its parent folders.\n' + | ||
'This tool is meant to be invoked from a working directory inside a Rush repository.'); | ||
} | ||
const monorepoRoot = path.dirname(rushJsonPath); | ||
const rushJson = node_core_library_1.JsonFile.load(rushJsonPath); | ||
const { rushVersion } = rushJson; | ||
const installRunNodeModuleFolder = path.join(monorepoRoot, `common/temp/install-run/@microsoft+rush@${rushVersion}`); | ||
try { | ||
// First, try to load the version of "rush-lib" that was installed by install-run-rush.js | ||
terminal.writeVerboseLine(`Trying to load ${RUSH_LIB_NAME} installed by install-run-rush`); | ||
rushLibModule = requireRushLibUnderFolderPath(installRunNodeModuleFolder); | ||
} | ||
catch (e) { | ||
let installAndRunRushStderrContent = ''; | ||
try { | ||
const installAndRunRushJSPath = path.join(monorepoRoot, 'common/scripts/install-run-rush.js'); | ||
terminal.writeLine('The Rush engine has not been installed yet. Invoking install-run-rush.js...'); | ||
const installAndRuhRushProcess = node_core_library_1.Executable.spawnSync('node', [installAndRunRushJSPath, '--help'], { | ||
stdio: 'pipe' | ||
}); | ||
installAndRunRushStderrContent = installAndRuhRushProcess.stderr; | ||
if (installAndRuhRushProcess.status !== 0) { | ||
throw new Error(`The ${RUSH_LIB_NAME} package failed to install`); | ||
} | ||
// Retry to load "rush-lib" after install-run-rush run | ||
terminal.writeVerboseLine(`Trying to load ${RUSH_LIB_NAME} installed by install-run-rush a second time`); | ||
rushLibModule = requireRushLibUnderFolderPath(installRunNodeModuleFolder); | ||
} | ||
catch (e) { | ||
console.error(`${installAndRunRushStderrContent}`); | ||
throw new Error(`The ${RUSH_LIB_NAME} package failed to load`); | ||
} | ||
} | ||
if (rushLibModule !== undefined) { | ||
// to track which scenario is active and how it got initialized. | ||
global.___rush___rushLibModuleFromInstallAndRunRush = rushLibModule; | ||
terminal.writeVerboseLine(`Loaded ${RUSH_LIB_NAME} installed by install-run-rush`); | ||
} | ||
} | ||
catch (e) { | ||
// no-catch | ||
errorMessage = e.message; | ||
} | ||
} | ||
if (rushLibModule === undefined) { | ||
// This error indicates that a project is trying to import "@rushstack/rush-sdk", but the Rush engine | ||
// instance cannot be found. If you are writing Jest tests for a Rush plugin, add "@microsoft/rush-lib" | ||
// to the devDependencies for your project. | ||
throw new Error('The "@rushstack/rush-sdk" package context has not been initialized.'); | ||
console.error(`Error: The @rushstack/rush-sdk package was not able to load the Rush engine: | ||
${errorMessage} | ||
`); | ||
process.exit(1); | ||
} | ||
@@ -94,2 +146,34 @@ // Based on TypeScript's __exportStar() | ||
} | ||
/** | ||
* Require `@microsoft/rush-lib` under the specified folder path. | ||
*/ | ||
function requireRushLibUnderFolderPath(folderPath) { | ||
const rushLibModulePath = node_core_library_1.Import.resolveModule({ | ||
modulePath: RUSH_LIB_NAME, | ||
baseFolderPath: folderPath | ||
}); | ||
return require(rushLibModulePath); | ||
} | ||
/** | ||
* Find the rush.json location and return the path, or undefined if a rush.json can't be found. | ||
* | ||
* @privateRemarks | ||
* Keep this in sync with `RushConfiguration.tryFindRushJsonLocation`. | ||
*/ | ||
function tryFindRushJsonLocation(startingFolder) { | ||
let currentFolder = startingFolder; | ||
// Look upwards at parent folders until we find a folder containing rush.json | ||
for (let i = 0; i < 10; ++i) { | ||
const rushJsonFilename = path.join(currentFolder, 'rush.json'); | ||
if (node_core_library_1.FileSystem.exists(rushJsonFilename)) { | ||
return rushJsonFilename; | ||
} | ||
const parentFolder = path.dirname(currentFolder); | ||
if (parentFolder === currentFolder) { | ||
break; | ||
} | ||
currentFolder = parentFolder; | ||
} | ||
return undefined; | ||
} | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@rushstack/rush-sdk", | ||
"version": "5.62.0-pr3059", | ||
"version": "5.62.0", | ||
"description": "An API for interacting with the Rush engine", | ||
@@ -20,3 +20,3 @@ "repository": { | ||
"devDependencies": { | ||
"@microsoft/rush-lib": "5.62.0-pr3059", | ||
"@microsoft/rush-lib": "5.62.0", | ||
"@rushstack/eslint-config": "2.5.1", | ||
@@ -23,0 +23,0 @@ "@rushstack/heft": "0.44.2", |
@@ -13,3 +13,3 @@ ## @rushstack/rush-sdk | ||
3. **(Not implemented yet)** For scripts and tools that are designed to be used in a Rush monorepo, in the future **@rushstack/rush-sdk** will automatically invoke **install-run-rush.js** and load the local installation. This ensures that tools load a compatible version of the Rush engine for the given branch. Once this is implemented, **@rushstack/rush-sdk** can replace **@microsoft/rush-lib** entirely as the official API interface, with the latter serving as the underlying implementation. | ||
3. For scripts and tools that are designed to be used in a Rush monorepo, in the future **@rushstack/rush-sdk** will automatically invoke **install-run-rush.js** and load the local installation. This ensures that tools load a compatible version of the Rush engine for the given branch. Once this is implemented, **@rushstack/rush-sdk** can replace **@microsoft/rush-lib** entirely as the official API interface, with the latter serving as the underlying implementation. | ||
@@ -19,3 +19,7 @@ | ||
## Debugging | ||
Verbose logging can be turn on by set environment variable `RUSH_SDK_DEBUG` to `1` | ||
## Links | ||
@@ -22,0 +26,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
130498
2844
0
31
3