Skip to content

Commit

Permalink
fix(nx-plugin): correct importPath and import updates for migration t…
Browse files Browse the repository at this point in the history
…o local plugin
  • Loading branch information
AgentEnder committed Apr 20, 2023
1 parent bef152d commit 29dc8cb
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/generated/cli/workspace-generator.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ description: 'Runs a workspace generator from the tools/generators directory'
## Usage

```shell
nx workspace-generator [name]
nx workspace-generator [generator]
```

Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpm nx`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ description: 'Runs a workspace generator from the tools/generators directory'
## Usage

```shell
nx workspace-generator [name]
nx workspace-generator [generator]
```

Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpm nx`.
Expand Down
4 changes: 2 additions & 2 deletions packages/nx/src/command-line/nx-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,11 @@ export const commandsObject = yargs
* @deprecated(v17): Remove `workspace-generator in v17. Use local plugins.
*/
.command({
command: 'workspace-generator [name]',
command: 'workspace-generator [generator]',
describe: 'Runs a workspace generator from the tools/generators directory',
deprecated:
'Use a local plugin instead. See: https://nx.dev/deprecated/workspace-generators',
aliases: ['workspace-schematic [name]'],
aliases: ['workspace-schematic [generator]'],
builder: async (yargs) =>
linkToNxDevAndExamples(withGenerateOptions(yargs), 'workspace-generator'),
handler: workspaceGeneratorHandler,
Expand Down
2 changes: 1 addition & 1 deletion packages/nx/src/command-line/workspace-generators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export async function workspaceGenerators(args: yargs.Arguments) {
const generator = process.argv.slice(3);

output.warn({
title: `${NX_PREFIX} Workspace Generators are no longer supported`,
title: `Workspace Generators are no longer supported`,
bodyLines: [
'Instead, Nx now supports executing generators or executors from ',
'local plugins. To run a generator from a local plugin, ',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
import { moveGenerator } from '../../generators/move/move';
import { nxVersion } from '../../utils/versions';
import { PackageJson } from 'nx/src/utils/package-json';
import { posix } from 'path';

const PROJECT_NAME = 'workspace-plugin';
const DESTINATION = `tools/${PROJECT_NAME}`;
Expand Down Expand Up @@ -74,12 +75,71 @@ function collectAndMoveGenerators(tree: Tree, destinationProjectRoot: string) {
schema: `./src/generators/${joinPathFragments(c, 'schema.json')}`,
description: schema.description ?? `Generator ${c}`,
};
tree.rename(childDir, joinPathFragments(destinationDir, c));
moveFilesInDirectory(
tree,
childDir,
joinPathFragments(destinationDir, c)
);
}
}
return generators;
}

function moveFilesInDirectory(tree: Tree, source: string, destination: string) {
const relative = posix.relative(source, posix.dirname(destination));
if (!relative.startsWith('../')) {
// If the destination is in the same directory or a subdirectory of the source
// we can just move the files. If it is not, we need to update the relative imports.
return;
}
let offsetLevel = 0;
const pathParts = relative.split('/');
for (const part of pathParts) {
if (part === '..') {
offsetLevel++;
} else {
break;
}
}
for (const c of tree.children(source)) {
if (!tree.isFile(c)) {
moveFilesInDirectory(
tree,
joinPathFragments(source, c),
joinPathFragments(destination, c)
);
}
tree.rename(
joinPathFragments(source, c),
joinPathFragments(destination, c)
);
// If its a TS file we can update relative imports with find + replace
// This could be done with AST, but since we are only looking at relative
// imports its easy to do via string replace. We replace any strings starting
// with a relative path outside of their own directory.
if (c.endsWith('.ts')) {
let content = tree.read(joinPathFragments(destination, c)).toString();
// +2 is a bit of a magic number here - represents extra directory levels in a normal
// plugin structure compared to the workspace-generator layout
const extraDirectoriesInPluginStructure = 2;
content = content.replace(
new RegExp(`'` + `\.\.\/`.repeat(offsetLevel), 'g'),
"'" + '../'.repeat(offsetLevel + extraDirectoriesInPluginStructure)
);
content = content.replace(
new RegExp(`"` + `\.\.\/`.repeat(offsetLevel), 'g'),
'"' + '../'.repeat(offsetLevel + extraDirectoriesInPluginStructure)
);
// We write it back in the same spot, since it is moved as if it was a regular file after this
tree.write(joinPathFragments(source, c), content);
}
tree.rename(
joinPathFragments(source, c),
joinPathFragments(destination, c)
);
}
}

async function createNewPlugin(tree: Tree) {
ensurePackage('@nx/nx-plugin', nxVersion);
const { pluginGenerator } =
Expand All @@ -90,7 +150,7 @@ async function createNewPlugin(tree: Tree) {
const { Linter } = ensurePackage('@nx/linter', nxVersion);

const { npmScope } = getWorkspaceLayout(tree);
const importPath = npmScope ? `${npmScope}/${PROJECT_NAME}` : PROJECT_NAME;
const importPath = npmScope ? `@${npmScope}/${PROJECT_NAME}` : PROJECT_NAME;

await pluginGenerator(tree, {
minimal: true,
Expand Down

0 comments on commit 29dc8cb

Please sign in to comment.