fix(init): consolidate `init-test-app` command (#1563)

Also removed the `@react-native-community/cli` plugin. It wasn't
advertised anywhere and was only used on CI.
This commit is contained in:
Tommy Nguyen 2023-09-04 14:24:45 +00:00 коммит произвёл GitHub
Родитель a89bf578d1
Коммит 7b5a812740
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 128 добавлений и 211 удалений

8
.github/actions/init-test-app/action.yml поставляемый
Просмотреть файл

@ -11,8 +11,12 @@ runs:
run: |
scripts/install-test-template.sh ${{ inputs.platform }}
shell: bash
- name: react-native init-test-app
- name: Initialize a new app
run: |
yarn react-native init-test-app --destination test-app --name TestApp --platform ${{ inputs.platform }}
if [[ ${{ inputs.platform }} == "all" ]]; then
yarn init-test-app --destination test-app --name TestApp -p android -p ios -p macos -p windows
else
yarn init-test-app --destination test-app --name TestApp --platform ${{ inputs.platform }}
fi
shell: bash
working-directory: template-example

Просмотреть файл

@ -49,11 +49,6 @@ describe("react-native config", () => {
name: "react-native-test-app",
}),
}),
commands: expect.arrayContaining([
expect.objectContaining({
name: "init-test-app",
}),
]),
assets: [],
platforms: expect.objectContaining({
android: expect.anything(),
@ -99,11 +94,6 @@ describe("react-native config", () => {
name: "react-native-test-app",
}),
}),
commands: expect.arrayContaining([
expect.objectContaining({
name: "init-test-app",
}),
]),
platforms: expect.objectContaining({
android: expect.anything(),
}),
@ -131,11 +121,6 @@ describe("react-native config", () => {
name: "react-native-test-app",
}),
}),
commands: expect.arrayContaining([
expect.objectContaining({
name: "init-test-app",
}),
]),
assets: [],
platforms: expect.objectContaining({
ios: expect.anything(),
@ -167,11 +152,6 @@ describe("react-native config", () => {
name: "react-native-test-app",
}),
}),
commands: expect.arrayContaining([
expect.objectContaining({
name: "init-test-app",
}),
]),
platforms: expect.objectContaining({
ios: expect.anything(),
}),
@ -209,11 +189,6 @@ describe("react-native config", () => {
name: "react-native-test-app",
}),
}),
commands: expect.arrayContaining([
expect.objectContaining({
name: "init-test-app",
}),
]),
platforms: expect.objectContaining({
windows: expect.objectContaining({
npmPackageName: "react-native-windows",

Просмотреть файл

@ -1,116 +1,4 @@
// @ts-check
"use strict";
const {
findNearest,
getPackageVersion,
readJSONFile,
} = require("./scripts/helpers");
/**
* @typedef {import("./scripts/configure").Platform} Platform;
*/
/**
* @template Args
* @typedef {{
* name: string,
* description?: string,
* examples?: Array<{
* desc: string;
* cmd: string;
* }>,
* func: (argv: Array<string>, config: {}, args: Args) => void | Promise<void>,
* options?: Array<{
* name: string;
* description?: string;
* parse?: (val: string) => any;
* default?: string | number | boolean;
* }>,
* }} Command;
*/
/**
* Infers project name by finding and parsing the nearest `package.json`.
* @returns {string | undefined}
*/
function inferProjectName() {
const packageJson = findNearest("package.json");
if (packageJson) {
try {
const name = readJSONFile(packageJson)["name"];
return typeof name === "string" && name ? `${name}-test-app` : undefined;
} catch (_) {
// Ignore
}
}
return undefined;
}
/**
* @param {string} choice
* @returns {Platform[]}
*/
function sanitizePlatformChoice(choice) {
/** @type {Set<Platform>} */
const platforms = new Set();
for (const platform of choice.split(",")) {
switch (platform) {
case "all":
return ["android", "ios", "macos", "windows"];
case "android":
case "ios":
case "macos":
case "windows":
platforms.add(platform);
continue;
default:
throw new Error(`Unknown platform: ${platform}`);
}
}
return Array.from(platforms);
}
/** @type {{ commands: Command<{ destination: string; name: string; platform: string; }>[] }} */
module.exports = {
commands: [
{
name: "init-test-app",
description: "Initializes a new test app project",
func: (_argv, _config, { destination, name, platform }) => {
const { configure } = require("./scripts/configure");
configure({
name,
packagePath: destination,
testAppPath: __dirname,
targetVersion: getPackageVersion("react-native"),
platforms: sanitizePlatformChoice(platform),
flatten: true,
force: true,
init: true,
});
},
options: [
{
name: "--destination [string]",
description:
"Path to the directory where the test app should be created",
default: require("path").join(process.cwd(), "test-app"),
},
{
name: "--name [string]",
description: "Display name of the test app",
default: inferProjectName() || "ReactTestApp",
},
{
name: "--platform [string]",
description:
"Specific platform to support: all, android, ios, macos, windows",
default: "all",
},
],
},
],
dependency: {
platforms: {
windows: null,

Просмотреть файл

@ -472,10 +472,16 @@ const getConfig = (() => {
typeof configuration === "undefined" ||
"JEST_WORKER_ID" in process.env // skip caching when testing
) {
// Git ignore files are only renamed when published. `GIT_IGNORE_FILE`
// should therefore only be set during testing.
const gitignore = process.env["GIT_IGNORE_FILE"] || "_gitignore";
const { name, templatePath, testAppPath, flatten, init } = params;
// `.gitignore` files are only renamed when published.
const gitignore = ["_gitignore", ".gitignore"].find((filename) => {
return fs.existsSync(path.join(testAppPath, "example", filename));
});
if (!gitignore) {
throw new Error("Failed to find `.gitignore`");
}
const projectPathFlag =
flatten && packageSatisfiesVersionRange(cliPlatformIOS, "<8.0.0")
? " --project-path ."
@ -487,6 +493,7 @@ const getConfig = (() => {
process.cwd(),
path.dirname(require.resolve("react-native/template/package.json"))
);
configuration = {
common: {
files: {

Просмотреть файл

@ -197,7 +197,37 @@ function getTemplate(platforms) {
});
}
async function main() {
function main() {
return new Promise((resolve) => {
const { parseArgs } = require("./parseargs");
parseArgs(
"Initializes a new app project from template",
{
name: {
description: "Name of the app",
type: "string",
},
platform: {
description:
"Platform to configure; can be specified multiple times e.g., `-p android -p ios`",
type: "string",
multiple: true,
short: "p",
},
destination: {
description: "Destination path for the app",
type: "string",
},
},
async (args) => {
const prompts = require("prompts");
prompts.override({
name: args.name,
platforms:
typeof args.platform === "string" ? [args.platform] : args.platform,
packagePath: args.destination,
});
/**
* @type {{
* name?: string;
@ -205,7 +235,7 @@ async function main() {
* platforms?: import("./configure").Platform[];
* }}
*/
const { name, packagePath, platforms } = await require("prompts")([
const { name, packagePath, platforms } = await prompts([
{
type: "text",
name: "name",
@ -235,13 +265,14 @@ async function main() {
]);
if (!name || !packagePath || !platforms) {
return 1;
resolve(1);
return;
}
const { configure } = require("./configure");
const [targetVersion, templatePath] = await getTemplate(platforms);
return configure({
const result = configure({
name,
packagePath,
templatePath,
@ -252,6 +283,11 @@ async function main() {
force: true,
init: true,
});
resolve(result);
}
);
});
}
main().then((result) => {

Просмотреть файл

@ -37,7 +37,20 @@ npm pack
mv react-native-test-app-$version.tgz $tarball
yarn
GIT_IGNORE_FILE=".gitignore" yarn react-native init-test-app --destination template-example --name TemplateExample --platform "$platform"
if [[ "$platform" == "all" ]]; then
yarn init-test-app \
--destination template-example \
--name TemplateExample \
--platform android \
--platform ios \
--platform macos \
--platform windows
else
yarn init-test-app \
--destination template-example \
--name TemplateExample \
--platform "$platform"
fi
pushd template-example 1> /dev/null
node ../scripts/copy-yarnrc.mjs ../.yarnrc.yml

Просмотреть файл

@ -1,8 +1,6 @@
#!/bin/bash
set -eo pipefail
export GIT_IGNORE_FILE=".gitignore"
PACKAGE_MANAGER=yarn
VERSION=${1}
@ -166,7 +164,8 @@ echo "│ Initialize new app │"
echo "└─────────────────────┘"
echo
${PACKAGE_MANAGER} react-native init-test-app \
${PACKAGE_MANAGER} init-test-app \
--destination template-example \
--name TemplateExample \
--platform android,ios
--platform android \
--platform ios

Просмотреть файл

@ -44,12 +44,7 @@ describe("test-app-util", () => {
return Number(major) * 10000 + Number(minor) * 100 + Number(patch);
}
beforeAll(() => {
process.env["GIT_IGNORE_FILE"] = ".gitignore";
});
afterAll(() => {
delete process.env["GIT_IGNORE_FILE"];
removeProject(defaultTestProject);
});

Просмотреть файл

@ -5,7 +5,7 @@ exports[`gatherConfig() flattens configuration for a single platform only 1`] =
"dependencies": {},
"files": {
".gitignore": {
"source": "example/_gitignore",
"source": "example/.gitignore",
},
".watchmanconfig": {
"source": "node_modules/react-native/template/_watchmanconfig",
@ -61,7 +61,7 @@ exports[`gatherConfig() flattens configuration for a single platform only 2`] =
"dependencies": {},
"files": {
".gitignore": {
"source": "example/_gitignore",
"source": "example/.gitignore",
},
".watchmanconfig": {
"source": "node_modules/react-native/template/_watchmanconfig",
@ -181,7 +181,7 @@ exports[`gatherConfig() returns common configuration 1`] = `
"dependencies": {},
"files": {
".gitignore": {
"source": "example/_gitignore",
"source": "example/.gitignore",
},
".watchmanconfig": {
"source": "node_modules/react-native/template/_watchmanconfig",
@ -190,7 +190,7 @@ exports[`gatherConfig() returns common configuration 1`] = `
"source": "node_modules/react-native/template/babel.config.js",
},
"common/.gitignore": {
"source": "example/_gitignore",
"source": "example/.gitignore",
},
"common/.watchmanconfig": {
"source": "node_modules/react-native/template/_watchmanconfig",
@ -265,7 +265,7 @@ exports[`gatherConfig() returns configuration for a single platform 1`] = `
"dependencies": {},
"files": {
".gitignore": {
"source": "example/_gitignore",
"source": "example/.gitignore",
},
".watchmanconfig": {
"source": "node_modules/react-native/template/_watchmanconfig",
@ -331,7 +331,7 @@ exports[`gatherConfig() returns configuration for all platforms 1`] = `
},
"files": {
".gitignore": {
"source": "example/_gitignore",
"source": "example/.gitignore",
},
".watchmanconfig": {
"source": "node_modules/react-native/template/_watchmanconfig",
@ -436,7 +436,7 @@ module.exports = {
};
",
"windows/.gitignore": {
"source": "example/windows/_gitignore",
"source": "example/windows/.gitignore",
},
},
"oldFiles": [
@ -471,7 +471,7 @@ exports[`gatherConfig() returns configuration for arbitrary platforms 1`] = `
"dependencies": {},
"files": {
".gitignore": {
"source": "example/_gitignore",
"source": "example/.gitignore",
},
".watchmanconfig": {
"source": "node_modules/react-native/template/_watchmanconfig",