feat(react-native): add upgrade-native generator to upgrade native code (#9925)

This commit is contained in:
Emily Xiong 2022-04-26 14:31:59 -04:00 committed by GitHub
parent 4d17b3275e
commit 6e72dc6c12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 224 additions and 2 deletions

View File

@ -429,6 +429,47 @@
"implementation": "/packages/react-native/src/generators/stories/stories#storiesGenerator.ts",
"aliases": [],
"path": "/packages/react-native/src/generators/stories/schema.json"
},
{
"name": "upgrade-native",
"factory": "./src/generators/upgrade-native/upgrade-native#reactNativeUpgradeNativeGenerator",
"schema": {
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "NxReactNativeUpgradeNativeConfigure",
"title": "React native upgrade native configuration",
"description": "Upgrade native iOS and Android code to latest.",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Project name.",
"$default": { "$source": "argv", "index": 0 }
},
"displayName": {
"description": "The display name to show in the application. Defaults to name.",
"type": "string"
},
"js": {
"type": "boolean",
"description": "Generate JavaScript files rather than TypeScript files",
"default": false
},
"e2eTestRunner": {
"description": "Adds the specified e2e test runner.",
"type": "string",
"enum": ["detox", "none"],
"default": "detox"
}
},
"required": ["name"],
"presets": []
},
"description": "Destructive command to upgrade native iOS and Android code to latest.",
"hidden": false,
"implementation": "/packages/react-native/src/generators/upgrade-native/upgrade-native#reactNativeUpgradeNativeGenerator.ts",
"aliases": [],
"path": "/packages/react-native/src/generators/upgrade-native/schema.json"
}
],
"executors": [

View File

@ -230,7 +230,8 @@
"component",
"storybook-configuration",
"component-story",
"stories"
"stories",
"upgrade-native"
]
}
},

View File

@ -46,6 +46,12 @@
"schema": "./src/generators/stories/schema.json",
"description": "Create stories for all components declared in an application or library.",
"hidden": false
},
"upgrade-native": {
"factory": "./src/generators/upgrade-native/upgrade-native#reactNativeUpgradeNativeSchematic",
"schema": "./src/generators/upgrade-native/schema.json",
"description": "Destructive command to upgrade native iOS and Android code to latest.",
"hidden": false
}
},
"generators": {
@ -92,6 +98,12 @@
"schema": "./src/generators/stories/schema.json",
"description": "Create stories/specs for all components declared in an application or library.",
"hidden": false
},
"upgrade-native": {
"factory": "./src/generators/upgrade-native/upgrade-native#reactNativeUpgradeNativeGenerator",
"schema": "./src/generators/upgrade-native/schema.json",
"description": "Destructive command to upgrade native iOS and Android code to latest.",
"hidden": false
}
}
}

View File

@ -1,4 +1,4 @@
import { names, Tree } from '@nrwl/devkit';
import { names } from '@nrwl/devkit';
import { join } from 'path';
import { Schema } from '../schema';

View File

@ -0,0 +1,30 @@
import { generateFiles, joinPathFragments, Tree } from '@nrwl/devkit';
import { join } from 'path';
import { normalizeOptions } from './normalize-options';
import { UpgradeNativeConfigureSchema } from '../schema';
export function createNativeFiles(
host: Tree,
schema: UpgradeNativeConfigureSchema,
root: string
) {
const options = normalizeOptions(schema);
const iosProjectRoot = joinPathFragments(root, 'ios');
const androidProjectRoot = joinPathFragments(root, 'android');
generateFiles(
host,
join(__dirname, '../../application/files/app/ios'),
iosProjectRoot,
options
);
generateFiles(
host,
join(__dirname, '../../application/files/app/android'),
androidProjectRoot,
options
);
}

View File

