Skip to content

Commit

Permalink
feat(tools): enable multiple package migration via --name option (mic…
Browse files Browse the repository at this point in the history
…rosoft#20583)

* feat(tools): enable multiple package migration via --name option

* Update tools/generators/migrate-converged-pkg/index.ts

Co-authored-by: Elizabeth Craig <[email protected]>

* Update tools/generators/migrate-converged-pkg/schema.ts

Co-authored-by: Peter Varholak <[email protected]>

* feat(tools): create overriden getProjects function that enables filtering

Co-authored-by: Elizabeth Craig <[email protected]>
Co-authored-by: Peter Varholak <[email protected]>
  • Loading branch information
3 people authored and Marion Le Pontois committed Jan 17, 2022
1 parent 1ec635c commit 1558bf5
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 20 deletions.
14 changes: 12 additions & 2 deletions tools/generators/migrate-converged-pkg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ Workspace Generator for migrating converged packages to new DX (stage 1)[https:/

<!-- tocstop -->

## NOTES

## Usage

```sh
Expand Down Expand Up @@ -60,6 +58,18 @@ Package/library name (needs to be full name of the package, scope included - e.g

> NOTE: will trigger CLI prompt if you didn't provide this option
**Run migration on subset of packages:**

To run migration on multiple packages you can specify a comma separated list of project names.

```sh
# run migration on:
# - @fluentui/lib-zero
# - @fluentui/lib-one
# - @fluentui/lib-two
yarn nx workspace-generator migrate-converged-pkg --name='@fluentui/lib-zero,@fluentui/lib-one,@fluentui/lib-two'
```

#### `all`

Type: `boolean`
Expand Down
23 changes: 23 additions & 0 deletions tools/generators/migrate-converged-pkg/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,29 @@ describe('migrate-converged-pkg generator', () => {
expect(configs['@proj/react-old'].sourceRoot).not.toBeDefined();
});
});

describe(`--name`, () => {
it(`should accept comma separated string to exec on multiple projects`, async () => {
const projects = [options.name, '@proj/react-one', '@proj/react-two', '@proj/react-old'] as const;

setupDummyPackage(tree, { name: projects[1], version: '9.0.22' });
setupDummyPackage(tree, { name: projects[2], version: '9.0.31' });
setupDummyPackage(tree, { name: projects[3], version: '8.0.1' });

await generator(tree, { name: `${projects[0]},${projects[1]}` });

const configs = projects.reduce((acc, projectName) => {
acc[projectName] = readProjectConfiguration(tree, projectName);

return acc;
}, {} as Record<typeof projects[number], ReadProjectConfiguration>);

expect(configs[projects[0]].sourceRoot).toBeDefined();
expect(configs[projects[1]].sourceRoot).toBeDefined();
expect(configs[projects[2]].sourceRoot).not.toBeDefined();
expect(configs[projects[3]].sourceRoot).not.toBeDefined();
});
});
});

// ==== helpers ====
Expand Down
45 changes: 31 additions & 14 deletions tools/generators/migrate-converged-pkg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
readWorkspaceConfiguration,
joinPathFragments,
readJson,
getProjects,
stripIndents,
visitNotIgnoredFiles,
logger,
Expand All @@ -18,7 +17,15 @@ import * as path from 'path';
import * as os from 'os';

import { PackageJson, TsConfig } from '../../types';
import { arePromptsEnabled, getProjectConfig, printUserLogs, prompt, updateJestConfig, UserLog } from '../../utils';
import {
arePromptsEnabled,
getProjectConfig,
getProjects,
printUserLogs,
prompt,
updateJestConfig,
UserLog,
} from '../../utils';

import { MigrateConvergedPkgGeneratorSchema } from './schema';

Expand Down Expand Up @@ -46,7 +53,13 @@ export default async function (tree: Tree, schema: MigrateConvergedPkgGeneratorS
}

if (hasSchemaFlag(validatedSchema, 'name')) {
runMigrationOnProject(tree, validatedSchema, userLog);
const projectNames = validatedSchema.name.split(',').filter(Boolean);

if (projectNames.length > 1) {
runBatchMigration(tree, userLog, projectNames);
} else {
runMigrationOnProject(tree, validatedSchema, userLog);
}
}

await formatFiles(tree);
Expand All @@ -56,11 +69,11 @@ export default async function (tree: Tree, schema: MigrateConvergedPkgGeneratorS
};
}

function runBatchMigration(tree: Tree, userLog: UserLog) {
const projects = getProjects(tree);
function runBatchMigration(tree: Tree, userLog: UserLog, projectNames?: string[]) {
const projects = getProjects(tree, projectNames);

projects.forEach((project, projectName) => {
if (!isPackageConverged(tree, project)) {
projects.forEach((projectConfig, projectName) => {
if (!isPackageConverged(tree, projectConfig)) {
userLog.push({ type: 'error', message: `${projectName} is not converged package. Skipping migration...` });
return;
}
Expand Down Expand Up @@ -365,13 +378,17 @@ async function validateSchema(tree: Tree, schema: MigrateConvergedPkgGeneratorSc
}

if (newSchema.name) {
const projectConfig = readProjectConfiguration(tree, newSchema.name);
const projectNames = newSchema.name.split(',').filter(Boolean);

if (!isPackageConverged(tree, projectConfig)) {
throw new Error(
`${newSchema.name} is not converged package. Make sure to run the migration on packages with version 9.x.x`,
);
}
projectNames.forEach(projectName => {
const projectConfig = readProjectConfiguration(tree, projectName);

if (!isPackageConverged(tree, projectConfig)) {
throw new Error(
`${newSchema.name} is not converged package. Make sure to run the migration on packages with version 9.x.x`,
);
}
});
}

return newSchema;
Expand All @@ -382,7 +399,7 @@ async function triggerDynamicPrompts() {

return prompt<PromptResponse>([
{
message: 'Which converged package would you like migrate to new DX? (ex: @fluentui/react-menu)',
message: 'Which converged package(s) would you like migrate to new DX? (ex: @fluentui/react-menu)',
type: 'input',
name: 'name',
},
Expand Down
2 changes: 1 addition & 1 deletion tools/generators/migrate-converged-pkg/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"properties": {
"name": {
"type": "string",
"description": "Package name",
"description": "Library name or comma delimited library names to execute migration on multiple libraries.",
"$default": {
"$source": "argv",
"index": 0
Expand Down
2 changes: 1 addition & 1 deletion tools/generators/migrate-converged-pkg/schema.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export interface MigrateConvergedPkgGeneratorSchema {
/**
* Library name
* Library name or comma delimited library names to execute migration on multiple libraries.
*/
name?: string;
/**
Expand Down
3 changes: 2 additions & 1 deletion tools/tsconfig.tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"module": "commonjs",
"target": "es5",
"types": ["node"],
"importHelpers": false
"importHelpers": false,
"downlevelIteration": true
},
"exclude": ["**/*.spec.ts"],
"include": ["**/*.ts"]
Expand Down
34 changes: 33 additions & 1 deletion tools/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import * as yargsParser from 'yargs-parser';
import type * as Enquirer from 'enquirer';
import { joinPathFragments, logger, readProjectConfiguration, readWorkspaceConfiguration, Tree } from '@nrwl/devkit';
import {
joinPathFragments,
logger,
readProjectConfiguration,
readWorkspaceConfiguration,
Tree,
getProjects as getAllProjects,
} from '@nrwl/devkit';

/**
* CLI prompts abstraction to trigger dynamic prompts within a generator
Expand Down Expand Up @@ -119,3 +126,28 @@ export function printUserLogs(logs: UserLog) {

logger.log(`${'='.repeat(80)}\n`);
}

/**
* Overridden `@nrwl/devkit#getProjects` function
* Get all workspace projects or only subset, if projectNames array is specified
*
* @param tree
* @param projectNames - array of project names. Use this to return only subset of projects
*/
export function getProjects(tree: Tree, projectNames?: string[]) {
const allProjects = getAllProjects(tree);

if (Array.isArray(projectNames) && projectNames.length > 0) {
const pickedProjects: ReturnType<typeof getAllProjects> = new Map();

for (const [projectName, projectConfig] of allProjects.entries()) {
if (projectNames.includes(projectName)) {
pickedProjects.set(projectName, projectConfig);
}
}

return pickedProjects;
}

return allProjects;
}

0 comments on commit 1558bf5

Please sign in to comment.