diff --git a/__e2e__/init.test.ts b/__e2e__/init.test.ts index 620dfb325..d5c4391cc 100644 --- a/__e2e__/init.test.ts +++ b/__e2e__/init.test.ts @@ -168,3 +168,29 @@ test('init uses npm as the package manager with --npm', () => { expect(fs.existsSync(path.join(initDirPath, file))).toBe(true); }); }); + +test('init --platform-name should work for out of tree platform', () => { + createCustomTemplateFiles(); + const outOfTreePlatformName = 'react-native-macos'; + + const {stdout} = runCLI(DIR, [ + 'init', + PROJECT_NAME, + '--platform-name', + outOfTreePlatformName, + '--skip-install', + '--verbose', + ]); + + expect(stdout).toContain('Run instructions'); + expect(stdout).toContain( + `Installing template from ${outOfTreePlatformName}@latest`, + ); + + // make sure we don't leave garbage + expect(fs.readdirSync(DIR)).toContain('custom'); + + let dirFiles = fs.readdirSync(path.join(DIR, PROJECT_NAME)); + + expect(dirFiles.length).toBeGreaterThan(0); +}); diff --git a/packages/cli/src/commands/init/index.ts b/packages/cli/src/commands/init/index.ts index be2aaee2f..f693120ec 100644 --- a/packages/cli/src/commands/init/index.ts +++ b/packages/cli/src/commands/init/index.ts @@ -47,5 +47,10 @@ export default { description: 'Inits a project with a custom package name (Android) and bundle ID (iOS), e.g. com.example.app', }, + { + name: '--platform-name ', + description: + 'Name of out of tree platform to be used for ex. react-native-macos. This flag is optional as it should be passed automatically by out of tree platform. It needs to match the name of the platform declared in package.json', + }, ], }; diff --git a/packages/cli/src/commands/init/init.ts b/packages/cli/src/commands/init/init.ts index 9fa46837c..848885b34 100644 --- a/packages/cli/src/commands/init/init.ts +++ b/packages/cli/src/commands/init/init.ts @@ -44,6 +44,7 @@ type Options = { version?: string; packageName?: string; installPods?: string | boolean; + platformName?: string; }; interface TemplateOptions { @@ -261,14 +262,17 @@ function createTemplateUri(options: Options, version: string): string { const isTypescriptTemplate = options.template === 'react-native-template-typescript'; + // This allows to correctly retrieve template uri for out of tree platforms. + const platform = options.platformName || 'react-native'; + if (isTypescriptTemplate) { logger.warn( "Ignoring custom template: 'react-native-template-typescript'. Starting from React Native v0.71 TypeScript is used by default.", ); - return 'react-native'; + return platform; } - return options.template || `react-native@${version}`; + return options.template || `${platform}@${version}`; } //remove quotes from object keys to match the linter rules of the template diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index de74e82df..2f973f307 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -134,15 +134,16 @@ function attachCommand>( } } -async function run() { +// Platform name is optional argument passed by out of tree platforms. +async function run(platformName?: string) { try { - await setupAndRun(); + await setupAndRun(platformName); } catch (e) { handleError(e as Error); } } -async function setupAndRun() { +async function setupAndRun(platformName?: string) { // Commander is not available yet // when we run `config`, we don't want to output anything to the console. We @@ -210,7 +211,14 @@ async function setupAndRun() { } } - program.parse(process.argv); + const argv = [...process.argv]; + + // If out of tree platform specifices custom platform name by passing it to , we need to pass it to argv array. + if (platformName) { + argv.push('--platform-name', platformName); + } + + program.parse(argv); } const bin = require.resolve('./bin');