@ -0,0 +1,37 @@
import { names } from '@nrwl/devkit';
import { UpgradeNativeConfigureSchema } from '../schema';
export interface NormalizedSchema {
name: string;
displayName: string;
className: string;
lowerCaseName: string;
entryFile: string;
entryFileIos: string;
e2eTestRunner: 'detox' | 'none';
}
export function normalizeOptions(
options: UpgradeNativeConfigureSchema
): NormalizedSchema {
const { fileName, className } = names(options.name);
const entryFileIos = 'src/main';
const entryFile = options.js ? 'src/main.js' : 'src/main.tsx';
/**
* if options.name is "my-app"
* name: "my-app", className: 'MyApp', lowerCaseName: 'myapp', displayName: 'MyApp'
* if options.name is "myApp"
* name: "my-app", className: 'MyApp', lowerCaseName: 'myapp', displayName: 'MyApp'
*/
return {
name: fileName,
className,
lowerCaseName: className.toLowerCase(),
displayName: options.displayName || className,
entryFile,
entryFileIos,
e2eTestRunner: options.e2eTestRunner,
};
}

View File

@ -0,0 +1,8 @@
import { Linter } from '@nrwl/linter';
export interface UpgradeNativeConfigureSchema {
name: string;
displayName?: string;
js: boolean; // default is false
e2eTestRunner: 'detox' | 'none'; // default is detox
}

View File

@ -0,0 +1,34 @@
{
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "NxReactNativeUpgradeNativeConfigure",
"title": "React native upgrade native configuration",
"description": "Upgrade native iOS and Android code to latest.",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Project name.",
"$default": {
"$source": "argv",
"index": 0
}
},
"displayName": {
"description": "The display name to show in the application. Defaults to name.",
"type": "string"
},
"js": {
"type": "boolean",
"description": "Generate JavaScript files rather than TypeScript files",
"default": false
},
"e2eTestRunner": {
"description": "Adds the specified e2e test runner.",
"type": "string",
"enum": ["detox", "none"],
"default": "detox"
}
},
"required": ["name"]
}

View File

@ -0,0 +1,59 @@
/**
* This function is a destructive command that replace React Native iOS and Android code with latest.
* It would replace the Android and iOS folder entirely.
*/
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { UpgradeNativeConfigureSchema } from './schema';
import {
convertNxGenerator,
Tree,
joinPathFragments,
GeneratorCallback,
readProjectConfiguration,
} from '@nrwl/devkit';
import { join } from 'path';
import { createNativeFiles } from './lib/create-native-files';
import { existsSync, removeSync } from 'fs-extra';
import { runPodInstall } from '../../utils/pod-install-task';
import { runChmod } from '../../utils/chmod-task';
export async function reactNativeUpgradeNativeGenerator(
host: Tree,
schema: UpgradeNativeConfigureSchema
): Promise<GeneratorCallback> {
const { projectType, root } = readProjectConfiguration(host, schema.name);
const iosProjectRoot = joinPathFragments(host.root, root, 'ios');
const androidProjectRoot = joinPathFragments(host.root, root, 'android');
if (
projectType !== 'application' ||
!existsSync(iosProjectRoot) ||
!existsSync(androidProjectRoot)
) {
throw new Error(`Could not upgrade React Native code for ${schema.name}`);
}
removeSync(iosProjectRoot);
removeSync(androidProjectRoot);
createNativeFiles(host, schema, root);
const podInstallTask = runPodInstall(iosProjectRoot);
const chmodTaskGradlew = runChmod(join(androidProjectRoot, 'gradlew'), 0o775);
const chmodTaskGradlewBat = runChmod(
join(androidProjectRoot, 'gradlew.bat'),
0o775
);
return runTasksInSerial(
podInstallTask,
chmodTaskGradlew,
chmodTaskGradlewBat
);
}
export default reactNativeUpgradeNativeGenerator;
export const reactNativeUpgradeNativeSchematic = convertNxGenerator(
reactNativeUpgradeNativeGenerator
);