Skip to content

Commit

Permalink
fix(misc): fix misc issues with move generators
Browse files Browse the repository at this point in the history
  • Loading branch information
leosvelperez committed Jun 27, 2023
1 parent 836cd34 commit 5d573fc
Show file tree
Hide file tree
Showing 15 changed files with 360 additions and 107 deletions.
4 changes: 4 additions & 0 deletions packages/angular/src/generators/move/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './normalize-schema';
export * from './update-module-name';
export * from './update-ng-package';
export * from './update-secondary-entry-points';
15 changes: 15 additions & 0 deletions packages/angular/src/generators/move/lib/normalize-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Tree } from '@nx/devkit';
import { readProjectConfiguration } from '@nx/devkit';
import type { NormalizedSchema, Schema } from '../schema';
import { getNewProjectName } from '../../utils/get-new-project-name';

export function normalizeSchema(tree: Tree, schema: Schema): NormalizedSchema {
const newProjectName = getNewProjectName(schema.destination);
const { root } = readProjectConfiguration(tree, schema.projectName);

return {
...schema,
newProjectName,
oldProjectRoot: root,
};
}
54 changes: 41 additions & 13 deletions packages/angular/src/generators/move/lib/update-module-name.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Linter } from '@nx/linter';
import { moveGenerator } from '@nx/workspace/generators';
import { UnitTestRunner } from '../../../utils/test-runners';
import { generateTestLibrary } from '../../utils/testing';
import { Schema } from '../schema';
import { NormalizedSchema } from '../schema';
import { updateModuleName } from './update-module-name';

