Skip to content

Commit

Permalink
fix(angular): process only angular projects in migration (#17833)
Browse files Browse the repository at this point in the history
(cherry picked from commit 20d45bb)
  • Loading branch information
leosvelperez authored and FrozenPandaz committed Jun 28, 2023
1 parent 70b977b commit 7be9aef
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import {
ProjectConfiguration,
ProjectGraph,
Tree,
addProjectConfiguration,
} from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import extractStandaloneConfig from './extract-standalone-config-from-bootstrap';
import { addProjectConfiguration } from '@nx/devkit';

let projectGraph: ProjectGraph;
jest.mock('@nx/devkit', () => ({
...jest.requireActual('@nx/devkit'),
createProjectGraphAsync: () => Promise.resolve(projectGraph),
}));

const TEST_MAIN_FILE = `import { bootstrapApplication } from '@angular/platform-browser';
import {
Expand All @@ -18,19 +29,22 @@ describe('extractStandaloneConfigFromBootstrap', () => {
it('should extract the config correctly from a standard main.ts file', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
addProjectConfiguration(tree, 'app1', {
name: 'app1',
root: 'apps/app1',
sourceRoot: 'apps/app1/src',
projectType: 'application',
targets: {
build: {
options: {
main: 'apps/app1/src/main.ts',
addProject(
tree,
'app1',
{
name: 'app1',
root: 'apps/app1',
sourceRoot: 'apps/app1/src',
projectType: 'application',
targets: {
build: {
options: { main: 'apps/app1/src/main.ts' },
},
},
},
});
['npm:@angular/core']
);

tree.write('apps/app1/src/main.ts', TEST_MAIN_FILE);

Expand Down Expand Up @@ -68,19 +82,22 @@ describe('extractStandaloneConfigFromBootstrap', () => {
it('should extract the config correctly when the main.ts imports bootstrap from bootstrap.ts file', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
addProjectConfiguration(tree, 'app1', {
name: 'app1',
root: 'apps/app1',
sourceRoot: 'apps/app1/src',
projectType: 'application',
targets: {
build: {
options: {
main: 'apps/app1/src/main.ts',
addProject(
tree,
'app1',
{
name: 'app1',
root: 'apps/app1',
sourceRoot: 'apps/app1/src',
projectType: 'application',
targets: {
build: {
options: { main: 'apps/app1/src/main.ts' },
},
},
},
});
['npm:@angular/core']
);

tree.write('apps/app1/src/main.ts', `import('./bootstrap');`);
tree.write('apps/app1/src/bootstrap.ts', TEST_MAIN_FILE);
Expand Down Expand Up @@ -120,4 +137,66 @@ describe('extractStandaloneConfigFromBootstrap', () => {
"
`);
});

it('should not throw with non-angular projects', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
addProject(
tree,
'app1',
{
name: 'app1',
projectType: 'application',
root: 'apps/app1',
sourceRoot: 'apps/app1',
targets: {
build: {
executor: '@nx-go/nx-go:build',
options: { main: 'apps/app1' },
},
},
},
[]
);

tree.write(
'apps/app1/main.go',
`package main
import "fmt"
func Hello(name string) string {
result := "Hello " + name
return result
}
func main() {
fmt.Println(Hello("app1"))
}`
);

// ACT && ASSERT
await expect(extractStandaloneConfig(tree)).resolves.not.toThrow();
});
});

function addProject(
tree: Tree,
projectName: string,
config: ProjectConfiguration,
dependencies: string[]
): void {
projectGraph = {
dependencies: {
[projectName]: dependencies.map((d) => ({
source: projectName,
target: d,
type: 'static',
})),
},
nodes: {
[projectName]: { data: config, name: projectName, type: 'app' },
},
};
addProjectConfiguration(tree, projectName, config);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { ProjectConfiguration, Tree } from '@nx/devkit';
import { formatFiles, getProjects, joinPathFragments } from '@nx/devkit';
import { formatFiles, joinPathFragments } from '@nx/devkit';
import { ensureTypescript } from '@nx/js/src/utils/typescript/ensure-typescript';
import { dirname, relative, resolve } from 'path';
import type { Identifier, Node, SourceFile, StringLiteral } from 'typescript';
import { getProjectsFilteredByDependencies } from '../utils/projects';

let tsModule: typeof import('typescript');
let tsquery: typeof import('@phenomnomnominal/tsquery').tsquery;
Expand Down Expand Up @@ -163,14 +164,16 @@ export default async function extractStandaloneConfig(tree: Tree) {
tsquery = require('@phenomnomnominal/tsquery').tsquery;
}

const projects = getProjects(tree);
const projects = await getProjectsFilteredByDependencies(tree, [
'npm:@angular/core',
]);

const BOOTSTRAP_APPLICATION_CALL_SELECTOR =
'CallExpression:has(Identifier[name=bootstrapApplication])';
const BOOTSTRAP_APPLICATION_CALL_CONFIG_SELECTOR =
'CallExpression:has(Identifier[name=bootstrapApplication]) > ObjectLiteralExpression';

for (const [, project] of projects.entries()) {
for (const { project } of projects) {
if (project.projectType !== 'application') {
continue;
}
Expand Down
9 changes: 4 additions & 5 deletions packages/angular/src/migrations/utils/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ export async function getProjectsFilteredByDependencies(
const projectGraph = await createProjectGraphAsync();

return Object.entries(projectGraph.dependencies)
.filter(([node, dep]) =>
dep.some(
({ target }) =>
!projectGraph.externalNodes?.[node] && dependencies.includes(target)
)
.filter(
([node, deps]) =>
!projectGraph.externalNodes?.[node] &&
deps.some(({ target }) => dependencies.includes(target))
)
.map(([projectName]) => ({
project: readProjectConfiguration(tree, projectName),
Expand Down

0 comments on commit 7be9aef

Please sign in to comment.