Skip to content

Commit 3a90a9a

Browse files
huntiefacebook-github-bot
authored andcommitted
Move codegen and spm command wrappers into community-cli-plugin (#57652)
Summary: Migrate the `codegen` and `spm` command implementations out of `react-native.config.js` and into the `react-native/community-cli-plugin` package, alongside the existing `bundleCommand` and `startCommand`. This continues moving command definitions into the plugin so `react-native.config.js` becomes a thin routing layer, as the file's own comment already calls for. **Changes** - Add `src/commands/spm/index.js` and `src/commands/codegen/index.js`, each defining and default-exporting its command (unchanged `name`, `description`, and `options`) plus an exported args type — mirroring the `bundle`/`start` command structure. - Export `spmCommand` and `codegenCommand` from `src/index.flow.js`. - Drop the inline `spmCommand` and `codegenCommand` definitions from `react-native.config.js`. - Add docs to README. Changelog: [Internal] Differential Revision: D113412987
1 parent 08ab5e1 commit 3a90a9a

5 files changed

Lines changed: 235 additions & 122 deletions

File tree

packages/community-cli-plugin/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,48 @@ npx @react-native-community/cli bundle --entry-file <path> [options]
7575
| `--read-global-cache` | Attempt to fetch transformed JS code from the global cache, if configured. Defaults to `false`. |
7676
| `--config <string>` | Path to the CLI configuration file. |
7777

78+
### `codegen`
79+
80+
Run the React Native codegen, generating native boilerplate from JS spec files.
81+
82+
#### Usage
83+
84+
```sh
85+
npx @react-native-community/cli codegen [options]
86+
```
87+
88+
#### Options
89+
90+
| Option | Description |
91+
| - | - |
92+
| `--path <path>` | Path to the React Native project root. Defaults to the current working directory. |
93+
| `--platform <string>` | Target platform. Supported values: `"android"`, `"ios"`, `"all"`. Defaults to `"all"`. |
94+
| `--outputPath <path>` | Path where generated artifacts will be output to. |
95+
| `--source <string>` | Whether the script is invoked from an `app` or a `library`. Defaults to `"app"`. |
96+
97+
### `spm [action]`
98+
99+
Set up or maintain Swift Package Manager support for the iOS/macOS app. Actions: `add`, `update`, `deinit`, `scaffold`. With no action: `add` (or `update` if SPM is already set up).
100+
101+
#### Usage
102+
103+
```sh
104+
npx @react-native-community/cli spm [action] [options]
105+
```
106+
107+
#### Options
108+
109+
| Option | Description |
110+
| - | - |
111+
| `--version <string>` | React Native version (e.g. `0.80.0`). Defaults to the version in `node_modules/react-native/package.json`. |
112+
| `--yes` | Skip the dirty-pbxproj confirmation prompt. |
113+
| `--xcodeproj <path>` | **[add]** Path to the `.xcodeproj` to inject SPM packages into (disambiguates when several exist). |
114+
| `--productName <string>` | **[add]** App target to inject into (disambiguates when several exist). |
115+
| `--deintegrate` | **[add]** Run `pod deintegrate` and strip React Native from the Podfile before injecting (CocoaPods → SwiftPM migration). |
116+
| `--artifacts <path>` | **[advanced]** Local artifact root containing complete `debug/` and `release/` slots. |
117+
| `--download <string>` | **[advanced]** Artifact download policy: `auto` (default), `skip`, or `force`. |
118+
| `--skipCodegen` | **[advanced]** Skip the react-native codegen step. |
119+
78120
## Contributing
79121

80122
Changes to this package can be made locally and tested against the `rn-tester` app, per the [Contributing guide](https://reactnative.dev/contributing/overview#contributing-code). During development, this package is automatically run from source with no build step.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
8+
* @format
9+
*/
10+
11+
import type {Command, Config} from '@react-native-community/cli-types';
12+
13+
export type CodegenCommandArgs = {
14+
path: string,
15+
platform: string,
16+
outputPath?: string,
17+
source: string,
18+
};
19+
20+
const codegenCommand: Command = {
21+
name: 'codegen',
22+
options: [
23+
{
24+
name: '--path <path>',
25+
description: 'Path to the React Native project root.',
26+
default: process.cwd(),
27+
},
28+
{
29+
name: '--platform <string>',
30+
description:
31+
'Target platform. Supported values: "android", "ios", "all".',
32+
default: 'all',
33+
},
34+
{
35+
name: '--outputPath <path>',
36+
description: 'Path where generated artifacts will be output to.',
37+
},
38+
{
39+
name: '--source <string>',
40+
description: 'Whether the script is invoked from an `app` or a `library`',
41+
default: 'app',
42+
},
43+
],
44+
func: (
45+
argv: Array<string>,
46+
config: Config,
47+
args: CodegenCommandArgs,
48+
): void => {
49+
const generateArtifactsExecutor = require.resolve(
50+
'react-native/scripts/codegen/generate-artifacts-executor',
51+
{paths: [config.root]},
52+
);
53+
// $FlowFixMe[unsupported-syntax] dynamic require of a resolved path
54+
require(generateArtifactsExecutor).execute(
55+
args.path,
56+
args.platform,
57+
args.outputPath,
58+
args.source,
59+
);
60+
},
61+
};
62+
63+
export default codegenCommand;
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
8+
* @format
9+
*/
10+
11+
import type {Command, Config} from '@react-native-community/cli-types';
12+
13+
export type SpmCommandArgs = {
14+
version?: string,
15+
yes?: boolean,
16+
xcodeproj?: string,
17+
productName?: string,
18+
deintegrate?: boolean,
19+
artifacts?: string,
20+
download?: string,
21+
skipCodegen?: boolean,
22+
};
23+
24+
const spmCommand: Command = {
25+
name: 'spm [action]',
26+
description:
27+
'Set up or maintain Swift Package Manager support for the iOS/macOS app. ' +
28+
'Actions: add, update, deinit, scaffold. With no action: add (or update ' +
29+
'if SPM is already set up).',
30+
options: [
31+
{
32+
name: '--version <string>',
33+
description:
34+
'React Native version (e.g. 0.80.0). Defaults to the version in node_modules/react-native/package.json.',
35+
},
36+
{
37+
name: '--yes',
38+
description: 'Skip the dirty-pbxproj confirmation prompt.',
39+
},
40+
{
41+
name: '--xcodeproj <path>',
42+
description:
43+
'[add] Path to the .xcodeproj to inject SPM packages into ' +
44+
'(disambiguates when several exist).',
45+
},
46+
{
47+
name: '--productName <string>',
48+
description:
49+
'[add] App target to inject into (disambiguates when several exist).',
50+
},
51+
{
52+
name: '--deintegrate',
53+
description:
54+
'[add] Run `pod deintegrate` and strip React Native from the Podfile ' +
55+
'before injecting (CocoaPods → SwiftPM migration).',
56+
},
57+
{
58+
name: '--artifacts <path>',
59+
description:
60+
'[advanced] Local artifact root containing complete debug/ and release/ slots.',
61+
},
62+
{
63+
name: '--download <string>',
64+
description:
65+
'[advanced] Artifact download policy: auto (default), skip, or force.',
66+
},
67+
{
68+
name: '--skipCodegen',
69+
description: '[advanced] Skip the react-native codegen step.',
70+
},
71+
],
72+
func: async (
73+
argv: Array<string>,
74+
config: Config,
75+
args: SpmCommandArgs,
76+
): Promise<void> => {
77+
const passthrough: Array<string> = [];
78+
if (argv[0] != null) {
79+
passthrough.push(argv[0]);
80+
}
81+
const stringOpts: Array<
82+
[
83+
'version' | 'productName' | 'xcodeproj' | 'artifacts' | 'download',
84+
string,
85+
],
86+
> = [
87+
['version', '--version'],
88+
['productName', '--product-name'],
89+
['xcodeproj', '--xcodeproj'],
90+
['artifacts', '--artifacts'],
91+
['download', '--download'],
92+
];
93+
for (const [key, flag] of stringOpts) {
94+
const value = args[key];
95+
if (value != null) {
96+
passthrough.push(flag, String(value));
97+
}
98+
}
99+
const boolOpts: Array<['skipCodegen' | 'deintegrate' | 'yes', string]> = [
100+
['skipCodegen', '--skip-codegen'],
101+
['deintegrate', '--deintegrate'],
102+
['yes', '--yes'],
103+
];
104+
for (const [key, flag] of boolOpts) {
105+
if (args[key] === true) {
106+
passthrough.push(flag);
107+
}
108+
}
109+
const setupAppleSpm = require.resolve(
110+
'react-native/scripts/setup-apple-spm',
111+
{paths: [config.root]},
112+
);
113+
// $FlowFixMe[unsupported-syntax] dynamic require of a resolved path
114+
await require(setupAppleSpm).main(passthrough);
115+
},
116+
};
117+
118+
export default spmCommand;

packages/community-cli-plugin/src/index.flow.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export {
1212
default as bundleCommand,
1313
unstable_createBundleCommandParser,
1414
} from './commands/bundle';
15+
export {default as codegenCommand} from './commands/codegen';
16+
export {default as spmCommand} from './commands/spm';
1517
export {default as startCommand} from './commands/start';
1618

1719
export {unstable_buildBundleWithConfig} from './commands/bundle/buildBundle';

packages/react-native/react-native.config.js

Lines changed: 10 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@
1414
import type {Command} from '@react-native-community/cli-types';
1515
*/
1616

17-
// React Native shouldn't be exporting itself like this, the Community Template should be be directly
18-
// depending on and injecting:
17+
// IMPORTANT: This is a routing file only. Do NOT add new command
18+
// definitions or implementations here.
19+
//
20+
// New CLI commands belong in @react-native/community-cli-plugin, and
21+
// may (temporarily) be imported and registered here.
22+
//
23+
// Future state: The Community Template should directly depend on and inject:
1924
// - @react-native-community/cli-platform-android
2025
// - @react-native-community/cli-platform-ios
2126
// - @react-native/community-cli-plugin
22-
// - codegen command should be inhoused into @react-native-community/cli
23-
//
24-
// This is a temporary workaround.
2527

2628
const verbose = Boolean(process.env.DEBUG?.includes('react-native'));
2729

@@ -72,126 +74,12 @@ const commands /*: Array<Command> */ = [];
7274

7375
const {
7476
bundleCommand,
77+
codegenCommand,
78+
spmCommand,
7579
startCommand,
7680
} = require('@react-native/community-cli-plugin');
7781

78-
commands.push(bundleCommand, startCommand);
79-
80-
const codegenCommand /*: Command */ = {
81-
name: 'codegen',
82-
options: [
83-
{
84-
name: '--path <path>',
85-
description: 'Path to the React Native project root.',
86-
default: process.cwd(),
87-
},
88-
{
89-
name: '--platform <string>',
90-
description:
91-
'Target platform. Supported values: "android", "ios", "all".',
92-
default: 'all',
93-
},
94-
{
95-
name: '--outputPath <path>',
96-
description: 'Path where generated artifacts will be output to.',
97-
},
98-
{
99-
name: '--source <string>',
100-
description: 'Whether the script is invoked from an `app` or a `library`',
101-
default: 'app',
102-
},
103-
],
104-
func: (argv, config, args) =>
105-
require('./scripts/codegen/generate-artifacts-executor').execute(
106-
args.path,
107-
args.platform,
108-
args.outputPath,
109-
args.source,
110-
),
111-
};
112-
113-
commands.push(codegenCommand);
114-
115-
const spmCommand /*: Command */ = {
116-
name: 'spm [action]',
117-
description:
118-
'Set up or maintain Swift Package Manager support for the iOS/macOS app. ' +
119-
'Actions: add, update, deinit, scaffold. With no action: add (or update ' +
120-
'if SPM is already set up).',
121-
options: [
122-
{
123-
name: '--version <string>',
124-
description:
125-
'React Native version (e.g. 0.80.0). Defaults to the version in node_modules/react-native/package.json.',
126-
},
127-
{
128-
name: '--yes',
129-
description: 'Skip the dirty-pbxproj confirmation prompt.',
130-
},
131-
{
132-
name: '--xcodeproj <path>',
133-
description:
134-
'[add] Path to the .xcodeproj to inject SPM packages into ' +
135-
'(disambiguates when several exist).',
136-
},
137-
{
138-
name: '--productName <string>',
139-
description:
140-
'[add] App target to inject into (disambiguates when several exist).',
141-
},
142-
{
143-
name: '--deintegrate',
144-
description:
145-
'[add] Run `pod deintegrate` and strip React Native from the Podfile ' +
146-
'before injecting (CocoaPods → SwiftPM migration).',
147-
},
148-
{
149-
name: '--artifacts <path>',
150-
description:
151-
'[advanced] Local artifact root containing complete debug/ and release/ slots.',
152-
},
153-
{
154-
name: '--download <string>',
155-
description:
156-
'[advanced] Artifact download policy: auto (default), skip, or force.',
157-
},
158-
{
159-
name: '--skipCodegen',
160-
description: '[advanced] Skip the react-native codegen step.',
161-
},
162-
],
163-
func: async (argv, _config, args) => {
164-
const passthrough /*: Array<string> */ = [];
165-
if (argv[0] != null) {
166-
passthrough.push(argv[0]);
167-
}
168-
const stringOpts /*: Array<[string, string]> */ = [
169-
['version', '--version'],
170-
['productName', '--product-name'],
171-
['xcodeproj', '--xcodeproj'],
172-
['artifacts', '--artifacts'],
173-
['download', '--download'],
174-
];
175-
for (const [key, flag] of stringOpts) {
176-
if (args[key] != null) {
177-
passthrough.push(flag, String(args[key]));
178-
}
179-
}
180-
const boolOpts /*: Array<[string, string]> */ = [
181-
['skipCodegen', '--skip-codegen'],
182-
['deintegrate', '--deintegrate'],
183-
['yes', '--yes'],
184-
];
185-
for (const [key, flag] of boolOpts) {
186-
if (args[key]) {
187-
passthrough.push(flag);
188-
}
189-
}
190-
await require('./scripts/setup-apple-spm').main(passthrough);
191-
},
192-
};
193-
194-
commands.push(spmCommand);
82+
commands.push(bundleCommand, startCommand, spmCommand, codegenCommand);
19583

19684
const config = {
19785
commands,

0 commit comments

Comments
 (0)