describe('updateModuleName Rule', () => {
Expand All @@ -20,17 +20,19 @@ describe('updateModuleName Rule', () => {
name: 'my-first',
simpleName: true,
});
const schema: Schema = {
const schema: NormalizedSchema = {
projectName: 'my-first',
destination: 'my/first',
updateImportPath: true,
newProjectName: 'my-first',
oldProjectRoot: 'libs/my-first',
};
await moveGenerator(tree, schema);

updateModuleName(tree, { ...schema, destination: 'my/first' });

expect(tree.exists(updatedModulePath)).toBe(true);
const moduleFile = tree.read(updatedModulePath).toString('utf-8');
const moduleFile = tree.read(updatedModulePath, 'utf-8');
expect(moduleFile).toContain(`export class MyFirstModule {}`);
});

Expand All @@ -42,10 +44,12 @@ describe('updateModuleName Rule', () => {
const indexPath = '/libs/shared/my-first/src/index.ts';
const secondModulePath = '/libs/my-second/src/lib/my-second.module.ts';

const schema: Schema = {
const schema: NormalizedSchema = {
projectName: 'my-first',
destination: 'shared/my-first',
updateImportPath: true,
newProjectName: 'shared-my-first',
oldProjectRoot: 'libs/my-first',
};

beforeEach(async () => {
Expand Down Expand Up @@ -111,10 +115,10 @@ describe('updateModuleName Rule', () => {
expect(tree.exists(updatedModulePath)).toBe(true);
expect(tree.exists(updatedModuleSpecPath)).toBe(true);

const moduleFile = tree.read(updatedModulePath).toString('utf-8');
const moduleFile = tree.read(updatedModulePath, 'utf-8');
expect(moduleFile).toContain(`export class SharedMyFirstModule {}`);

const moduleSpecFile = tree.read(updatedModuleSpecPath).toString('utf-8');
const moduleSpecFile = tree.read(updatedModuleSpecPath, 'utf-8');
expect(moduleSpecFile).toContain(
`import { SharedMyFirstModule } from './shared-my-first.module';`
);
Expand All @@ -130,7 +134,7 @@ describe('updateModuleName Rule', () => {
it('should update any references to the module', async () => {
updateModuleName(tree, schema);

const importerFile = tree.read(secondModulePath).toString('utf-8');
const importerFile = tree.read(secondModulePath, 'utf-8');
expect(importerFile).toContain(
`import { SharedMyFirstModule } from '@proj/shared/my-first';`
);
Expand All @@ -142,18 +146,20 @@ describe('updateModuleName Rule', () => {
it('should update the index.ts file which exports the module', async () => {
updateModuleName(tree, schema);

const indexFile = tree.read(indexPath).toString('utf-8');
const indexFile = tree.read(indexPath, 'utf-8');
expect(indexFile).toContain(
`export * from './lib/shared-my-first.module';`
);
});
});

describe('rename', () => {
const schema: Schema = {
const schema: NormalizedSchema = {
projectName: 'my-source',
destination: 'my-destination',
updateImportPath: true,
newProjectName: 'my-destination',
oldProjectRoot: 'libs/my-source',
};

const modulePath = '/libs/my-destination/src/lib/my-destination.module.ts';
Expand Down Expand Up @@ -233,10 +239,10 @@ describe('updateModuleName Rule', () => {
expect(tree.exists(modulePath)).toBe(true);
expect(tree.exists(moduleSpecPath)).toBe(true);

const moduleFile = tree.read(modulePath).toString('utf-8');
const moduleFile = tree.read(modulePath, 'utf-8');
expect(moduleFile).toContain(`export class MyDestinationModule {}`);

const moduleSpecFile = tree.read(moduleSpecPath).toString('utf-8');
const moduleSpecFile = tree.read(moduleSpecPath, 'utf-8');
expect(moduleSpecFile).toContain(
`import { MyDestinationModule } from './my-destination.module';`
);
Expand All @@ -252,7 +258,7 @@ describe('updateModuleName Rule', () => {
it('should update any references to the module', async () => {
updateModuleName(tree, schema);

const importerFile = tree.read(importerPath).toString('utf-8');
const importerFile = tree.read(importerPath, 'utf-8');
expect(importerFile).toContain(
`import { MyDestinationModule } from '@proj/my-destination';`
);
Expand All @@ -264,10 +270,32 @@ describe('updateModuleName Rule', () => {
it('should update the index.ts file which exports the module', async () => {
updateModuleName(tree, schema);

const indexFile = tree.read(indexPath).toString('utf-8');
const indexFile = tree.read(indexPath, 'utf-8');
expect(indexFile).toContain(
`export * from './lib/my-destination.module';`
);
});

it('should not rename unrelated symbols with similar name in different projects', async () => {
// create different project whose main module name starts with the same
// name of the project we're moving
await generateTestLibrary(tree, {
name: 'my-source-demo',
buildable: false,
linter: Linter.EsLint,
publishable: false,
simpleName: true,
skipFormat: false,
unitTestRunner: UnitTestRunner.Jest,
});

updateModuleName(tree, schema);

const moduleFile = tree.read(
'/libs/my-source-demo/src/lib/my-source-demo.module.ts',
'utf-8'
);
expect(moduleFile).toContain(`export class MySourceDemoModule {}`);
});
});
});
17 changes: 7 additions & 10 deletions packages/angular/src/generators/move/lib/update-module-name.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import {
getProjects,
joinPathFragments,
names,
readProjectConfiguration,
Tree,
visitNotIgnoredFiles,
} from '@nx/devkit';
import { getNewProjectName } from '../../utils/get-new-project-name';
import { join } from 'path';
import { Schema } from '../schema';
import type { NormalizedSchema } from '../schema';

/**
* Updates the Angular module name (including the spec file and index.ts)
Expand All @@ -19,10 +18,8 @@ import { Schema } from '../schema';
*/
export function updateModuleName(
tree: Tree,
{ projectName, destination }: Schema
{ projectName: oldProjectName, newProjectName }: NormalizedSchema
): void {
const newProjectName = getNewProjectName(destination);

const project = readProjectConfiguration(tree, newProjectName);

if (project.projectType === 'application') {
Expand All @@ -32,14 +29,14 @@ export function updateModuleName(
}

const moduleName = {
from: names(projectName).className,
to: names(newProjectName).className,
from: `${names(oldProjectName).className}Module`,
to: `${names(newProjectName).className}Module`,
};

const findModuleName = new RegExp(`\\b${moduleName.from}`, 'g');

const moduleFile = {
from: `${projectName}.module`,
from: `${oldProjectName}.module`,
to: `${newProjectName}.module`,
};

Expand Down Expand Up @@ -81,7 +78,7 @@ export function updateModuleName(
});

// update index file
const indexFile = join(project.sourceRoot, 'index.ts');
const indexFile = joinPathFragments(project.sourceRoot, 'index.ts');
if (tree.exists(indexFile)) {
updateFileContent(tree, replacements, indexFile);
}
Expand Down
12 changes: 5 additions & 7 deletions packages/angular/src/generators/move/lib/update-ng-package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ import {
updateJson,
workspaceRoot,
} from '@nx/devkit';
import { getNewProjectName } from '../../utils/get-new-project-name';
import { join, relative } from 'path';
import { Schema } from '../schema';
import type { NormalizedSchema } from '../schema';

export function updateNgPackage(tree: Tree, schema: Schema): void {
const newProjectName = getNewProjectName(schema.destination);
const project = readProjectConfiguration(tree, newProjectName);
export function updateNgPackage(tree: Tree, schema: NormalizedSchema): void {
const project = readProjectConfiguration(tree, schema.newProjectName);

if (project.projectType === 'application') {
return;
Expand All @@ -29,13 +27,13 @@ export function updateNgPackage(tree: Tree, schema: Schema): void {
const outputs = getOutputsForTargetAndConfiguration(
{
target: {
project: newProjectName,
project: schema.newProjectName,
target: 'build',
},
overrides: {},
},
{
name: newProjectName,
name: schema.newProjectName,
type: 'lib',
data: {
root: project.root,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import type { Tree } from '@nx/devkit';
import {
joinPathFragments,
normalizePath,
readProjectConfiguration,
visitNotIgnoredFiles,
} from '@nx/devkit';
import { basename, dirname } from 'path';
import type { NormalizedSchema } from '../schema';

const libraryExecutors = [
'@angular-devkit/build-angular:ng-packagr',
'@nx/angular:ng-packagr-lite',
'@nx/angular:package',
// TODO(v17): remove when @nrwl/* scope is removed
'@nrwl/angular:ng-packagr-lite',
'@nrwl/angular:package',
];

export function updateSecondaryEntryPoints(
tree: Tree,
schema: NormalizedSchema
): void {
const project = readProjectConfiguration(tree, schema.newProjectName);

if (project.projectType !== 'library') {
return;
}

if (
!Object.values(project.targets ?? {}).some((target) =>
libraryExecutors.includes(target.executor)
)
) {
return;
}

visitNotIgnoredFiles(tree, project.root, (filePath) => {
if (
basename(filePath) !== 'ng-package.json' ||
normalizePath(filePath) ===
joinPathFragments(project.root, 'ng-package.json')
) {
return;
}

updateReadme(
tree,
dirname(filePath),
schema.projectName,
schema.newProjectName
);
});
}

function updateReadme(
tree: Tree,
dir: string,
oldProjectName: string,
newProjectName: string
) {
const readmePath = joinPathFragments(dir, 'README.md');
if (!tree.exists(readmePath)) {
return;
}

const findName = new RegExp(`${oldProjectName}`, 'g');
const oldContent = tree.read(readmePath, 'utf-8');
const newContent = oldContent.replace(findName, newProjectName);
tree.write(readmePath, newContent);
}
23 changes: 23 additions & 0 deletions packages/angular/src/generators/move/move.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { readJson, Tree } from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Linter } from '@nx/linter';
import { UnitTestRunner } from '../../utils/test-runners';
import librarySecondaryEntryPointGenerator from '../library-secondary-entry-point/library-secondary-entry-point';
import { generateTestLibrary } from '../utils/testing';
import { angularMoveGenerator } from './move';

Expand Down Expand Up @@ -50,6 +51,28 @@ describe('@nx/angular:move', () => {
expect(ngPackageJson.dest).toEqual('../../dist/libs/mynewlib2');
});

it('should update secondary entry points readme file', async () => {
await generateTestLibrary(tree, { name: 'mylib2', buildable: true });
await librarySecondaryEntryPointGenerator(tree, {
library: 'mylib2',
name: 'testing',
});

await angularMoveGenerator(tree, {
projectName: 'mylib2',
destination: 'mynewlib2',
updateImportPath: true,
});

const readme = tree.read('libs/mynewlib2/testing/README.md', 'utf-8');
expect(readme).toMatchInlineSnapshot(`
"# @proj/mynewlib2/testing
Secondary entry point of \`@proj/mynewlib2\`. It can be used by importing from \`@proj/mynewlib2/testing\`.
"
`);
});

it('should format files', async () => {
jest.spyOn(devkit, 'formatFiles');

Expand Down
19 changes: 13 additions & 6 deletions packages/angular/src/generators/move/move.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { formatFiles, Tree } from '@nx/devkit';
import { moveGenerator } from '@nx/workspace/generators';
import { updateModuleName } from './lib/update-module-name';
import { updateNgPackage } from './lib/update-ng-package';
import { Schema } from './schema';
import {
normalizeSchema,
updateModuleName,
updateNgPackage,
updateSecondaryEntryPoints,
} from './lib';
import type { Schema } from './schema';

/**
* Moves an Angular lib/app to another folder (and renames it in the process)
Expand All @@ -15,11 +19,14 @@ export async function angularMoveGenerator(
tree: Tree,
schema: Schema
): Promise<void> {
const normalizedSchema = normalizeSchema(tree, schema);

await moveGenerator(tree, { ...schema, skipFormat: true });
updateModuleName(tree, schema);
updateNgPackage(tree, schema);
updateModuleName(tree, normalizedSchema);
updateNgPackage(tree, normalizedSchema);
updateSecondaryEntryPoints(tree, normalizedSchema);

if (!schema.skipFormat) {
if (!normalizedSchema.skipFormat) {
await formatFiles(tree);
}
}
Loading

0 comments on commit 5d573fc

Please sign in to comment.