Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export function compileTypeScript() {
// Find this project's relative directory. Rush already knows this, so just ask.
const packageDir = path.resolve('.');
const rushConfig = RushConfiguration.loadFromDefaultLocation({
startingFolder: packageDir
});
const project = rushConfig.tryGetProjectForPath(packageDir);
if (!project) {
console.error(`Unable to find project for '${packageDir}' in 'rush.json'.`);
throw Error();
}
//REVIEW: Better way to detect deployable projects?
// Since extension .js files are deployed to 'dist//out', and libraries are deployed to
// 'dist//node_modules//out'.
const pathToRoot = (path.dirname(project.projectRelativeFolder) === 'extensions') ?
'../../..' : '../../../../..';
return tsProject.src()
.pipe(sourcemaps.init())
public regenerateAndValidateShrinkwrap(shrinkwrapFile: ShrinkwrapFile|undefined): boolean {
console.log('Creating temp projects...');
if (fsx.existsSync(this._rushConfiguration.tempModulesFolder)) {
Utilities.dangerouslyDeletePath(this._rushConfiguration.tempModulesFolder);
}
Utilities.createFolderWithRetry(this._rushConfiguration.tempModulesFolder);
let shrinkwrapIsValid: boolean = true;
if (shrinkwrapFile) {
// Check any pinned dependencies first
this._rushConfiguration.pinnedVersions.forEach((version: string, dependency: string) => {
if (!shrinkwrapFile.hasCompatibleDependency(dependency, version)) {
console.log(colors.yellow(
`${os.EOL}The NPM shrinkwrap file does satisfy pinned version ${dependency}`
+ ` ("${version}").`));
shrinkwrapIsValid = false;
}
});
} else {
shrinkwrapIsValid = false;
}
function createSymlinksForTopLevelProject(localPackage: Package): void {
const localModuleFolder: string = path.join(localPackage.folderPath, 'node_modules');
// Sanity check
if (localPackage.parent) {
throw new Error('The provided package is not a top-level project');
}
// The root-level folder is the project itself, so we simply delete its node_modules
// to start clean
console.log('Purging ' + localModuleFolder);
Utilities.dangerouslyDeletePath(localModuleFolder);
if (localPackage.children.length > 0) {
Utilities.createFolderWithRetry(localModuleFolder);
for (const child of localPackage.children) {
createSymlinksForDependencies(child);
}
}
}
}
// We will NOT locally link this package; add it as a regular dependency.
tempPackageJson.dependencies[pair.packageName] = pair.packageVersion;
if (shrinkwrapFile) {
if (!shrinkwrapFile.hasCompatibleDependency(pair.packageName, pair.packageVersion, tempProjectName)) {
console.log(colors.yellow(
`${os.EOL}The NPM shrinkwrap file does not provide dependency ${pair.packageName}`
+ ` ("${pair.packageVersion}") required by "${rushProject.packageName}".`));
shrinkwrapIsValid = false;
}
}
}
JsonFile.saveJsonFile(tempPackageJson, tempPackageJsonFilename);
}
console.log('Writing common/package.json');
const commonPackageJsonFilename: string = path.join(this._rushConfiguration.commonFolder, 'package.json');
JsonFile.saveJsonFile(commonPackageJson, commonPackageJsonFilename);
return shrinkwrapIsValid;
}
}
public regenerateAndValidateShrinkwrap(shrinkwrapFile: ShrinkwrapFile|undefined): boolean {
console.log('Creating temp projects...');
if (fsx.existsSync(this._rushConfiguration.tempModulesFolder)) {
Utilities.dangerouslyDeletePath(this._rushConfiguration.tempModulesFolder);
}
Utilities.createFolderWithRetry(this._rushConfiguration.tempModulesFolder);
let shrinkwrapIsValid: boolean = true;
if (shrinkwrapFile) {
// Check any pinned dependencies first
this._rushConfiguration.pinnedVersions.forEach((version: string, dependency: string) => {
if (!shrinkwrapFile.hasCompatibleDependency(dependency, version)) {
console.log(colors.yellow(
`${os.EOL}The NPM shrinkwrap file does satisfy pinned version ${dependency}`
+ ` ("${version}").`));
shrinkwrapIsValid = false;
}
});
function createSymlinksForTopLevelProject(localPackage: Package): void {
const localModuleFolder: string = path.join(localPackage.folderPath, 'node_modules');
// Sanity check
if (localPackage.parent) {
throw new Error('The provided package is not a top-level project');
}
// The root-level folder is the project itself, so we simply delete its node_modules
// to start clean
console.log('Purging ' + localModuleFolder);
Utilities.dangerouslyDeletePath(localModuleFolder);
if (localPackage.children.length > 0) {
Utilities.createFolderWithRetry(localModuleFolder);
for (const child of localPackage.children) {
createSymlinksForDependencies(child);
}
}
}
// into the Common folder)?
const matchedRushPackage: RushConfigurationProject = rushConfiguration.getProjectByName(dependency.name);
if (matchedRushPackage) {
const matchedVersion: string = matchedRushPackage.packageJson.version;
// The dependency name matches an Rush project, but are there any other reasons not
// to create a local link?
if (cyclicSubtreeRoot) {
// DO NOT create a local link, because this is part of an existing
// cyclicDependencyProjects subtree
} else if (project.cyclicDependencyProjects.has(dependency.name)) {
// DO NOT create a local link, because we are starting a new
// cyclicDependencyProjects subtree
startingCyclicSubtree = true;
} else if (dependency.kind !== PackageDependencyKind.LocalLink
&& !semver.satisfies(matchedVersion, dependency.versionRange)) {
// DO NOT create a local link, because the local project's version isn't SemVer compatible.
// (Note that in order to make version bumping work as expected, we ignore SemVer for
// immediate dependencies of top-level projects, indicated by PackageDependencyKind.LocalLink.
// Is this wise?)
console.log(colors.yellow(`Rush will not locally link ${dependency.name} for ${localPackage.name}`
+ ` because the requested version "${dependency.versionRange}" is incompatible`
+ ` with the local version ${matchedVersion}`));
} else {
// Yes, it is compatible, so create a symlink to the Rush project.
// If the link is coming from our top-level Rush project, then record a
// build dependency in rush-link.json:
if (localPackage === localProjectPackage) {
if (startingCyclicSubtree) {
// If we are starting a new subtree, then newLocalPackage will be its root
// NOTE: cyclicSubtreeRoot is guaranteed to be undefined here, since we never start
// a new tree inside an existing tree
newCyclicSubtreeRoot = newLocalPackage;
}
resolution.parentForCreate.addChild(newLocalPackage);
queue.push({
commonPackage: commonDependencyPackage,
localPackage: newLocalPackage,
cyclicSubtreeRoot: newCyclicSubtreeRoot
});
}
} else {
if (dependency.kind !== PackageDependencyKind.Optional) {
throw Error(`The dependency "${dependency.name}" needed by "${localPackage.name}"`
+ ` was not found the ${rushConfiguration.commonFolderName} folder -- do you need to run "rush generate"?`);
} else {
console.log(colors.yellow('Skipping optional dependency: ' + dependency.name));
}
}
}
}
// When debugging, you can uncomment this line to dump the data structure
// to the console:
// localProjectPackage.printTree();
createSymlinksForTopLevelProject(localProjectPackage);
// Also symlink the ".bin" folder
public ensureRushVersionInstalled(
version: string,
configuration: MinimalRushConfiguration | undefined
): Promise {
const isLegacyRushVersion: boolean = semver.lt(version, '4.0.0');
const expectedRushPath: string = path.join(this._rushGlobalFolder.nodeSpecificPath, `rush-${version}`);
const installMarker: _LastInstallFlag = new _LastInstallFlag(expectedRushPath, {
node: process.versions.node
});
let installPromise: Promise = Promise.resolve();
if (!installMarker.isValid()) {
installPromise = installPromise.then(() => {
// Need to install Rush
console.log(`Rush version ${version} is not currently installed. Installing...`);
const resourceName: string = `rush-${version}`;
console.log(`Trying to acquire lock for ${resourceName}`);
return LockFile.acquire(expectedRushPath, resourceName).then((lock: LockFile) => {
if (installMarker.isValid()) {
function createSymlinksForDependencies(localPackage: Package): void {
const localModuleFolder: string = path.join(localPackage.folderPath, 'node_modules');
if (!localPackage.symlinkTargetFolderPath) {
// Program bug
throw Error('localPackage.symlinkTargetFolderPath was not assigned');
}
// This is special case for when localPackage.name has the form '@scope/name',
// in which case we need to create the '@scope' folder first.
const parentFolderPath: string = path.dirname(localPackage.folderPath);
if (parentFolderPath && parentFolderPath !== localPackage.folderPath) {
if (!fsx.existsSync(parentFolderPath)) {
Utilities.createFolderWithRetry(parentFolderPath);
}
}
if (localPackage.children.length === 0) {
// If there are no children, then we can symlink the entire folder
createSymlink(localPackage.symlinkTargetFolderPath, localPackage.folderPath, SymlinkKind.Directory);
} else {
// If there are children, then we need to symlink each item in the folder individually
Utilities.createFolderWithRetry(localPackage.folderPath);
for (const filename of fsx.readdirSync(localPackage.symlinkTargetFolderPath)) {
if (filename.toLowerCase() !== 'node_modules') {
// Create the symlink
let symlinkKind: SymlinkKind = SymlinkKind.File;
const linkSource: string = path.join(localPackage.folderPath, filename);