Skip to content

Commit

Permalink
fix(angular): init also installs plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
jaysoo committed Sep 16, 2024
1 parent 89aa6d4 commit b920b8a
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 59 deletions.
9 changes: 7 additions & 2 deletions e2e/nx/src/import.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getSelectedPackageManager,
newProject,
runCLI,
runCommand,
updateJson,
updateFile,
e2eCwd,
Expand Down Expand Up @@ -38,7 +39,11 @@ describe('Nx Import', () => {
try {
rmdirSync(join(tempImportE2ERoot));
} catch {}

runCommand(`git add .`);
runCommand(`git commit -am "Update" --allow-empty`);
});

afterAll(() => cleanupProject());

it('should be able to import a vite app', () => {
Expand Down Expand Up @@ -111,15 +116,15 @@ describe('Nx Import', () => {
});
mkdirSync(join(repoPath, 'packages/a'), { recursive: true });
writeFileSync(join(repoPath, 'packages/a/README.md'), `# A`);
execSync(`git add packages/a`, {
execSync(`git add .`, {
cwd: repoPath,
});
execSync(`git commit -m "add package a"`, {
cwd: repoPath,
});
mkdirSync(join(repoPath, 'packages/b'), { recursive: true });
writeFileSync(join(repoPath, 'packages/b/README.md'), `# B`);
execSync(`git add packages/b`, {
execSync(`git add .`, {
cwd: repoPath,
});
execSync(`git commit -m "add package b"`, {
Expand Down
24 changes: 23 additions & 1 deletion packages/angular/src/generators/init/init.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import {
addDependenciesToPackageJson,
createProjectGraphAsync,
ensurePackage,
formatFiles,
type GeneratorCallback,
logger,
readNxJson,
type GeneratorCallback,
type Tree,
} from '@nx/devkit';
import { addPlugin } from '@nx/devkit/src/utils/add-plugin';
import { getInstalledPackageVersion, versions } from '../utils/version-utils';
import { createNodesV2 } from '../../plugins/plugin';
import { Schema } from './schema';

export async function angularInitGenerator(
Expand All @@ -17,6 +20,25 @@ export async function angularInitGenerator(
ignoreAngularCacheDirectory(tree);
const installTask = installAngularDevkitCoreIfMissing(tree, options);

// For Angular inference plugin, we only want it during import since our
// generators do not use `angular.json`, and `nx init` should split
// `angular.json` into multiple `project.json` files -- as this is preferred
// by most folks we've talked to.
options.addPlugin ??= process.env.NX_RUNNING_NX_IMPORT === 'true';

if (options.addPlugin) {
await addPlugin(
tree,
await createProjectGraphAsync(),
'@nx/angular/plugin',
createNodesV2,
{
targetNamePrefix: ['', 'angular:', 'angular-'],
},
options.updatePackageScripts
);
}

if (!options.skipFormat) {
await formatFiles(tree);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/angular/src/generators/init/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ export interface Schema {
skipInstall?: boolean;
skipPackageJson?: boolean;
keepExistingVersions?: boolean;
/* internal */
addPlugin?: boolean;
updatePackageScripts?: boolean;
}
30 changes: 15 additions & 15 deletions packages/angular/src/plugins/plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe('@nx/angular/plugin', () => {
"targets": {
"build": {
"cache": true,
"command": "ng run my-app:build",
"command": "ng build",
"dependsOn": [
"^build",
],
Expand Down Expand Up @@ -131,7 +131,7 @@ describe('@nx/angular/plugin', () => {
],
},
"serve": {
"command": "ng run my-app:serve",
"command": "ng serve",
"configurations": {
"production": {
"command": "ng run my-app:serve:production",
Expand All @@ -157,7 +157,7 @@ describe('@nx/angular/plugin', () => {
},
"test": {
"cache": true,
"command": "ng run my-app:test",
"command": "ng test",
"inputs": [
"default",
"^production",
Expand Down Expand Up @@ -197,7 +197,7 @@ describe('@nx/angular/plugin', () => {
"targets": {
"build": {
"cache": true,
"command": "ng run my-lib:build",
"command": "ng build",
"dependsOn": [
"^build",
],
Expand Down Expand Up @@ -233,7 +233,7 @@ describe('@nx/angular/plugin', () => {
},
"test": {
"cache": true,
"command": "ng run my-lib:test",
"command": "ng test",
"inputs": [
"default",
"^production",
Expand Down Expand Up @@ -394,7 +394,7 @@ describe('@nx/angular/plugin', () => {
"targets": {
"build": {
"cache": true,
"command": "ng run org1-app1:build",
"command": "ng build",
"dependsOn": [
"^build",
],
Expand Down Expand Up @@ -429,7 +429,7 @@ describe('@nx/angular/plugin', () => {
],
},
"serve": {
"command": "ng run org1-app1:serve",
"command": "ng serve",
"configurations": {
"production": {
"command": "ng run org1-app1:serve:production",
Expand All @@ -455,7 +455,7 @@ describe('@nx/angular/plugin', () => {
},
"test": {
"cache": true,
"command": "ng run org1-app1:test",
"command": "ng test",
"inputs": [
"default",
"^production",
Expand Down Expand Up @@ -495,7 +495,7 @@ describe('@nx/angular/plugin', () => {
"targets": {
"build": {
"cache": true,
"command": "ng run org1-lib1:build",
"command": "ng build",
"dependsOn": [
"^build",
],
Expand Down Expand Up @@ -531,7 +531,7 @@ describe('@nx/angular/plugin', () => {
},
"test": {
"cache": true,
"command": "ng run org1-lib1:test",
"command": "ng test",
"inputs": [
"default",
"^production",
Expand Down Expand Up @@ -578,7 +578,7 @@ describe('@nx/angular/plugin', () => {
"targets": {
"build": {
"cache": true,
"command": "ng run org2-app1:build",
"command": "ng build",
"dependsOn": [
"^build",
],
Expand Down Expand Up @@ -613,7 +613,7 @@ describe('@nx/angular/plugin', () => {
],
},
"serve": {
"command": "ng run org2-app1:serve",
"command": "ng serve",
"configurations": {
"production": {
"command": "ng run org2-app1:serve:production",
Expand All @@ -639,7 +639,7 @@ describe('@nx/angular/plugin', () => {
},
"test": {
"cache": true,
"command": "ng run org2-app1:test",
"command": "ng test",
"inputs": [
"default",
"^production",
Expand Down Expand Up @@ -679,7 +679,7 @@ describe('@nx/angular/plugin', () => {
"targets": {
"build": {
"cache": true,
"command": "ng run org2-lib1:build",
"command": "ng build",
"dependsOn": [
"^build",
],
Expand Down Expand Up @@ -715,7 +715,7 @@ describe('@nx/angular/plugin', () => {
},
"test": {
"cache": true,
"command": "ng run org2-lib1:test",
"command": "ng test",
"inputs": [
"default",
"^production",
Expand Down
26 changes: 23 additions & 3 deletions packages/angular/src/plugins/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import * as posix from 'node:path/posix';
import { hashObject } from 'nx/src/devkit-internals';
import { workspaceDataDirectory } from 'nx/src/utils/cache-directory';

export interface AngularPluginOptions {
targetNamePrefix?: string;
}

type AngularProjects = Record<
string,
Pick<ProjectConfiguration, 'projectType' | 'sourceRoot' | 'targets'>
Expand Down Expand Up @@ -76,7 +80,7 @@ function writeProjectsToCache(
writeJsonFile(cachePath, results);
}

export const createNodesV2: CreateNodesV2<{}> = [
export const createNodesV2: CreateNodesV2<AngularPluginOptions> = [
'**/angular.json',
async (configFiles, options, context) => {
const optionsHash = hashObject(options);
Expand Down Expand Up @@ -124,6 +128,7 @@ async function createNodesInternal(

projectsCache[hash] ??= await buildAngularProjects(
configFilePath,
options,
angularWorkspaceRoot,
context
);
Expand All @@ -133,6 +138,7 @@ async function createNodesInternal(

async function buildAngularProjects(
configFilePath: string,
options: AngularPluginOptions,
angularWorkspaceRoot: string,
context: CreateNodesContextV2
): Promise<AngularProjects> {
Expand All @@ -156,11 +162,25 @@ async function buildAngularProjects(

const namedInputs = getNamedInputs(project.root, context);

for (const [targetName, angularTarget] of Object.entries(projectTargets)) {
for (const [_targetName, angularTarget] of Object.entries(projectTargets)) {
const targetName = options?.targetNamePrefix
? `${options.targetNamePrefix}${_targetName}`
: _targetName;
const externalDependencies = ['@angular/cli'];

targets[targetName] = {
command: `ng run ${projectName}:${targetName}`,
command:
// For targets that are also Angular CLI commands, infer the simplified form.
// Otherwise, use `ng run` to support non-command targets so that they will run.
targetName === 'build' ||
targetName === 'deploy' ||
targetName === 'extract-i18n' ||
targetName === 'e2e' ||
targetName === 'lint' ||
targetName === 'serve' ||
targetName === 'test'
? `ng ${targetName}`
: `ng run ${projectName}:${targetName}`,
options: { cwd: angularWorkspaceRoot },
metadata: {
technologies: ['angular'],
Expand Down
89 changes: 56 additions & 33 deletions packages/devkit/src/utils/add-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,64 @@ async function _addPluginInternal<PluginOptions>(

let pluginOptions: PluginOptions;
let projConfigs: ConfigurationResult;
const combinations = generateCombinations(options);
optionsLoop: for (const _pluginOptions of combinations) {
pluginOptions = _pluginOptions as PluginOptions;

nxJson.plugins ??= [];
if (
nxJson.plugins.some((p) =>
typeof p === 'string'
? p === pluginName
: p.plugin === pluginName && !p.include
)
) {
// Plugin has already been added
return;
if (Object.keys(options).length > 0) {
const combinations = generateCombinations(options);
optionsLoop: for (const _pluginOptions of combinations) {
pluginOptions = _pluginOptions as PluginOptions;

nxJson.plugins ??= [];
if (
nxJson.plugins.some((p) =>
typeof p === 'string'
? p === pluginName
: p.plugin === pluginName && !p.include
)
) {
// Plugin has already been added
return;
}
global.NX_GRAPH_CREATION = true;
try {
projConfigs = await retrieveProjectConfigurations(
[pluginFactory(pluginOptions)],
tree.root,
nxJson
);
} catch (e) {
// Errors are okay for this because we're only running 1 plugin
if (e instanceof ProjectConfigurationsError) {
projConfigs = e.partialProjectConfigurationsResult;
} else {
throw e;
}
}
global.NX_GRAPH_CREATION = false;

for (const projConfig of Object.values(projConfigs.projects)) {
const node = graphNodes.find(
(node) => node.data.root === projConfig.root
);

if (!node) {
continue;
}

for (const targetName in projConfig.targets) {
if (node.data.targets[targetName]) {
// Conflicting Target Name, check the next one
pluginOptions = null;
continue optionsLoop;
}
}
}

break;
}
} else {
// If the plugin does not take in options, we add the plugin with empty options.
nxJson.plugins ??= [];
pluginOptions = {} as unknown as PluginOptions;
global.NX_GRAPH_CREATION = true;
try {
projConfigs = await retrieveProjectConfigurations(
Expand All @@ -135,26 +178,6 @@ async function _addPluginInternal<PluginOptions>(
}
}
global.NX_GRAPH_CREATION = false;

for (const projConfig of Object.values(projConfigs.projects)) {
const node = graphNodes.find(
(node) => node.data.root === projConfig.root
);

if (!node) {
continue;
}

for (const targetName in projConfig.targets) {
if (node.data.targets[targetName]) {
// Conflicting Target Name, check the next one
pluginOptions = null;
continue optionsLoop;
}
}
}

break;
}

if (!pluginOptions) {
Expand Down
Loading

0 comments on commit b920b8a

Please sign in to comment.