Skip to content

Commit

Permalink
chore: improve mr after review
Browse files Browse the repository at this point in the history
  • Loading branch information
pedro-gomes-92 committed Dec 20, 2024
1 parent 2ce2242 commit 38d22be
Show file tree
Hide file tree
Showing 16 changed files with 253 additions and 221 deletions.
132 changes: 71 additions & 61 deletions rush-plugins/rush-migrate-subspace-plugin/src/cleanSubspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { getRushSubspacesConfigurationJsonPath, querySubspaces } from './utiliti
import { RushConstants } from '@rushstack/rush-sdk';
import { chooseDependencyPrompt, confirmNextDependencyPrompt } from './prompts/dependency';
import { IPackageJson, JsonFile } from '@rushstack/node-core-library';
import { rSortVersions, subsetVersion } from './utilities/dependency';
import { reverseSortVersions, subsetVersion } from './utilities/dependency';
import {
getProjectPackageFilePath,
loadProjectPackageJson,
Expand All @@ -28,46 +28,49 @@ import {
import { IRushConfigurationProjectJson } from '@rushstack/rush-sdk/lib/api/RushConfigurationProject';
import { RESERVED_VERSIONS } from './constants/versions';

const removeSupersetDependency = async (
const removeSupersetDependency = (
subspaceName: string,
dependencyName: string,
versionsMap: Map<string, string[]>,
rootPath: string = getRootPath()
): Promise<number> => {
rootPath: string
): number => {
const versions: string[] = Array.from(versionsMap.keys());
const subspaceCommonVersionsPath: string = getRushSubspaceCommonVersionsFilePath(subspaceName, rootPath);
const subspaceCommonVersionsJson: RushSubspaceCommonVersionsJson = loadRushSubspaceCommonVersions(
subspaceName,
rootPath
);

const newValidVersions: string[] = rSortVersions(versions).reduce<string[]>((prevVersions, currVersion) => {
const newVersions: string[] = [...prevVersions];
if (newVersions.includes(currVersion)) {
return newVersions;
}
const newValidVersions: string[] = reverseSortVersions(versions).reduce<string[]>(
(prevVersions, currVersion) => {
const newVersions: string[] = [...prevVersions];
if (newVersions.includes(currVersion)) {
return newVersions;
}

const newSubsetVersion: string | undefined = newVersions.find((newVersion) =>
subsetVersion(newVersion, currVersion)
);
const newSubsetVersion: string | undefined = newVersions.find((newVersion) =>
subsetVersion(newVersion, currVersion)
);

if (RESERVED_VERSIONS.includes(currVersion) || !newSubsetVersion) {
newVersions.push(currVersion);
} else {
// Update projects with new subset version
versionsMap.get(currVersion)?.forEach((projectName) => {
if (updateProjectDependency(projectName, dependencyName, newSubsetVersion, rootPath)) {
Console.debug(
`Updated project ${Colorize.bold(projectName)} for dependency ${Colorize.bold(
dependencyName
)} ${Colorize.bold(currVersion)} => ${Colorize.bold(newSubsetVersion)}!`
);
if (RESERVED_VERSIONS.includes(currVersion) || !newSubsetVersion) {
newVersions.push(currVersion);
} else {
// Update projects with new subset version
for (const projectName of versionsMap.get(currVersion) || []) {
if (updateProjectDependency(projectName, dependencyName, newSubsetVersion, rootPath)) {
Console.debug(
`Updated project ${Colorize.bold(projectName)} for dependency ${Colorize.bold(
dependencyName
)} ${Colorize.bold(currVersion)} => ${Colorize.bold(newSubsetVersion)}!`
);
}
}
});
}
}

return newVersions;
}, []);
return newVersions;
},
[]
);

const removedAlternativeVersionsCount: number = versions.length - newValidVersions.length;
if (removedAlternativeVersionsCount > 0) {
Expand All @@ -84,30 +87,31 @@ const removeSupersetDependency = async (
return removedAlternativeVersionsCount;
};

const removeDuplicatedDependencies = (subspaceName: string, rootPath: string = getRootPath()): void => {
const removeDuplicatedDependencies = (subspaceName: string, rootPath: string): void => {
Console.log(`Removing duplicated dependencies for subspace ${Colorize.bold(subspaceName)}...`);

const projects: IRushConfigurationProjectJson[] = queryProjectsFromSubspace(subspaceName, rootPath);
let countRemoved: number = 0;
projects.forEach((project) => {

for (const project of projects) {
const projectPackageFilePath: string = getProjectPackageFilePath(project.projectFolder, rootPath);
const projectPackageJson: IPackageJson = loadProjectPackageJson(project.projectFolder, rootPath);

const dependencies: string[] = Object.keys(projectPackageJson.dependencies || {});
const devDependencies: string[] = Object.keys(projectPackageJson.devDependencies || {});

devDependencies.forEach((devDependency) => {
for (const devDependency of devDependencies) {
if (dependencies.includes(devDependency)) {
countRemoved += 1;
Console.debug(
`Removed ${Colorize.bold(devDependency)} from project ${Colorize.bold(project.packageName)}`
);
delete projectPackageJson.devDependencies![devDependency];
}
});
}

JsonFile.save(projectPackageJson, projectPackageFilePath);
});
}

if (countRemoved > 0) {
Console.success(
Expand All @@ -122,13 +126,16 @@ const removeDuplicatedDependencies = (subspaceName: string, rootPath: string = g

const removeUnusedAlternativeVersions = (
subspaceName: string,
subspaceDependencies: Map<string, Map<string, string[]>>
subspaceDependencies: Map<string, Map<string, string[]>>,
rootPath: string
): void => {
Console.log(`Removing unused alternative versions for subspace ${Colorize.bold(subspaceName)}...`);

const subspaceCommonVersionsPath: string = getRushSubspaceCommonVersionsFilePath(subspaceName);
const subspaceCommonVersionsJson: RushSubspaceCommonVersionsJson =
loadRushSubspaceCommonVersions(subspaceName);
const subspaceCommonVersionsPath: string = getRushSubspaceCommonVersionsFilePath(subspaceName, rootPath);
const subspaceCommonVersionsJson: RushSubspaceCommonVersionsJson = loadRushSubspaceCommonVersions(
subspaceName,
rootPath
);

if (!subspaceCommonVersionsJson.allowedAlternativeVersions) {
return;
Expand Down Expand Up @@ -181,7 +188,8 @@ const removeUnusedAlternativeVersions = (

const removeSupersetDependencyVersions = async (
subspaceName: string,
subspaceDependencies: Map<string, Map<string, string[]>>
subspaceDependencies: Map<string, Map<string, string[]>>,
rootPath: string
): Promise<void> => {
const multipleVersionDependencies: string[] = Array.from(subspaceDependencies.keys()).filter(
(dependency) => subspaceDependencies.get(dependency)!.size > 1
Expand All @@ -196,18 +204,16 @@ const removeSupersetDependencyVersions = async (

if (await scanForAllDependenciesPrompt()) {
Console.log(`Removing superset versions for subspace ${Colorize.bold(subspaceName)}...`);
await Promise.all(
Array.from(subspaceDependencies.entries()).map(([dependency, versionsMap]) =>
removeSupersetDependency(subspaceName, dependency, versionsMap)
)
).then((countPerDependency) => {
const count: number = countPerDependency.reduce((a, b) => a + b, 0);
if (count > 0) {
Console.success(`Removed ${Colorize.bold(`${count}`)} superset alternative versions!`);
} else {
Console.success(`No alternative versions have been removed!`);
}
});
const countPerDependency: number[] = Array.from(subspaceDependencies.entries()).map(
([dependency, versionsMap]) => removeSupersetDependency(subspaceName, dependency, versionsMap, rootPath)
);

const count: number = countPerDependency.reduce((a, b) => a + b, 0);
if (count > 0) {
Console.success(`Removed ${Colorize.bold(`${count}`)} superset alternative versions!`);
} else {
Console.success(`No alternative versions have been removed!`);
}

return;
}
Expand All @@ -219,7 +225,8 @@ const removeSupersetDependencyVersions = async (
const count: number = await removeSupersetDependency(
subspaceName,
selectedDependency,
subspaceDependencies.get(selectedDependency) as Map<string, string[]>
subspaceDependencies.get(selectedDependency) as Map<string, string[]>,
rootPath
);

if (count > 0) {
Expand All @@ -239,16 +246,16 @@ const removeSupersetDependencyVersions = async (
} while (multipleVersionDependencies.length > 0 && (await confirmNextDependencyPrompt()));
};

export const cleanSubspace = async (): Promise<void> => {
export const cleanSubspace = async (targetMonorepoPath: string = getRootPath()): Promise<void> => {
Console.debug('Executing clean subspace command...');

const targetSubspaces: string[] = querySubspaces();
if (!isSubspaceSupported()) {
const targetSubspaces: string[] = querySubspaces(targetMonorepoPath);
if (!isSubspaceSupported(targetMonorepoPath)) {
Console.error(
`The monorepo ${Colorize.bold(
getRootPath()
targetMonorepoPath
)} doesn't support subspaces! Make sure you have ${Colorize.bold(
getRushSubspacesConfigurationJsonPath()
getRushSubspacesConfigurationJsonPath(targetMonorepoPath)
)} with the ${Colorize.bold(RushConstants.defaultSubspaceName)} subspace. Exiting...`
);
return;
Expand All @@ -257,19 +264,22 @@ export const cleanSubspace = async (): Promise<void> => {
const targetSubspace: string = await chooseSubspacePrompt(targetSubspaces);
Console.title(`🛁 Cleaning subspace ${Colorize.underline(targetSubspace)} alternative versions...`);

let subspaceDependencies: Map<string, Map<string, string[]>> = getSubspaceDependencies(targetSubspace);
let subspaceDependencies: Map<string, Map<string, string[]>> = getSubspaceDependencies(
targetSubspace,
targetMonorepoPath
);
if (await scanForDuplicatedDependenciesPrompt()) {
removeDuplicatedDependencies(targetSubspace);
subspaceDependencies = getSubspaceDependencies(targetSubspace);
removeDuplicatedDependencies(targetSubspace, targetMonorepoPath);
subspaceDependencies = getSubspaceDependencies(targetSubspace, targetMonorepoPath);
}

if (await scanForSupersetDependencyVersionsPrompt()) {
await removeSupersetDependencyVersions(targetSubspace, subspaceDependencies);
subspaceDependencies = getSubspaceDependencies(targetSubspace);
await removeSupersetDependencyVersions(targetSubspace, subspaceDependencies, targetMonorepoPath);
subspaceDependencies = getSubspaceDependencies(targetSubspace, targetMonorepoPath);
}

if (await scanForUnusedDependencyVersionsPrompt()) {
removeUnusedAlternativeVersions(targetSubspace, subspaceDependencies);
removeUnusedAlternativeVersions(targetSubspace, subspaceDependencies, targetMonorepoPath);
}

Console.warn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import Console from '../providers/console';
import { Colorize } from '@rushstack/terminal';
import { IRushConfigurationProjectJson } from '@rushstack/rush-sdk/lib/api/RushConfigurationProject';
import { enterNewProjectLocationPrompt, moveProjectPrompt } from '../prompts/project';
import { getRootPath } from '../utilities/path';
import { RushConstants } from '@rushstack/rush-sdk';
import { addProjectToRushConfiguration } from './updateRushConfiguration';
import {
Expand All @@ -20,7 +19,7 @@ import path from 'path';
const refreshSubspace = (subspaceName: string, rootPath: string): void => {
const subspacesConfig: ISubspacesConfigurationJson = loadRushSubspacesConfiguration(rootPath);
const newSubspaces: string[] = [...subspacesConfig.subspaceNames];
if (queryProjectsFromSubspace(subspaceName).length === 0) {
if (queryProjectsFromSubspace(subspaceName, rootPath).length === 0) {
newSubspaces.splice(newSubspaces.indexOf(subspaceName), 1);
}

Expand All @@ -31,11 +30,10 @@ const refreshSubspace = (subspaceName: string, rootPath: string): void => {

const moveProjectToSubspaceFolder = async (
sourceProjectFolderPath: string,
targetSubspace: string
targetSubspace: string,
rootPath: string
): Promise<string | undefined> => {
const targetSubspaceFolderPath: string = `${getRootPath()}/${
RushNameConstants.SubspacesFolderName
}/${targetSubspace}`;
const targetSubspaceFolderPath: string = `${rootPath}/${RushNameConstants.SubspacesFolderName}/${targetSubspace}`;

const targetProjectFolderPath: string = await enterNewProjectLocationPrompt(
sourceProjectFolderPath,
Expand Down Expand Up @@ -71,24 +69,33 @@ const moveProjectToSubspaceFolder = async (
export const addProjectToSubspace = async (
sourceProject: IRushConfigurationProjectJson,
targetSubspace: string,
sourceMonorepoPath: string
sourceMonorepoPath: string,
targetMonorepoPath: string
): Promise<void> => {
Console.debug(
`Adding project ${Colorize.bold(sourceProject.packageName)} to subspace ${Colorize.bold(
targetSubspace
)}...`
);

let targetProjectFolderPath: string | undefined = `${getRootPath()}/${sourceProject.projectFolder}`;
if (isExternalMonorepo(sourceMonorepoPath) || (await moveProjectPrompt())) {
let targetProjectFolderPath: string | undefined = `${targetMonorepoPath}/${sourceProject.projectFolder}`;
if (isExternalMonorepo(sourceMonorepoPath, targetMonorepoPath) || (await moveProjectPrompt())) {
const sourceProjectFolderPath: string = `${sourceMonorepoPath}/${sourceProject.projectFolder}`;
targetProjectFolderPath = await moveProjectToSubspaceFolder(sourceProjectFolderPath, targetSubspace);
targetProjectFolderPath = await moveProjectToSubspaceFolder(
sourceProjectFolderPath,
targetSubspace,
targetMonorepoPath
);
if (!targetProjectFolderPath) {
return;
}

if (FileSystem.exists(`${getRootPath()}/${RushNameConstants.EdenMonorepoFileName}`)) {
await updateEdenProject(sourceProject, path.relative(sourceMonorepoPath, targetProjectFolderPath));
if (FileSystem.exists(`${targetMonorepoPath}/${RushNameConstants.EdenMonorepoFileName}`)) {
await updateEdenProject(
sourceProject,
path.relative(sourceMonorepoPath, targetProjectFolderPath),
targetMonorepoPath
);
}
}

Expand All @@ -103,7 +110,7 @@ export const addProjectToSubspace = async (
FileSystem.deleteFolder(targetLegacySubspaceFolderPath);
}

addProjectToRushConfiguration(sourceProject, targetSubspace, targetProjectFolderPath);
addProjectToRushConfiguration(sourceProject, targetSubspace, targetProjectFolderPath, targetMonorepoPath);
if (sourceProject.subspaceName) {
refreshSubspace(sourceProject.subspaceName, sourceMonorepoPath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
import { ISubspacesConfigurationJson } from '@rushstack/rush-sdk/lib/api/SubspacesConfiguration';
import { getRushSubspaceConfigurationFolderPath } from '../utilities/subspace';

export const createSubspace = async (subspaceName: string): Promise<void> => {
export const createSubspace = async (subspaceName: string, rootPath: string): Promise<void> => {
Console.debug(`Creating subspace ${Colorize.bold(subspaceName)}...`);
const subspaceConfigFolder: string = getRushSubspaceConfigurationFolderPath(subspaceName);
const subspaceConfigFolder: string = getRushSubspaceConfigurationFolderPath(subspaceName, rootPath);
FileSystem.ensureFolder(subspaceConfigFolder);

const files: string[] = ['.npmrc', 'common-versions.json', 'repo-state.json'];
Expand All @@ -23,17 +23,19 @@ export const createSubspace = async (subspaceName: string): Promise<void> => {
}
}

const subspacesConfigJson: ISubspacesConfigurationJson = loadRushSubspacesConfiguration();
const subspacesConfigJson: ISubspacesConfigurationJson = loadRushSubspacesConfiguration(rootPath);
if (!subspacesConfigJson.subspaceNames.includes(subspaceName)) {
Console.debug(
`Updating ${getRushSubspacesConfigurationJsonPath()} by adding ${Colorize.bold(subspaceName)}...`
`Updating ${getRushSubspacesConfigurationJsonPath(rootPath)} by adding ${Colorize.bold(
subspaceName
)}...`
);
const newSubspacesConfigJson: ISubspacesConfigurationJson = {
...subspacesConfigJson,
subspaceNames: [...subspacesConfigJson.subspaceNames, subspaceName]
};

JsonFile.save(newSubspacesConfigJson, getRushSubspacesConfigurationJsonPath(), {
JsonFile.save(newSubspacesConfigJson, getRushSubspacesConfigurationJsonPath(rootPath), {
updateExistingFile: true
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ import { Colorize } from '@rushstack/terminal';
import { RushNameConstants } from '../constants/paths';
import { getProjectMismatches } from '../utilities/project';
import { VersionMismatchFinderEntity } from '@rushstack/rush-sdk/lib/logic/versionMismatch/VersionMismatchFinderEntity';
import { getRootPath } from '../utilities/path';
import { sortVersions } from '../utilities/dependency';

export const generateReport = async (projectName: string): Promise<void> => {
export const generateReport = async (projectName: string, rootPath: string): Promise<void> => {
Console.debug(`Generating mismatches report for the project ${Colorize.bold(projectName)}...`);

const projectMismatches: ReadonlyMap<
string,
ReadonlyMap<string, readonly VersionMismatchFinderEntity[]>
> = getProjectMismatches(projectName);
> = getProjectMismatches(projectName, rootPath);
if (projectMismatches.size === 0) {
Console.success(`No mismatches found for the project ${Colorize.bold(projectName)}.`);
return;
Expand All @@ -39,7 +38,7 @@ export const generateReport = async (projectName: string): Promise<void> => {
}
}

const reportFilePath: string = `${getRootPath()}/${projectName}_${RushNameConstants.AnalysisFileName}`;
const reportFilePath: string = `${rootPath}/${projectName}_${RushNameConstants.AnalysisFileName}`;
const jsonFilePath: string = await enterReportFileLocationPrompt(reportFilePath);
JsonFile.save(output, jsonFilePath, { prettyFormatting: true });
Console.success(`Saved report file to ${Colorize.bold(jsonFilePath)}.`);
Expand Down
Loading

0 comments on commit 38d22be

Please sign in to comment.