Skip to content

Commit 9ca2244

Browse files
authored
Merge pull request microsoft#1356 from iclanton/ianc/fix-rush-add
[rush] Fix an issue where "rush add" erroneously believes ensureConsistentVersions is unset.
2 parents e91c474 + 5c949c2 commit 9ca2244

3 files changed

Lines changed: 161 additions & 125 deletions

File tree

apps/rush-lib/src/logic/PackageJsonUpdater.ts

Lines changed: 139 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -118,72 +118,12 @@ export class PackageJsonUpdater {
118118
variant
119119
} = options;
120120

121-
const implicitlyPinned: Map<string, string>
122-
= InstallManager.collectImplicitlyPreferredVersions(this._rushConfiguration, {
121+
const implicitlyPinned: Map<string, string> = InstallManager.collectImplicitlyPreferredVersions(
122+
this._rushConfiguration,
123+
{
123124
variant
124-
});
125-
126-
const version: string = this._getNormalizedVersionSpec(
127-
packageName, initialVersion, implicitlyPinned.get(packageName), rangeStyle);
128-
129-
console.log();
130-
console.log(colors.green(`Updating projects to use `)
131-
+ packageName + '@' + colors.cyan(version));
132-
console.log();
133-
134-
const currentProjectUpdate: IUpdateProjectOptions = {
135-
project: currentProject,
136-
packageName,
137-
newVersion: version,
138-
dependencyType: devDependency ? DependencyType.Dev : undefined
139-
};
140-
this.updateProject(currentProjectUpdate);
141-
142-
const otherPackageUpdates: Array<IUpdateProjectOptions> = [];
143-
144-
if (this._rushConfiguration.ensureConsistentVersions || updateOtherPackages) {
145-
// we need to do a mismatch check
146-
const mismatchFinder: VersionMismatchFinder = VersionMismatchFinder.getMismatches(this._rushConfiguration, {
147-
variant: variant
148-
});
149-
150-
const mismatches: Array<string> = mismatchFinder.getMismatches();
151-
if (mismatches.length) {
152-
if (!updateOtherPackages) {
153-
return Promise.reject(new Error(`Adding '${packageName}@${version}' to ${currentProject.packageName}`
154-
+ ` causes mismatched dependencies. Use the "--make-consistent" flag to update other packages to use this`
155-
+ ` version, or do not specify a SemVer range.`));
156-
}
157-
158-
// otherwise we need to go update a bunch of other projects
159-
const mismatchedVersions: Array<string> | undefined = mismatchFinder.getVersionsOfMismatch(packageName);
160-
if (mismatchedVersions) {
161-
for (const mismatchedVersion of mismatchedVersions) {
162-
for (const consumer of mismatchFinder.getConsumersOfMismatch(packageName, mismatchedVersion)!) {
163-
if (consumer !== currentProject.packageName) {
164-
otherPackageUpdates.push({
165-
project: this._rushConfiguration.getProjectByName(consumer)!,
166-
packageName: packageName,
167-
newVersion: version
168-
});
169-
}
170-
}
171-
}
172-
}
173-
}
174-
}
175-
176-
this.updateProjects(otherPackageUpdates);
177-
178-
for (const project of this._rushConfiguration.projects) {
179-
if (project.packageJsonEditor.saveIfModified()) {
180-
console.log(colors.green('Wrote ') + project.packageJsonEditor.filePath);
181125
}
182-
}
183-
184-
if (skipUpdate) {
185-
return Promise.resolve();
186-
}
126+
);
187127

188128
const purgeManager: PurgeManager = new PurgeManager(this._rushConfiguration, this._rushGlobalFolder);
189129
const installManagerOptions: IInstallManagerOptions = {
@@ -204,16 +144,82 @@ export class PackageJsonUpdater {
204144
installManagerOptions
205145
);
206146

207-
console.log();
208-
console.log(colors.green('Running "rush update"'));
209-
console.log();
210-
return installManager.doInstall()
211-
.then(() => {
212-
purgeManager.deleteAll();
213-
})
214-
.catch((error) => {
215-
purgeManager.deleteAll();
216-
throw error;
147+
return this._getNormalizedVersionSpec(
148+
installManager,
149+
packageName,
150+
initialVersion,
151+
implicitlyPinned.get(packageName),
152+
rangeStyle
153+
).then((version) => {
154+
console.log();
155+
console.log(colors.green(`Updating projects to use `) + packageName + '@' + colors.cyan(version));
156+
console.log();
157+
158+
const currentProjectUpdate: IUpdateProjectOptions = {
159+
project: currentProject,
160+
packageName,
161+
newVersion: version,
162+
dependencyType: devDependency ? DependencyType.Dev : undefined
163+
};
164+
this.updateProject(currentProjectUpdate);
165+
166+
const otherPackageUpdates: Array<IUpdateProjectOptions> = [];
167+
168+
if (this._rushConfiguration.ensureConsistentVersions || updateOtherPackages) {
169+
// we need to do a mismatch check
170+
const mismatchFinder: VersionMismatchFinder = VersionMismatchFinder.getMismatches(this._rushConfiguration, {
171+
variant: variant
172+
});
173+
174+
const mismatches: Array<string> = mismatchFinder.getMismatches();
175+
if (mismatches.length) {
176+
if (!updateOtherPackages) {
177+
return Promise.reject(new Error(`Adding '${packageName}@${version}' to ${currentProject.packageName}`
178+
+ ` causes mismatched dependencies. Use the "--make-consistent" flag to update other packages to use this`
179+
+ ` version, or do not specify a SemVer range.`));
180+
}
181+
182+
// otherwise we need to go update a bunch of other projects
183+
const mismatchedVersions: Array<string> | undefined = mismatchFinder.getVersionsOfMismatch(packageName);
184+
if (mismatchedVersions) {
185+
for (const mismatchedVersion of mismatchedVersions) {
186+
for (const consumer of mismatchFinder.getConsumersOfMismatch(packageName, mismatchedVersion)!) {
187+
if (consumer !== currentProject.packageName) {
188+
otherPackageUpdates.push({
189+
project: this._rushConfiguration.getProjectByName(consumer)!,
190+
packageName: packageName,
191+
newVersion: version
192+
});
193+
}
194+
}
195+
}
196+
}
197+
}
198+
}
199+
200+
this.updateProjects(otherPackageUpdates);
201+
202+
for (const project of this._rushConfiguration.projects) {
203+
if (project.packageJsonEditor.saveIfModified()) {
204+
console.log(colors.green('Wrote ') + project.packageJsonEditor.filePath);
205+
}
206+
}
207+
208+
if (skipUpdate) {
209+
return Promise.resolve();
210+
}
211+
212+
console.log();
213+
console.log(colors.green('Running "rush update"'));
214+
console.log();
215+
return installManager.doInstall()
216+
.then(() => {
217+
purgeManager.deleteAll();
218+
})
219+
.catch((error) => {
220+
purgeManager.deleteAll();
221+
throw error;
222+
});
217223
});
218224
}
219225

@@ -261,10 +267,12 @@ export class PackageJsonUpdater {
261267
* the selected version.
262268
*/
263269
private _getNormalizedVersionSpec(
270+
installManager: InstallManager,
264271
packageName: string,
265272
initialSpec: string | undefined,
266273
implicitlyPinnedVersion: string | undefined,
267-
rangeStyle: SemVerStyle): string {
274+
rangeStyle: SemVerStyle
275+
): Promise<string> {
268276

269277
console.log(colors.gray(`Determining new version for dependency: ${packageName}`));
270278
if (initialSpec) {
@@ -280,76 +288,82 @@ export class PackageJsonUpdater {
280288
console.log(colors.green('Assigning "')
281289
+ colors.cyan(initialSpec)
282290
+ colors.green(`" for "${packageName}" because it matches what other projects are using in this repo.`));
283-
return initialSpec;
291+
return Promise.resolve(initialSpec);
284292
}
285293

286294
if (this._rushConfiguration.ensureConsistentVersions && !initialSpec && implicitlyPinnedVersion) {
287295
console.log(`Assigning the version range "${colors.cyan(implicitlyPinnedVersion)}" for "${packageName}" because`
288296
+ ` it is already used by other projects in this repo.`);
289-
return implicitlyPinnedVersion;
297+
return Promise.resolve(implicitlyPinnedVersion);
290298
}
291299

292-
let selectedVersion: string | undefined;
293-
294300
if (this._rushConfiguration.packageManager === 'yarn') {
295301
throw new Error('The Yarn package manager is not currently supported by the "rush add" command.');
296302
}
297303

298-
if (initialSpec && initialSpec !== 'latest') {
299-
console.log(colors.gray('Finding newest version that satisfies the selector: ') + initialSpec);
300-
console.log();
301-
console.log(`Querying registry for all versions of "${packageName}"...`);
304+
return installManager.ensureLocalPackageManager().then(() => {
305+
let selectedVersion: string | undefined;
306+
307+
if (initialSpec && initialSpec !== 'latest') {
308+
console.log(colors.gray('Finding newest version that satisfies the selector: ') + initialSpec);
309+
console.log();
310+
console.log(`Querying registry for all versions of "${packageName}"...`);
302311

303-
const allVersions: string =
304-
Utilities.executeCommandAndCaptureOutput(this._rushConfiguration.packageManagerToolFilename,
305-
['view', packageName, 'versions', '--json'],
306-
this._rushConfiguration.commonTempFolder);
312+
const allVersions: string =
313+
Utilities.executeCommandAndCaptureOutput(this._rushConfiguration.packageManagerToolFilename,
314+
['view', packageName, 'versions', '--json'],
315+
this._rushConfiguration.commonTempFolder);
307316

308-
let versionList: Array<string> = JSON.parse(allVersions);
309-
versionList = versionList.sort((a: string, b: string) => { return semver.gt(a, b) ? -1 : 1; });
317+
let versionList: Array<string> = JSON.parse(allVersions);
318+
versionList = versionList.sort((a: string, b: string) => { return semver.gt(a, b) ? -1 : 1; });
310319

311-
console.log(colors.gray(`Found ${versionList.length} available versions.`));
320+
console.log(colors.gray(`Found ${versionList.length} available versions.`));
312321

313-
for (const version of versionList) {
314-
if (semver.satisfies(version, initialSpec)) {
315-
selectedVersion = version;
316-
console.log(`Found latest version: ${colors.cyan(selectedVersion)}`);
317-
break;
322+
for (const version of versionList) {
323+
if (semver.satisfies(version, initialSpec)) {
324+
selectedVersion = version;
325+
console.log(`Found latest version: ${colors.cyan(selectedVersion)}`);
326+
break;
327+
}
318328
}
319-
}
320-
if (!selectedVersion) {
321-
throw new Error(`Unable to find a version of "${packageName}" that satisfies`
322-
+ ` the version range "${initialSpec}"`);
323-
}
324-
} else {
325-
if (initialSpec !== 'latest') {
326-
console.log(colors.gray(`The "ensureConsistentVersions" policy is NOT active,`
327-
+ ` so we will assign the latest version.`));
329+
330+
if (!selectedVersion) {
331+
throw new Error(`Unable to find a version of "${packageName}" that satisfies`
332+
+ ` the version range "${initialSpec}"`);
333+
}
334+
} else {
335+
if (!this._rushConfiguration.ensureConsistentVersions) {
336+
console.log(colors.gray(`The "ensureConsistentVersions" policy is NOT active,`
337+
+ ` so we will assign the latest version.`));
338+
console.log();
339+
}
340+
console.log(`Querying NPM registry for latest version of "${packageName}"...`);
341+
342+
selectedVersion = Utilities.executeCommandAndCaptureOutput(
343+
this._rushConfiguration.packageManagerToolFilename,
344+
['view', `${packageName}@latest`, 'version'],
345+
this._rushConfiguration.commonTempFolder
346+
).trim();
347+
328348
console.log();
349+
350+
console.log(`Found latest version: ${colors.cyan(selectedVersion)}`);
329351
}
330-
console.log(`Querying NPM registry for latest version of "${packageName}"...`);
331352

332-
selectedVersion = Utilities.executeCommandAndCaptureOutput(this._rushConfiguration.packageManagerToolFilename,
333-
['view', `${packageName}@latest`, 'version'],
334-
this._rushConfiguration.commonTempFolder).trim();
335353
console.log();
336354

337-
console.log(`Found latest version: ${colors.cyan(selectedVersion)}`);
338-
}
339-
340-
console.log();
341-
342-
if (rangeStyle === SemVerStyle.Caret) {
343-
console.log(colors.grey(`Assigning version "^${selectedVersion}" for "${packageName}" because the "--caret"`
344-
+ ` flag was specified.`));
345-
return '^' + selectedVersion;
346-
} else if (rangeStyle === SemVerStyle.Exact) {
347-
console.log(colors.grey(`Assigning version "${selectedVersion}" for "${packageName}" because the "--exact"`
348-
+ ` flag was specified.`));
349-
return selectedVersion;
350-
} else {
351-
console.log(colors.gray(`Assigning version "~${selectedVersion}" for "${packageName}".`));
352-
return '~' + selectedVersion!;
353-
}
355+
if (rangeStyle === SemVerStyle.Caret) {
356+
console.log(colors.grey(`Assigning version "^${selectedVersion}" for "${packageName}" because the "--caret"`
357+
+ ` flag was specified.`));
358+
return '^' + selectedVersion;
359+
} else if (rangeStyle === SemVerStyle.Exact) {
360+
console.log(colors.grey(`Assigning version "${selectedVersion}" for "${packageName}" because the "--exact"`
361+
+ ` flag was specified.`));
362+
return selectedVersion;
363+
} else {
364+
console.log(colors.gray(`Assigning version "~${selectedVersion}" for "${packageName}".`));
365+
return '~' + selectedVersion!;
366+
}
367+
});
354368
}
355369
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"changes": [
3+
{
4+
"comment": "Fix an issue where \"rush add\" erroneously believes ensureConsistentVersions is unset.",
5+
"packageName": "@microsoft/rush",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@microsoft/rush",
10+
"email": "iclanton@users.noreply.github.com"
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"changes": [
3+
{
4+
"comment": "Fix an issue that arises when \"rush add\" is run and the package manager isn't installed.",
5+
"packageName": "@microsoft/rush",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@microsoft/rush",
10+
"email": "iclanton@users.noreply.github.com"
11+
}

0 commit comments

Comments
 (0)