chore(core): move isNxGenerator out of workspaces (#18097)

This commit is contained in:
Emily Xiong 2023-07-18 18:12:15 -04:00 committed by GitHub
parent 3a29699210
commit d4f0e304b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 167 additions and 165 deletions

View File

@ -48,7 +48,6 @@ import {
toOldFormat,
} from './angular-json';
import { normalizeExecutorSchema } from '../command-line/run/executor-utils';
import { Workspaces } from '../config/workspaces';
import {
CustomHasher,
Executor,
@ -1033,8 +1032,6 @@ async function getWrappedWorkspaceNodeModulesArchitectHost(
} = await import('@angular-devkit/architect/node');
class WrappedWorkspaceNodeModulesArchitectHost extends AngularWorkspaceNodeModulesArchitectHost {
private workspaces = new Workspaces(this.root);
constructor(private workspace, private root) {
super(workspace, root);
}
@ -1064,7 +1061,7 @@ async function getWrappedWorkspaceNodeModulesArchitectHost(
const { json: packageJson, path: packageJsonPath } =
readPluginPackageJson(
nodeModule,
this.workspaces['resolvePaths'].bind(this.workspaces)()
this.root ? [this.root, __dirname] : [__dirname]
);
const executorsFile = packageJson.executors ?? packageJson.builders;

View File

@ -23,6 +23,7 @@ import { NxJsonConfiguration } from '../../config/nx-json';
import { findInstalledPlugins } from '../../utils/plugins/installed-plugins';
import type { Arguments } from 'yargs';
import { output } from '../../utils/output';
import { getGeneratorInformation } from './generator-utils';
export interface GenerateOptions {
collectionName: string;
@ -69,7 +70,7 @@ async function promptForCollection(
resolvedCollectionName,
normalizedGeneratorName,
generatorConfiguration: { ['x-deprecated']: deprecated, hidden },
} = ws.readGenerator(collectionName, generatorName);
} = getGeneratorInformation(collectionName, generatorName, workspaceRoot);
if (hidden) {
continue;
}
@ -94,7 +95,7 @@ async function promptForCollection(
resolvedCollectionName,
normalizedGeneratorName,
generatorConfiguration: { ['x-deprecated']: deprecated, hidden },
} = ws.readGenerator(name, generatorName);
} = getGeneratorInformation(name, generatorName, workspaceRoot);
if (hidden) {
continue;
}
@ -156,7 +157,7 @@ async function promptForCollection(
return true;
}
try {
ws.readGenerator(value, generatorName);
getGeneratorInformation(value, generatorName, workspaceRoot);
return true;
} catch {
logger.error(`\nCould not find ${value}:${generatorName}`);
@ -325,7 +326,11 @@ export async function generate(cwd: string, args: { [k: string]: any }) {
['x-deprecated']: deprecated,
['x-use-standalone-layout']: isStandalonePreset,
},
} = ws.readGenerator(opts.collectionName, opts.generatorName);
} = getGeneratorInformation(
opts.collectionName,
opts.generatorName,
workspaceRoot
);
if (deprecated) {
logger.warn(
@ -363,7 +368,13 @@ export async function generate(cwd: string, args: { [k: string]: any }) {
verbose
);
if (ws.isNxGenerator(opts.collectionName, normalizedGeneratorName)) {
if (
getGeneratorInformation(
opts.collectionName,
normalizedGeneratorName,
workspaceRoot
).isNxGenerator
) {
const host = new FsTree(
workspaceRoot,
verbose,

View File

@ -0,0 +1,147 @@
import { dirname, join } from 'path';
import {
Generator,
GeneratorsJson,
GeneratorsJsonEntry,
} from '../../config/misc-interfaces';
import {
getImplementationFactory,
resolveSchema,
} from '../../config/schema-utils';
import { readJsonFile } from '../../utils/fileutils';
import { readPluginPackageJson } from '../../utils/nx-plugin';
import { getNxRequirePaths } from '../../utils/installation-directory';
export function getGeneratorInformation(
collectionName: string,
generatorName: string,
root: string | null
): {
resolvedCollectionName: string;
normalizedGeneratorName: string;
schema: any;
implementationFactory: () => Generator<unknown>;
isNgCompat: boolean;
isNxGenerator: boolean;
generatorConfiguration: GeneratorsJsonEntry;
} {
try {
const {
generatorsFilePath,
generatorsJson,
resolvedCollectionName,
normalizedGeneratorName,
} = readGeneratorsJson(collectionName, generatorName, root);
const generatorsDir = dirname(generatorsFilePath);
const generatorConfig =
generatorsJson.generators?.[normalizedGeneratorName] ||
generatorsJson.schematics?.[normalizedGeneratorName];
const isNgCompat = !generatorsJson.generators?.[normalizedGeneratorName];
const schemaPath = resolveSchema(generatorConfig.schema, generatorsDir);
const schema = readJsonFile(schemaPath);
if (!schema.properties || typeof schema.properties !== 'object') {
schema.properties = {};
}
generatorConfig.implementation =
generatorConfig.implementation || generatorConfig.factory;
const implementationFactory = getImplementationFactory<Generator>(
generatorConfig.implementation,
generatorsDir
);
const normalizedGeneratorConfiguration: GeneratorsJsonEntry = {
...generatorConfig,
aliases: generatorConfig.aliases ?? [],
hidden: !!generatorConfig.hidden,
};
return {
resolvedCollectionName,
normalizedGeneratorName,
schema,
implementationFactory,
isNgCompat,
isNxGenerator: !isNgCompat,
generatorConfiguration: normalizedGeneratorConfiguration,
};
} catch (e) {
throw new Error(
`Unable to resolve ${collectionName}:${generatorName}.\n${e.message}`
);
}
}
export function readGeneratorsJson(
collectionName: string,
generator: string,
root: string | null
): {
generatorsFilePath: string;
generatorsJson: GeneratorsJson;
normalizedGeneratorName: string;
resolvedCollectionName: string;
} {
let generatorsFilePath;
if (collectionName.endsWith('.json')) {
generatorsFilePath = require.resolve(collectionName, {
paths: root ? [root, __dirname] : [__dirname],
});
} else {
const { json: packageJson, path: packageJsonPath } = readPluginPackageJson(
collectionName,
root ? [root, __dirname] : [__dirname]
);
const generatorsFile = packageJson.generators ?? packageJson.schematics;
if (!generatorsFile) {
throw new Error(
`The "${collectionName}" package does not support Nx generators.`
);
}
generatorsFilePath = require.resolve(
join(dirname(packageJsonPath), generatorsFile)
);
}
const generatorsJson = readJsonFile<GeneratorsJson>(generatorsFilePath);
let normalizedGeneratorName =
findFullGeneratorName(generator, generatorsJson.generators) ||
findFullGeneratorName(generator, generatorsJson.schematics);
if (!normalizedGeneratorName) {
for (let parent of generatorsJson.extends || []) {
try {
return readGeneratorsJson(parent, generator, root);
} catch (e) {}
}
throw new Error(
`Cannot find generator '${generator}' in ${generatorsFilePath}.`
);
}
return {
generatorsFilePath,
generatorsJson,
normalizedGeneratorName,
resolvedCollectionName: collectionName,
};
}
function findFullGeneratorName(
name: string,
generators: {
[name: string]: { aliases?: string[] };
}
) {
if (generators) {
for (let [key, data] of Object.entries<{ aliases?: string[] }>(
generators
)) {
if (
key === name ||
(data.aliases && (data.aliases as string[]).includes(name))
) {
return key;
}
}
}
}

View File

@ -1,6 +1,6 @@
import { Workspaces } from '../../config/workspaces';
import { flushChanges, FsTree } from '../../generators/tree';
import { combineOptionsForGenerator, handleErrors } from '../../utils/params';
import { getGeneratorInformation } from '../generate/generator-utils';
function removeSpecialFlags(generatorOptions: { [p: string]: any }): void {
delete generatorOptions.interactive;
@ -11,14 +11,12 @@ function removeSpecialFlags(generatorOptions: { [p: string]: any }): void {
}
export async function newWorkspace(cwd: string, args: { [k: string]: any }) {
const ws = new Workspaces(null);
return handleErrors(
process.env.NX_VERBOSE_LOGGING === 'true' || args.verbose,
async () => {
const isInteractive = args.interactive;
const { normalizedGeneratorName, schema, implementationFactory } =
ws.readGenerator('@nx/workspace/generators.json', 'new');
getGeneratorInformation('@nx/workspace/generators.json', 'new', null);
removeSpecialFlags(args);
const combinedOpts = await combineOptionsForGenerator(
args,

View File

@ -6,11 +6,7 @@ import { performance } from 'perf_hooks';
import { workspaceRoot } from '../utils/workspace-root';
import { readJsonFile, readYamlFile } from '../utils/fileutils';
import { logger, NX_PREFIX } from '../utils/logger';
import {
loadNxPlugins,
loadNxPluginsSync,
readPluginPackageJson,
} from '../utils/nx-plugin';
import { loadNxPlugins, loadNxPluginsSync } from '../utils/nx-plugin';
import type { NxJsonConfiguration, TargetDefaults } from './nx-json';
import {
@ -18,11 +14,6 @@ import {
ProjectsConfigurations,
TargetConfiguration,
} from './workspace-json-project-json';
import {
Generator,
GeneratorsJson,
GeneratorsJsonEntry,
} from './misc-interfaces';
import { PackageJson } from '../utils/package-json';
import { output } from '../utils/output';
import { joinPathFragments } from '../utils/path';
@ -36,7 +27,6 @@ import {
findProjectForPath,
normalizeProjectRoot,
} from '../project-graph/utils/find-project-for-path';
import { getImplementationFactory, resolveSchema } from './schema-utils';
export class Workspaces {
private cachedProjectsConfig: ProjectsConfigurations;
@ -164,69 +154,6 @@ export class Workspaces {
return projects;
}
isNxGenerator(collectionName: string, generatorName: string) {
return !this.readGenerator(collectionName, generatorName).isNgCompat;
}
readGenerator(
collectionName: string,
generatorName: string
): {
resolvedCollectionName: string;
normalizedGeneratorName: string;
schema: any;
implementationFactory: () => Generator<unknown>;
isNgCompat: boolean;
/**
* @deprecated(v16): This will be removed in v16, use generatorConfiguration.aliases
*/
aliases: string[];
generatorConfiguration: GeneratorsJsonEntry;
} {
try {
const {
generatorsFilePath,
generatorsJson,
resolvedCollectionName,
normalizedGeneratorName,
} = this.readGeneratorsJson(collectionName, generatorName);
const generatorsDir = path.dirname(generatorsFilePath);
const generatorConfig =
generatorsJson.generators?.[normalizedGeneratorName] ||
generatorsJson.schematics?.[normalizedGeneratorName];
const isNgCompat = !generatorsJson.generators?.[normalizedGeneratorName];
const schemaPath = resolveSchema(generatorConfig.schema, generatorsDir);
const schema = readJsonFile(schemaPath);
if (!schema.properties || typeof schema.properties !== 'object') {
schema.properties = {};
}
generatorConfig.implementation =
generatorConfig.implementation || generatorConfig.factory;
const implementationFactory = getImplementationFactory<Generator>(
generatorConfig.implementation,
generatorsDir
);
const normalizedGeneratorConfiguration: GeneratorsJsonEntry = {
...generatorConfig,
aliases: generatorConfig.aliases ?? [],
hidden: !!generatorConfig.hidden,
};
return {
resolvedCollectionName,
normalizedGeneratorName,
schema,
implementationFactory,
isNgCompat,
aliases: generatorConfig.aliases || [],
generatorConfiguration: normalizedGeneratorConfiguration,
};
} catch (e) {
throw new Error(
`Unable to resolve ${collectionName}:${generatorName}.\n${e.message}`
);
}
}
hasNxJson(): boolean {
const nxJson = path.join(this.root, 'nx.json');
return existsSync(nxJson);
@ -262,64 +189,6 @@ export class Workspaces {
}
}
}
private readGeneratorsJson(
collectionName: string,
generator: string
): {
generatorsFilePath: string;
generatorsJson: GeneratorsJson;
normalizedGeneratorName: string;
resolvedCollectionName: string;
} {
let generatorsFilePath;
if (collectionName.endsWith('.json')) {
generatorsFilePath = require.resolve(collectionName, {
paths: this.resolvePaths(),
});
} else {
const { json: packageJson, path: packageJsonPath } =
readPluginPackageJson(collectionName, this.resolvePaths());
const generatorsFile = packageJson.generators ?? packageJson.schematics;
if (!generatorsFile) {
throw new Error(
`The "${collectionName}" package does not support Nx generators.`
);
}
generatorsFilePath = require.resolve(
path.join(path.dirname(packageJsonPath), generatorsFile)
);
}
const generatorsJson = readJsonFile<GeneratorsJson>(generatorsFilePath);
let normalizedGeneratorName =
findFullGeneratorName(generator, generatorsJson.generators) ||
findFullGeneratorName(generator, generatorsJson.schematics);
if (!normalizedGeneratorName) {
for (let parent of generatorsJson.extends || []) {
try {
return this.readGeneratorsJson(parent, generator);
} catch (e) {}
}
throw new Error(
`Cannot find generator '${generator}' in ${generatorsFilePath}.`
);
}
return {
generatorsFilePath,
generatorsJson,
normalizedGeneratorName,
resolvedCollectionName: collectionName,
};
}
private resolvePaths() {
return this.root ? [this.root, __dirname] : [__dirname];
}
}
function findMatchingProjectInCwd(
@ -335,26 +204,6 @@ function findMatchingProjectInCwd(
return matchingProject;
}
function findFullGeneratorName(
name: string,
generators: {
[name: string]: { aliases?: string[] };
}
) {
if (generators) {
for (let [key, data] of Object.entries<{ aliases?: string[] }>(
generators
)) {
if (
key === name ||
(data.aliases && (data.aliases as string[]).includes(name))
) {
return key;
}
}
}
}
/**
* Pulled from toFileName in names from @nx/devkit.
* Todo: Should refactor, not duplicate.