feat(expo): use createNodesV2 (#28005)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
735300c63e
commit
277c58fbcc
@ -1,5 +1,5 @@
|
|||||||
export {
|
export {
|
||||||
createNodes,
|
createNodes,
|
||||||
createDependencies,
|
createNodesV2,
|
||||||
DetoxPluginOptions,
|
DetoxPluginOptions,
|
||||||
} from './src/plugins/plugin';
|
} from './src/plugins/plugin';
|
||||||
|
|||||||
@ -2,16 +2,15 @@ import {
|
|||||||
createProjectGraphAsync,
|
createProjectGraphAsync,
|
||||||
formatFiles,
|
formatFiles,
|
||||||
readNxJson,
|
readNxJson,
|
||||||
readProjectConfiguration,
|
|
||||||
type Tree,
|
type Tree,
|
||||||
updateNxJson,
|
updateNxJson,
|
||||||
} from '@nx/devkit';
|
} from '@nx/devkit';
|
||||||
import { AggregatedLog } from '@nx/devkit/src/generators/plugin-migrations/aggregate-log-util';
|
import { AggregatedLog } from '@nx/devkit/src/generators/plugin-migrations/aggregate-log-util';
|
||||||
import {
|
import {
|
||||||
migrateProjectExecutorsToPluginV1,
|
migrateProjectExecutorsToPlugin,
|
||||||
NoTargetsToMigrateError,
|
NoTargetsToMigrateError,
|
||||||
} from '@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator';
|
} from '@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator';
|
||||||
import { createNodes } from '../../plugins/plugin';
|
import { createNodesV2 } from '../../plugins/plugin';
|
||||||
import { processBuildOptions } from './lib/process-build-options';
|
import { processBuildOptions } from './lib/process-build-options';
|
||||||
import { postTargetTransformer } from './lib/post-target-transformer';
|
import { postTargetTransformer } from './lib/post-target-transformer';
|
||||||
import { processTestOptions } from './lib/process-test-options';
|
import { processTestOptions } from './lib/process-test-options';
|
||||||
@ -24,11 +23,11 @@ interface Schema {
|
|||||||
export async function convertToInferred(tree: Tree, options: Schema) {
|
export async function convertToInferred(tree: Tree, options: Schema) {
|
||||||
const projectGraph = await createProjectGraphAsync();
|
const projectGraph = await createProjectGraphAsync();
|
||||||
const migrationLogs = new AggregatedLog();
|
const migrationLogs = new AggregatedLog();
|
||||||
const migratedProjects = await migrateProjectExecutorsToPluginV1(
|
const migratedProjects = await migrateProjectExecutorsToPlugin(
|
||||||
tree,
|
tree,
|
||||||
projectGraph,
|
projectGraph,
|
||||||
'@nx/detox/plugin',
|
'@nx/detox/plugin',
|
||||||
createNodes,
|
createNodesV2,
|
||||||
{
|
{
|
||||||
buildTargetName: 'build',
|
buildTargetName: 'build',
|
||||||
startTargetName: 'start',
|
startTargetName: 'start',
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
CreateDependencies,
|
|
||||||
CreateNodes,
|
CreateNodes,
|
||||||
CreateNodesContext,
|
CreateNodesContext,
|
||||||
|
createNodesFromFiles,
|
||||||
|
CreateNodesResult,
|
||||||
|
CreateNodesV2,
|
||||||
detectPackageManager,
|
detectPackageManager,
|
||||||
NxJsonConfiguration,
|
NxJsonConfiguration,
|
||||||
readJsonFile,
|
readJsonFile,
|
||||||
@ -11,9 +13,10 @@ import {
|
|||||||
import { dirname, join } from 'path';
|
import { dirname, join } from 'path';
|
||||||
import { getLockFileName } from '@nx/js';
|
import { getLockFileName } from '@nx/js';
|
||||||
import { getNamedInputs } from '@nx/devkit/src/utils/get-named-inputs';
|
import { getNamedInputs } from '@nx/devkit/src/utils/get-named-inputs';
|
||||||
import { existsSync, readdirSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes';
|
import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes';
|
||||||
import { workspaceDataDirectory } from 'nx/src/utils/cache-directory';
|
import { workspaceDataDirectory } from 'nx/src/utils/cache-directory';
|
||||||
|
import { hashObject } from 'nx/src/devkit-internals';
|
||||||
|
|
||||||
export interface DetoxPluginOptions {
|
export interface DetoxPluginOptions {
|
||||||
buildTargetName?: string;
|
buildTargetName?: string;
|
||||||
@ -21,56 +24,97 @@ export interface DetoxPluginOptions {
|
|||||||
testTargetName?: string;
|
testTargetName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cachePath = join(workspaceDataDirectory, 'detox.hash');
|
function readTargetsCache(
|
||||||
const targetsCache = readTargetsCache();
|
cachePath: string
|
||||||
|
): Record<string, Record<string, TargetConfiguration<DetoxPluginOptions>>> {
|
||||||
function readTargetsCache(): Record<
|
|
||||||
string,
|
|
||||||
Record<string, TargetConfiguration<DetoxPluginOptions>>
|
|
||||||
> {
|
|
||||||
return existsSync(cachePath) ? readJsonFile(cachePath) : {};
|
return existsSync(cachePath) ? readJsonFile(cachePath) : {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeTargetsToCache() {
|
function writeTargetsToCache(
|
||||||
writeJsonFile(cachePath, targetsCache);
|
cachePath: string,
|
||||||
|
targetsCache: Record<
|
||||||
|
string,
|
||||||
|
Record<string, TargetConfiguration<DetoxPluginOptions>>
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
const oldCache = readTargetsCache(cachePath);
|
||||||
|
writeJsonFile(cachePath, {
|
||||||
|
...oldCache,
|
||||||
|
targetsCache,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createDependencies: CreateDependencies = () => {
|
export const createNodesV2: CreateNodesV2<DetoxPluginOptions> = [
|
||||||
writeTargetsToCache();
|
'**/{detox.config,.detoxrc}.{json,js}',
|
||||||
return [];
|
async (configFiles, options, context) => {
|
||||||
};
|
const optionsHash = hashObject(options);
|
||||||
|
const cachePath = join(workspaceDataDirectory, `expo-${optionsHash}.hash`);
|
||||||
|
const targetsCache = readTargetsCache(cachePath);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await createNodesFromFiles(
|
||||||
|
(configFile, options, context) =>
|
||||||
|
createNodesInternal(configFile, options, context, targetsCache),
|
||||||
|
configFiles,
|
||||||
|
options,
|
||||||
|
context
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
writeTargetsToCache(cachePath, targetsCache);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export const createNodes: CreateNodes<DetoxPluginOptions> = [
|
export const createNodes: CreateNodes<DetoxPluginOptions> = [
|
||||||
'**/{detox.config,.detoxrc}.{json,js}',
|
'**/{detox.config,.detoxrc}.{json,js}',
|
||||||
async (configFilePath, options, context) => {
|
async (configFilePath, options, context) => {
|
||||||
options = normalizeOptions(options);
|
const optionsHash = hashObject(options);
|
||||||
const projectRoot = dirname(configFilePath);
|
const cachePath = join(workspaceDataDirectory, `detox-${optionsHash}.hash`);
|
||||||
|
|
||||||
// Do not create a project if project.json isn't there.
|
const targetsCache = readTargetsCache(cachePath);
|
||||||
const siblingFiles = readdirSync(join(context.workspaceRoot, projectRoot));
|
const result = await createNodesInternal(
|
||||||
if (!siblingFiles.includes('project.json')) {
|
configFilePath,
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const hash = await calculateHashForCreateNodes(
|
|
||||||
projectRoot,
|
|
||||||
options,
|
options,
|
||||||
context,
|
context,
|
||||||
[getLockFileName(detectPackageManager(context.workspaceRoot))]
|
targetsCache
|
||||||
);
|
);
|
||||||
|
|
||||||
targetsCache[hash] ??= buildDetoxTargets(projectRoot, options, context);
|
writeTargetsToCache(cachePath, targetsCache);
|
||||||
|
|
||||||
return {
|
return result;
|
||||||
projects: {
|
|
||||||
[projectRoot]: {
|
|
||||||
targets: targetsCache[hash],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
async function createNodesInternal(
|
||||||
|
configFile: string,
|
||||||
|
options: DetoxPluginOptions,
|
||||||
|
context: CreateNodesContext,
|
||||||
|
targetsCache: Record<
|
||||||
|
string,
|
||||||
|
Record<string, TargetConfiguration<DetoxPluginOptions>>
|
||||||
|
>
|
||||||
|
): Promise<CreateNodesResult> {
|
||||||
|
options = normalizeOptions(options);
|
||||||
|
const projectRoot = dirname(configFile);
|
||||||
|
|
||||||
|
const hash = await calculateHashForCreateNodes(
|
||||||
|
projectRoot,
|
||||||
|
options,
|
||||||
|
context,
|
||||||
|
[getLockFileName(detectPackageManager(context.workspaceRoot))]
|
||||||
|
);
|
||||||
|
|
||||||
|
targetsCache[hash] ??= buildDetoxTargets(projectRoot, options, context);
|
||||||
|
|
||||||
|
return {
|
||||||
|
projects: {
|
||||||
|
[projectRoot]: {
|
||||||
|
targets: targetsCache[hash],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function buildDetoxTargets(
|
function buildDetoxTargets(
|
||||||
projectRoot: string,
|
projectRoot: string,
|
||||||
options: DetoxPluginOptions,
|
options: DetoxPluginOptions,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
export {
|
export {
|
||||||
createNodes,
|
createNodes,
|
||||||
createDependencies,
|
createNodesV2,
|
||||||
ExpoPluginOptions,
|
ExpoPluginOptions,
|
||||||
} from './plugins/plugin';
|
} from './plugins/plugin';
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
import {
|
import {
|
||||||
CreateDependencies,
|
|
||||||
CreateNodes,
|
CreateNodes,
|
||||||
CreateNodesContext,
|
CreateNodesContext,
|
||||||
|
createNodesFromFiles,
|
||||||
|
CreateNodesResult,
|
||||||
|
CreateNodesV2,
|
||||||
detectPackageManager,
|
detectPackageManager,
|
||||||
|
logger,
|
||||||
NxJsonConfiguration,
|
NxJsonConfiguration,
|
||||||
readJsonFile,
|
readJsonFile,
|
||||||
TargetConfiguration,
|
TargetConfiguration,
|
||||||
workspaceRoot,
|
|
||||||
writeJsonFile,
|
writeJsonFile,
|
||||||
} from '@nx/devkit';
|
} from '@nx/devkit';
|
||||||
import { dirname, join } from 'path';
|
import { dirname, join } from 'path';
|
||||||
@ -15,6 +17,8 @@ import { getNamedInputs } from '@nx/devkit/src/utils/get-named-inputs';
|
|||||||
import { existsSync, readdirSync } from 'fs';
|
import { existsSync, readdirSync } from 'fs';
|
||||||
import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes';
|
import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes';
|
||||||
import { workspaceDataDirectory } from 'nx/src/utils/cache-directory';
|
import { workspaceDataDirectory } from 'nx/src/utils/cache-directory';
|
||||||
|
import { combineGlobPatterns } from 'nx/src/utils/globs';
|
||||||
|
import { hashObject } from 'nx/src/devkit-internals';
|
||||||
import { loadConfigFile } from '@nx/devkit/src/utils/config-utils';
|
import { loadConfigFile } from '@nx/devkit/src/utils/config-utils';
|
||||||
|
|
||||||
export interface ExpoPluginOptions {
|
export interface ExpoPluginOptions {
|
||||||
@ -29,68 +33,114 @@ export interface ExpoPluginOptions {
|
|||||||
submitTargetName?: string;
|
submitTargetName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cachePath = join(workspaceDataDirectory, 'expo.hash');
|
function readTargetsCache(
|
||||||
const targetsCache = readTargetsCache();
|
cachePath: string
|
||||||
|
): Record<string, Record<string, TargetConfiguration<ExpoPluginOptions>>> {
|
||||||
function readTargetsCache(): Record<
|
|
||||||
string,
|
|
||||||
Record<string, TargetConfiguration<ExpoPluginOptions>>
|
|
||||||
> {
|
|
||||||
return existsSync(cachePath) ? readJsonFile(cachePath) : {};
|
return existsSync(cachePath) ? readJsonFile(cachePath) : {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeTargetsToCache() {
|
function writeTargetsToCache(
|
||||||
const oldCache = readTargetsCache();
|
cachePath: string,
|
||||||
|
targetsCache: Record<
|
||||||
|
string,
|
||||||
|
Record<string, TargetConfiguration<ExpoPluginOptions>>
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
const oldCache = readTargetsCache(cachePath);
|
||||||
writeJsonFile(cachePath, {
|
writeJsonFile(cachePath, {
|
||||||
...oldCache,
|
...oldCache,
|
||||||
targetsCache,
|
targetsCache,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createDependencies: CreateDependencies = () => {
|
export const createNodesV2: CreateNodesV2<ExpoPluginOptions> = [
|
||||||
writeTargetsToCache();
|
'**/app.{json,config.js,config.ts}',
|
||||||
return [];
|
async (configFiles, options, context) => {
|
||||||
};
|
const optionsHash = hashObject(options);
|
||||||
|
const cachePath = join(workspaceDataDirectory, `expo-${optionsHash}.hash`);
|
||||||
|
const targetsCache = readTargetsCache(cachePath);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await createNodesFromFiles(
|
||||||
|
(configFile, options, context) =>
|
||||||
|
createNodesInternal(configFile, options, context, targetsCache),
|
||||||
|
configFiles,
|
||||||
|
options,
|
||||||
|
context
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
writeTargetsToCache(cachePath, targetsCache);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export const createNodes: CreateNodes<ExpoPluginOptions> = [
|
export const createNodes: CreateNodes<ExpoPluginOptions> = [
|
||||||
'**/app.{json,config.js,config.ts}',
|
'**/app.{json,config.js,config.ts}',
|
||||||
async (configFilePath, options, context) => {
|
async (configFilePath, options, context) => {
|
||||||
options = normalizeOptions(options);
|
logger.warn(
|
||||||
const projectRoot = dirname(configFilePath);
|
'`createNodes` is deprecated. Update your plugin to utilize createNodesV2 instead. In Nx 20, this will change to the createNodesV2 API.'
|
||||||
|
|
||||||
// Do not create a project if package.json or project.json or metro.config.js isn't there.
|
|
||||||
const siblingFiles = readdirSync(join(context.workspaceRoot, projectRoot));
|
|
||||||
if (
|
|
||||||
!siblingFiles.includes('package.json') ||
|
|
||||||
!siblingFiles.includes('metro.config.js')
|
|
||||||
) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
const appConfig = await getAppConfig(configFilePath, context);
|
|
||||||
// if appConfig.expo is not defined
|
|
||||||
if (!appConfig.expo) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const hash = await calculateHashForCreateNodes(
|
|
||||||
projectRoot,
|
|
||||||
options,
|
|
||||||
context,
|
|
||||||
[getLockFileName(detectPackageManager(context.workspaceRoot))]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
targetsCache[hash] ??= buildExpoTargets(projectRoot, options, context);
|
const optionsHash = hashObject(options);
|
||||||
|
const cachePath = join(workspaceDataDirectory, `expo-${optionsHash}.hash`);
|
||||||
|
const targetsCache = readTargetsCache(cachePath);
|
||||||
|
|
||||||
return {
|
return createNodesInternal(configFilePath, options, context, targetsCache);
|
||||||
projects: {
|
|
||||||
[projectRoot]: {
|
|
||||||
targets: targetsCache[hash],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
async function createNodesInternal(
|
||||||
|
configFile: string,
|
||||||
|
options: ExpoPluginOptions,
|
||||||
|
context: CreateNodesContext,
|
||||||
|
targetsCache: Record<
|
||||||
|
string,
|
||||||
|
Record<string, TargetConfiguration<ExpoPluginOptions>>
|
||||||
|
>
|
||||||
|
): Promise<CreateNodesResult> {
|
||||||
|
options = normalizeOptions(options);
|
||||||
|
const projectRoot = dirname(configFile);
|
||||||
|
|
||||||
|
// Do not create a project if package.json or project.json or metro.config.js isn't there.
|
||||||
|
const siblingFiles = readdirSync(join(context.workspaceRoot, projectRoot));
|
||||||
|
if (
|
||||||
|
!siblingFiles.includes('package.json') ||
|
||||||
|
!siblingFiles.includes('metro.config.js')
|
||||||
|
) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's an Expo project
|
||||||
|
const packageJson = readJsonFile(
|
||||||
|
join(context.workspaceRoot, projectRoot, 'package.json')
|
||||||
|
);
|
||||||
|
const appConfig = await getAppConfig(configFile, context);
|
||||||
|
if (
|
||||||
|
!appConfig.expo &&
|
||||||
|
!packageJson.dependencies?.['expo'] &&
|
||||||
|
!packageJson.devDependencies?.['expo']
|
||||||
|
) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const hash = await calculateHashForCreateNodes(
|
||||||
|
projectRoot,
|
||||||
|
options,
|
||||||
|
context,
|
||||||
|
[getLockFileName(detectPackageManager(context.workspaceRoot))]
|
||||||
|
);
|
||||||
|
|
||||||
|
targetsCache[hash] ??= buildExpoTargets(projectRoot, options, context);
|
||||||
|
|
||||||
|
return {
|
||||||
|
projects: {
|
||||||
|
[projectRoot]: {
|
||||||
|
targets: targetsCache[hash],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function buildExpoTargets(
|
function buildExpoTargets(
|
||||||
projectRoot: string,
|
projectRoot: string,
|
||||||
options: ExpoPluginOptions,
|
options: ExpoPluginOptions,
|
||||||
|
|||||||
@ -6,10 +6,10 @@ import {
|
|||||||
} from '@nx/devkit';
|
} from '@nx/devkit';
|
||||||
import { AggregatedLog } from '@nx/devkit/src/generators/plugin-migrations/aggregate-log-util';
|
import { AggregatedLog } from '@nx/devkit/src/generators/plugin-migrations/aggregate-log-util';
|
||||||
import {
|
import {
|
||||||
migrateProjectExecutorsToPluginV1,
|
migrateProjectExecutorsToPlugin,
|
||||||
NoTargetsToMigrateError,
|
NoTargetsToMigrateError,
|
||||||
} from '@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator';
|
} from '@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator';
|
||||||
import { createNodes } from '../../../plugins/plugin';
|
import { createNodesV2 } from '../../../plugins/plugin';
|
||||||
import { processBuildOptions } from './lib/process-build-options';
|
import { processBuildOptions } from './lib/process-build-options';
|
||||||
import { postTargetTransformer } from './lib/post-target-transformer';
|
import { postTargetTransformer } from './lib/post-target-transformer';
|
||||||
import { processExportOptions } from './lib/process-export-options';
|
import { processExportOptions } from './lib/process-export-options';
|
||||||
@ -29,11 +29,11 @@ export async function convertToInferred(tree: Tree, options: Schema) {
|
|||||||
const projectGraph = await createProjectGraphAsync();
|
const projectGraph = await createProjectGraphAsync();
|
||||||
const migrationLogs = new AggregatedLog();
|
const migrationLogs = new AggregatedLog();
|
||||||
const projects = getProjects(tree);
|
const projects = getProjects(tree);
|
||||||
const migratedProjects = await migrateProjectExecutorsToPluginV1(
|
const migratedProjects = await migrateProjectExecutorsToPlugin(
|
||||||
tree,
|
tree,
|
||||||
projectGraph,
|
projectGraph,
|
||||||
'@nx/expo/plugin',
|
'@nx/expo/plugin',
|
||||||
createNodes,
|
createNodesV2,
|
||||||
{
|
{
|
||||||
buildTargetName: 'build',
|
buildTargetName: 'build',
|
||||||
exportTargetName: 'export',
|
exportTargetName: 'export',
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
export {
|
export {
|
||||||
createNodes,
|
createNodes,
|
||||||
createDependencies,
|
createNodesV2,
|
||||||
ReactNativePluginOptions,
|
ReactNativePluginOptions,
|
||||||
} from './plugins/plugin';
|
} from './plugins/plugin';
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
CreateDependencies,
|
|
||||||
CreateNodes,
|
CreateNodes,
|
||||||
CreateNodesContext,
|
CreateNodesContext,
|
||||||
|
createNodesFromFiles,
|
||||||
|
CreateNodesResult,
|
||||||
|
CreateNodesV2,
|
||||||
detectPackageManager,
|
detectPackageManager,
|
||||||
joinPathFragments,
|
joinPathFragments,
|
||||||
NxJsonConfiguration,
|
NxJsonConfiguration,
|
||||||
@ -16,6 +18,7 @@ import { existsSync, readdirSync } from 'fs';
|
|||||||
import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes';
|
import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes';
|
||||||
import { workspaceDataDirectory } from 'nx/src/utils/cache-directory';
|
import { workspaceDataDirectory } from 'nx/src/utils/cache-directory';
|
||||||
import { loadConfigFile } from '@nx/devkit/src/utils/config-utils';
|
import { loadConfigFile } from '@nx/devkit/src/utils/config-utils';
|
||||||
|
import { hashObject } from 'nx/src/devkit-internals';
|
||||||
|
|
||||||
export interface ReactNativePluginOptions {
|
export interface ReactNativePluginOptions {
|
||||||
startTargetName?: string;
|
startTargetName?: string;
|
||||||
@ -29,70 +32,125 @@ export interface ReactNativePluginOptions {
|
|||||||
upgradeTargetName?: string;
|
upgradeTargetName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cachePath = join(workspaceDataDirectory, 'react-native.hash');
|
function readTargetsCache(
|
||||||
const targetsCache = readTargetsCache();
|
cachePath: string
|
||||||
function readTargetsCache(): Record<
|
): Record<
|
||||||
string,
|
string,
|
||||||
Record<string, TargetConfiguration<ReactNativePluginOptions>>
|
Record<string, TargetConfiguration<ReactNativePluginOptions>>
|
||||||
> {
|
> {
|
||||||
return existsSync(cachePath) ? readJsonFile(cachePath) : {};
|
return existsSync(cachePath) ? readJsonFile(cachePath) : {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeTargetsToCache() {
|
function writeTargetsToCache(
|
||||||
const oldCache = readTargetsCache();
|
cachePath: string,
|
||||||
|
targetsCache: Record<
|
||||||
|
string,
|
||||||
|
Record<string, TargetConfiguration<ReactNativePluginOptions>>
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
const oldCache = readTargetsCache(cachePath);
|
||||||
writeJsonFile(cachePath, {
|
writeJsonFile(cachePath, {
|
||||||
...oldCache,
|
...oldCache,
|
||||||
...targetsCache,
|
targetsCache,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createDependencies: CreateDependencies = () => {
|
export const createNodesV2: CreateNodesV2<ReactNativePluginOptions> = [
|
||||||
writeTargetsToCache();
|
'**/app.{json,config.js,config.ts}',
|
||||||
return [];
|
async (configFiles, options, context) => {
|
||||||
};
|
const optionsHash = hashObject(options);
|
||||||
|
const cachePath = join(workspaceDataDirectory, `expo-${optionsHash}.hash`);
|
||||||
|
const targetsCache = readTargetsCache(cachePath);
|
||||||
|
|
||||||
export const createNodes: CreateNodes<ReactNativePluginOptions> = [
|
try {
|
||||||
'**/app.{json,config.js}',
|
return await createNodesFromFiles(
|
||||||
async (configFilePath, options, context) => {
|
(configFile, options, context) =>
|
||||||
options = normalizeOptions(options);
|
createNodesInternal(configFile, options, context, targetsCache),
|
||||||
const projectRoot = dirname(configFilePath);
|
configFiles,
|
||||||
|
options,
|
||||||
// Do not create a project if package.json or project.json or metro.config.js isn't there.
|
context
|
||||||
const siblingFiles = readdirSync(join(context.workspaceRoot, projectRoot));
|
);
|
||||||
if (
|
} finally {
|
||||||
!siblingFiles.includes('package.json') ||
|
writeTargetsToCache(cachePath, targetsCache);
|
||||||
!siblingFiles.includes('metro.config.js')
|
|
||||||
) {
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
const appConfig = await getAppConfig(configFilePath, context);
|
|
||||||
if (appConfig.expo) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const hash = await calculateHashForCreateNodes(
|
|
||||||
projectRoot,
|
|
||||||
options,
|
|
||||||
context,
|
|
||||||
[getLockFileName(detectPackageManager(context.workspaceRoot))]
|
|
||||||
);
|
|
||||||
|
|
||||||
targetsCache[hash] ??= buildReactNativeTargets(
|
|
||||||
projectRoot,
|
|
||||||
options,
|
|
||||||
context
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
projects: {
|
|
||||||
[projectRoot]: {
|
|
||||||
targets: targetsCache[hash],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const createNodes: CreateNodes<ReactNativePluginOptions> = [
|
||||||
|
'**/app.{json,config.js,config.ts}',
|
||||||
|
async (configFilePath, options, context) => {
|
||||||
|
const optionsHash = hashObject(options);
|
||||||
|
const cachePath = join(
|
||||||
|
workspaceDataDirectory,
|
||||||
|
`react-native-${optionsHash}.hash`
|
||||||
|
);
|
||||||
|
|
||||||
|
const targetsCache = readTargetsCache(cachePath);
|
||||||
|
const result = await createNodesInternal(
|
||||||
|
configFilePath,
|
||||||
|
options,
|
||||||
|
context,
|
||||||
|
targetsCache
|
||||||
|
);
|
||||||
|
|
||||||
|
writeTargetsToCache(cachePath, targetsCache);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
async function createNodesInternal(
|
||||||
|
configFile: string,
|
||||||
|
options: ReactNativePluginOptions,
|
||||||
|
context: CreateNodesContext,
|
||||||
|
targetsCache: Record<
|
||||||
|
string,
|
||||||
|
Record<string, TargetConfiguration<ReactNativePluginOptions>>
|
||||||
|
>
|
||||||
|
): Promise<CreateNodesResult> {
|
||||||
|
options = normalizeOptions(options);
|
||||||
|
const projectRoot = dirname(configFile);
|
||||||
|
|
||||||
|
// Do not create a project if package.json or project.json or metro.config.js isn't there.
|
||||||
|
const siblingFiles = readdirSync(join(context.workspaceRoot, projectRoot));
|
||||||
|
if (
|
||||||
|
!siblingFiles.includes('package.json') ||
|
||||||
|
!siblingFiles.includes('metro.config.js')
|
||||||
|
) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's an Expo project
|
||||||
|
const packageJson = readJsonFile(
|
||||||
|
join(context.workspaceRoot, projectRoot, 'package.json')
|
||||||
|
);
|
||||||
|
const appConfig = await getAppConfig(configFile, context);
|
||||||
|
if (
|
||||||
|
appConfig.expo ||
|
||||||
|
packageJson.dependencies?.['expo'] ||
|
||||||
|
packageJson.devDependencies?.['expo']
|
||||||
|
) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const hash = await calculateHashForCreateNodes(
|
||||||
|
projectRoot,
|
||||||
|
options,
|
||||||
|
context,
|
||||||
|
[getLockFileName(detectPackageManager(context.workspaceRoot))]
|
||||||
|
);
|
||||||
|
|
||||||
|
targetsCache[hash] ??= buildReactNativeTargets(projectRoot, options, context);
|
||||||
|
|
||||||
|
return {
|
||||||
|
projects: {
|
||||||
|
[projectRoot]: {
|
||||||
|
targets: targetsCache[hash],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function buildReactNativeTargets(
|
function buildReactNativeTargets(
|
||||||
projectRoot: string,
|
projectRoot: string,
|
||||||
options: ReactNativePluginOptions,
|
options: ReactNativePluginOptions,
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { createProjectGraphAsync, formatFiles, type Tree } from '@nx/devkit';
|
import { createProjectGraphAsync, formatFiles, type Tree } from '@nx/devkit';
|
||||||
import { AggregatedLog } from '@nx/devkit/src/generators/plugin-migrations/aggregate-log-util';
|
import { AggregatedLog } from '@nx/devkit/src/generators/plugin-migrations/aggregate-log-util';
|
||||||
import {
|
import {
|
||||||
migrateProjectExecutorsToPluginV1,
|
migrateProjectExecutorsToPlugin,
|
||||||
NoTargetsToMigrateError,
|
NoTargetsToMigrateError,
|
||||||
} from '@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator';
|
} from '@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator';
|
||||||
import { createNodes } from '../../../plugins/plugin';
|
import { createNodesV2 } from '../../../plugins/plugin';
|
||||||
import { postTargetTransformer } from './lib/post-target-transformer';
|
import { postTargetTransformer } from './lib/post-target-transformer';
|
||||||
import { processStartOptions } from './lib/process-start-options';
|
import { processStartOptions } from './lib/process-start-options';
|
||||||
import { createProcessOptions } from './lib/create-process-options';
|
import { createProcessOptions } from './lib/create-process-options';
|
||||||
@ -17,11 +17,11 @@ interface Schema {
|
|||||||
export async function convertToInferred(tree: Tree, options: Schema) {
|
export async function convertToInferred(tree: Tree, options: Schema) {
|
||||||
const projectGraph = await createProjectGraphAsync();
|
const projectGraph = await createProjectGraphAsync();
|
||||||
const migrationLogs = new AggregatedLog();
|
const migrationLogs = new AggregatedLog();
|
||||||
const migratedProjects = await migrateProjectExecutorsToPluginV1(
|
const migratedProjects = await migrateProjectExecutorsToPlugin(
|
||||||
tree,
|
tree,
|
||||||
projectGraph,
|
projectGraph,
|
||||||
'@nx/react-native/plugin',
|
'@nx/react-native/plugin',
|
||||||
createNodes,
|
createNodesV2,
|
||||||
{
|
{
|
||||||
buildAndroidTargetName: 'build-android',
|
buildAndroidTargetName: 'build-android',
|
||||||
buildIosTargetName: 'build-ios',
|
buildIosTargetName: 'build-ios',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user