@react-native/core-cli-utils 0.75.0-main

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # @react-native/core-cli-utils
2
+
3
+ ![npm package](https://img.shields.io/npm/v/@react-native/core-cli-utils?color=brightgreen&label=npm%20package)
4
+
5
+ A collection of utilites to help Frameworks build their React Native CLI tooling. This is not intended to be used directly use users of React Native.
6
+
7
+ ## Usage
8
+
9
+ ```js
10
+ import { Command } from 'commander';
11
+ import cli from '@react-native/core-cli-utils';
12
+ import debug from 'debug';
13
+
14
+ const android = new Command('android');
15
+
16
+ const frameworkFindsAndroidSrcDir = "...";
17
+ const tasks = cli.clean.android(frameworkFindsAndroidSrcDir);
18
+ const log = debug('fancy-framework:android');
19
+
20
+ android
21
+ .command('clean')
22
+ .description(cli.clean.android)
23
+ .action(async () => {
24
+ const log = debug('fancy-framework:android:clean');
25
+ log(`🧹 let me clean your Android caches`);
26
+ // Add other caches your framework needs besides the normal React Native caches
27
+ // here.
28
+ for (const task of tasks) {
29
+ try {
30
+ log(`\t ${task.label}`);
31
+ // See: https://github.com/sindresorhus/execa#lines
32
+ const {stdout} = await task.action({ lines: true })
33
+ log(stdout.join('\n\tGradle: '));
34
+ } catch (e) {
35
+ log(`\t ⚠️ whoops: ${e.message}`);
36
+ }
37
+ }
38
+ });
39
+ ```
40
+
41
+ And you'd be using it like this:
42
+
43
+ ```bash
44
+ $ ./fancy-framework android clean
45
+ 🧹 let me clean your Android caches
46
+ Gradle: // a bunch of gradle output
47
+ Gradle: ....
48
+ ```
49
+
50
+ ## Contributing
51
+
52
+ Changes to this package can be made locally and linked against your app. Please see the [Contributing guide](https://reactnative.dev/contributing/overview#contributing-code).
@@ -0,0 +1,20 @@
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
+ *
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ import { tasks as android } from "./private/android.js";
13
+ import { tasks as apple } from "./private/apple.js";
14
+ import { tasks as clean } from "./private/clean.js";
15
+ declare const $$EXPORT_DEFAULT_DECLARATION$$: {
16
+ android: android;
17
+ apple: apple;
18
+ clean: clean;
19
+ };
20
+ export default $$EXPORT_DEFAULT_DECLARATION$$;
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true,
5
+ });
6
+ exports.default = void 0;
7
+ var _android = require("./private/android.js");
8
+ var _apple = require("./private/apple.js");
9
+ var _clean = require("./private/clean.js");
10
+ /**
11
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
12
+ *
13
+ * This source code is licensed under the MIT license found in the
14
+ * LICENSE file in the root directory of this source tree.
15
+ *
16
+ *
17
+ * @format
18
+ * @oncall react_native
19
+ */
20
+ /* eslint sort-keys : "error" */
21
+ var _default = {
22
+ android: _android.tasks,
23
+ apple: _apple.tasks,
24
+ clean: _clean.tasks,
25
+ };
26
+ exports.default = _default;
@@ -0,0 +1,17 @@
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
+ * @oncall react_native
10
+ */
11
+
12
+ import { tasks as android } from "./private/android.js";
13
+ import { tasks as apple } from "./private/apple.js";
14
+ import { tasks as clean } from "./private/clean.js";
15
+
16
+ /* eslint sort-keys : "error" */
17
+ declare export default { android: android, apple: apple, clean: clean };
@@ -0,0 +1,62 @@
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
+ *
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ import type { Task } from "./types";
13
+ import execa from "execa";
14
+ type AndroidBuildMode = "debug" | "release";
15
+ type AndroidBuild = {
16
+ sourceDir: string;
17
+ appName: string;
18
+ mode: AndroidBuildMode;
19
+ gradleArgs?: Array<string>;
20
+ };
21
+ type GradleReturn = ReturnType<typeof execa>;
22
+ /**
23
+ * Assembles an Android app using Gradle
24
+ */
25
+ export declare const assemble: (
26
+ cwd: string,
27
+ appName: string,
28
+ mode: AndroidBuildMode,
29
+ ...args: ReadonlyArray<string>
30
+ ) => GradleReturn;
31
+ /**
32
+ * Assembles and tests an Android app using Gradle
33
+ */
34
+ export declare const build: (
35
+ cwd: string,
36
+ appName: string,
37
+ mode: AndroidBuildMode,
38
+ ...args: ReadonlyArray<string>
39
+ ) => GradleReturn;
40
+ /**
41
+ * Installs an Android app using Gradle
42
+ */
43
+ export declare const install: (
44
+ cwd: string,
45
+ appName: string,
46
+ mode: AndroidBuildMode,
47
+ ...args: ReadonlyArray<string>
48
+ ) => GradleReturn;
49
+ /**
50
+ * Runs a custom Gradle task if your frameworks needs aren't handled by assemble, build or install.
51
+ */
52
+ export declare const customTask: (
53
+ cwd: string,
54
+ customTaskName: string,
55
+ ...args: ReadonlyArray<string>
56
+ ) => GradleReturn;
57
+ type AndroidTasks = {
58
+ assemble: (options: AndroidBuild, ...args: ReadonlyArray<string>) => Task[];
59
+ build: (options: AndroidBuild, ...args: ReadonlyArray<string>) => Task[];
60
+ install: (options: AndroidBuild, ...args: ReadonlyArray<string>) => Task[];
61
+ };
62
+ export declare const tasks: AndroidTasks;
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true,
5
+ });
6
+ exports.tasks =
7
+ exports.install =
8
+ exports.customTask =
9
+ exports.build =
10
+ exports.assemble =
11
+ void 0;
12
+ var _utils = require("./utils");
13
+ var _execa = _interopRequireDefault(require("execa"));
14
+ function _interopRequireDefault(obj) {
15
+ return obj && obj.__esModule ? obj : { default: obj };
16
+ }
17
+ /**
18
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
19
+ *
20
+ * This source code is licensed under the MIT license found in the
21
+ * LICENSE file in the root directory of this source tree.
22
+ *
23
+ *
24
+ * @format
25
+ * @oncall react_native
26
+ */
27
+
28
+ async function gradle(cwd, ...args) {
29
+ const gradlew = _utils.isWindows ? "gradlew.bat" : "./gradlew";
30
+ // $FlowFixMe[incompatible-return] Mismatch between flow and TypeScript types
31
+ return (0, _execa.default)(gradlew, args, {
32
+ cwd,
33
+ stdio: "inherit",
34
+ });
35
+ }
36
+
37
+ //
38
+ // Gradle Task wrappers
39
+ //
40
+
41
+ /**
42
+ * Assembles an Android app using Gradle
43
+ */
44
+ const assemble = (cwd, appName, mode, ...args) =>
45
+ gradle(cwd, `${appName}:assemble${(0, _utils.toPascalCase)(mode)}`, ...args);
46
+
47
+ /**
48
+ * Assembles and tests an Android app using Gradle
49
+ */
50
+ exports.assemble = assemble;
51
+ const build = (cwd, appName, mode, ...args) =>
52
+ gradle(cwd, `${appName}:build${(0, _utils.toPascalCase)(mode)}`, ...args);
53
+
54
+ /**
55
+ * Installs an Android app using Gradle
56
+ */
57
+ exports.build = build;
58
+ const install = (cwd, appName, mode, ...args) =>
59
+ gradle(cwd, `${appName}:install${(0, _utils.toPascalCase)(mode)}`, ...args);
60
+
61
+ /**
62
+ * Runs a custom Gradle task if your frameworks needs aren't handled by assemble, build or install.
63
+ */
64
+ exports.install = install;
65
+ const customTask = (cwd, customTaskName, ...args) =>
66
+ gradle(cwd, customTaskName, ...args);
67
+
68
+ //
69
+ // Android Tasks
70
+ //
71
+ exports.customTask = customTask;
72
+ const tasks = {
73
+ assemble: (options, ...gradleArgs) => [
74
+ (0, _utils.task)("Assemble Android App", () =>
75
+ assemble(options.sourceDir, options.appName, options.mode, ...gradleArgs)
76
+ ),
77
+ ],
78
+ build: (options, ...gradleArgs) => [
79
+ (0, _utils.task)("Assembles and tests Android App", () =>
80
+ build(options.sourceDir, options.appName, options.mode, ...gradleArgs)
81
+ ),
82
+ ],
83
+ /**
84
+ * Useful extra gradle arguments:
85
+ *
86
+ * -PreactNativeDevServerPort=8081 sets the port for the installed app to point towards a Metro
87
+ * server on (for example) 8081.
88
+ */
89
+ install: (options, ...gradleArgs) => [
90
+ (0, _utils.task)("Installs the assembled Android App", () =>
91
+ install(options.sourceDir, options.appName, options.mode, ...gradleArgs)
92
+ ),
93
+ ],
94
+
95
+ // We are not supporting launching the app and setting up the tunnel for metro <-> app, this is
96
+ // a framework concern. For an example of how one could do this, please look at the community
97
+ // CLI's code:
98
+ // https://github.com/react-native-community/cli/blob/54d48a4e08a1aef334ae6168788e0157a666b4f5/packages/cli-platform-android/src/commands/runAndroid/index.ts#L272C1-L290C2
99
+ };
100
+ exports.tasks = tasks;
@@ -0,0 +1,80 @@
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
+ * @oncall react_native
10
+ */
11
+
12
+ import type { Task } from "./types";
13
+
14
+ import execa from "execa";
15
+
16
+ type AndroidBuildMode = "debug" | "release";
17
+
18
+ type AndroidBuild = {
19
+ sourceDir: string,
20
+ appName: string,
21
+ mode: AndroidBuildMode,
22
+ gradleArgs?: Array<string>,
23
+ };
24
+
25
+ type GradleReturn = ReturnType<typeof execa>;
26
+
27
+ //
28
+ // Gradle Task wrappers
29
+ //
30
+
31
+ /**
32
+ * Assembles an Android app using Gradle
33
+ */
34
+ declare export const assemble: (
35
+ cwd: string,
36
+ appName: string,
37
+ mode: AndroidBuildMode,
38
+ ...args: $ReadOnlyArray<string>
39
+ ) => GradleReturn;
40
+
41
+ /**
42
+ * Assembles and tests an Android app using Gradle
43
+ */
44
+ declare export const build: (
45
+ cwd: string,
46
+ appName: string,
47
+ mode: AndroidBuildMode,
48
+ ...args: $ReadOnlyArray<string>
49
+ ) => GradleReturn;
50
+
51
+ /**
52
+ * Installs an Android app using Gradle
53
+ */
54
+ declare export const install: (
55
+ cwd: string,
56
+ appName: string,
57
+ mode: AndroidBuildMode,
58
+ ...args: $ReadOnlyArray<string>
59
+ ) => GradleReturn;
60
+
61
+ /**
62
+ * Runs a custom Gradle task if your frameworks needs aren't handled by assemble, build or install.
63
+ */
64
+ declare export const customTask: (
65
+ cwd: string,
66
+ customTaskName: string,
67
+ ...args: $ReadOnlyArray<string>
68
+ ) => GradleReturn;
69
+
70
+ //
71
+ // Android Tasks
72
+ //
73
+
74
+ type AndroidTasks = {
75
+ assemble: (options: AndroidBuild, ...args: $ReadOnlyArray<string>) => Task[],
76
+ build: (options: AndroidBuild, ...args: $ReadOnlyArray<string>) => Task[],
77
+ install: (options: AndroidBuild, ...args: $ReadOnlyArray<string>) => Task[],
78
+ };
79
+
80
+ declare export const tasks: AndroidTasks;
@@ -0,0 +1,32 @@
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
+ *
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ import type { Task } from "./types";
13
+ type AppleBuildMode = "Debug" | "Release";
14
+ type AppleBuildOptions = {
15
+ isWorkspace: boolean;
16
+ name: string;
17
+ mode: AppleBuildMode;
18
+ scheme: string;
19
+ destination?: string;
20
+ } & AppleOptions;
21
+ type AppleBootstrapOption = {
22
+ bundleInstall: boolean;
23
+ newArchitecture: boolean;
24
+ } & AppleOptions;
25
+ type AppleInstallApp = { device: string; appPath: string } & AppleOptions;
26
+ type AppleOptions = { cwd: string; env?: { [key: string]: string | void } };
27
+ type AppleBuildTasks = {
28
+ bootstrap: (options: AppleBootstrapOption) => Task[];
29
+ build: (options: AppleBuildOptions, ...args: ReadonlyArray<string>) => Task[];
30
+ ios: { install: (options: AppleInstallApp) => Task[] };
31
+ };
32
+ export declare const tasks: AppleBuildTasks;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true,
5
+ });
6
+ exports.tasks = void 0;
7
+ var _utils = require("./utils");
8
+ var _execa = _interopRequireDefault(require("execa"));
9
+ function _interopRequireDefault(obj) {
10
+ return obj && obj.__esModule ? obj : { default: obj };
11
+ }
12
+ /**
13
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
14
+ *
15
+ * This source code is licensed under the MIT license found in the
16
+ * LICENSE file in the root directory of this source tree.
17
+ *
18
+ *
19
+ * @format
20
+ * @oncall react_native
21
+ */
22
+
23
+ const tasks = {
24
+ bootstrap: (options) => [
25
+ (0, _utils.task)("Install CocoaPods dependencies", async () => {
26
+ (0, _utils.assertDependencies)(
27
+ (0, _utils.isOnPath)("pod", "CocoaPods"),
28
+ (0, _utils.isOnPath)("bundle", "Bundler to manage Ruby's gems")
29
+ );
30
+ if (options.bundleInstall) {
31
+ await (0, _execa.default)("bundle", ["exec", "install"], {
32
+ cwd: options.cwd,
33
+ });
34
+ }
35
+ return await (0, _execa.default)("bundle", ["exec", "pod", "install"], {
36
+ cwd: options.cwd,
37
+ env: {
38
+ RCT_NEW_ARCH_ENABLED: options.newArchitecture ? "1" : "0",
39
+ },
40
+ });
41
+ }),
42
+ ],
43
+ build: (options, ...args) => [
44
+ (0, _utils.task)("build an app artifact", () => {
45
+ (0, _utils.assertDependencies)(
46
+ (0, _utils.isOnPath)("xcodebuild", "Xcode Commandline Tools")
47
+ );
48
+ const _args = [
49
+ options.isWorkspace ? "-workspace" : "-project",
50
+ options.name,
51
+ "-scheme",
52
+ options.scheme,
53
+ ];
54
+ if (options.destination != null) {
55
+ _args.push("-destination", options.destination);
56
+ }
57
+ _args.push(...args);
58
+ return (0, _execa.default)("xcodebuild", _args, {
59
+ cwd: options.cwd,
60
+ env: options.env,
61
+ });
62
+ }),
63
+ ],
64
+ ios: {
65
+ install: (options) => [
66
+ (0, _utils.task)("Install the app on a simulator", () => {
67
+ (0, _utils.assertDependencies)(
68
+ (0, _utils.isOnPath)("xcrun", "An Xcode Commandline tool: xcrun")
69
+ );
70
+ return (0, _execa.default)(
71
+ "xcrun",
72
+ ["simctl", "install", options.device, options.appPath],
73
+ {
74
+ cwd: options.cwd,
75
+ env: options.env,
76
+ }
77
+ );
78
+ }),
79
+ ],
80
+ },
81
+ };
82
+ exports.tasks = tasks;
@@ -0,0 +1,51 @@
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
+ * @oncall react_native
10
+ */
11
+
12
+ import type { Task } from "./types";
13
+
14
+ type AppleBuildMode = "Debug" | "Release";
15
+
16
+ type AppleBuildOptions = {
17
+ isWorkspace: boolean,
18
+ name: string,
19
+ mode: AppleBuildMode,
20
+ scheme: string,
21
+ destination?: string, // Device or Simulator or UUID
22
+ } & AppleOptions;
23
+
24
+ type AppleBootstrapOption = {
25
+ bundleInstall: boolean,
26
+ // Enabled by default
27
+ newArchitecture: boolean,
28
+ } & AppleOptions;
29
+
30
+ type AppleInstallApp = {
31
+ device: string,
32
+ appPath: string,
33
+ } & AppleOptions;
34
+
35
+ type AppleOptions = {
36
+ cwd: string,
37
+ env?: { [key: string]: string | void, ... },
38
+ };
39
+
40
+ type AppleBuildTasks = {
41
+ bootstrap: (options: AppleBootstrapOption) => Task[],
42
+ build: (
43
+ options: AppleBuildOptions,
44
+ ...args: $ReadOnlyArray<string>
45
+ ) => Task[],
46
+ ios: {
47
+ install: (options: AppleInstallApp) => Task[],
48
+ },
49
+ };
50
+
51
+ declare export const tasks: AppleBuildTasks;
@@ -0,0 +1,42 @@
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
+ *
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ import type { Task } from "./types";
13
+ type CleanTasks = {
14
+ android: (androidSrcDir: null | undefined | string) => Task[];
15
+ metro: () => Task[];
16
+ npm: (projectRootDir: string, verifyCache?: boolean) => Task[];
17
+ bun: (projectRootDir: string) => Task[];
18
+ watchman: (projectRootDir: string) => Task[];
19
+ yarn: (projectRootDir: string) => Task[];
20
+ cocoapods?: (projectRootDir: string) => Task[];
21
+ };
22
+ /**
23
+ * Removes the contents of a directory matching a given pattern, but keeps the directory.
24
+ * @private
25
+ */
26
+ export declare function deleteDirectoryContents(
27
+ directory: string,
28
+ filePattern: RegExp
29
+ ): Task["action"];
30
+ /**
31
+ * Removes a directory recursively.
32
+ * @private
33
+ */
34
+ export declare function deleteDirectory(directory: string): Task["action"];
35
+ /**
36
+ * Deletes the contents of the tmp directory matching a given pattern.
37
+ * @private
38
+ */
39
+ export declare function deleteTmpDirectoryContents(
40
+ filepattern: RegExp
41
+ ): ReturnType<typeof deleteDirectoryContents>;
42
+ export declare const tasks: CleanTasks;
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true,
5
+ });
6
+ exports.deleteDirectory = deleteDirectory;
7
+ exports.deleteDirectoryContents = deleteDirectoryContents;
8
+ exports.deleteTmpDirectoryContents = deleteTmpDirectoryContents;
9
+ exports.tasks = void 0;
10
+ var _utils = require("./utils");
11
+ var _execa = _interopRequireDefault(require("execa"));
12
+ var _fs = require("fs");
13
+ var _os = _interopRequireDefault(require("os"));
14
+ var _path = _interopRequireDefault(require("path"));
15
+ function _interopRequireDefault(obj) {
16
+ return obj && obj.__esModule ? obj : { default: obj };
17
+ }
18
+ /**
19
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
20
+ *
21
+ * This source code is licensed under the MIT license found in the
22
+ * LICENSE file in the root directory of this source tree.
23
+ *
24
+ *
25
+ * @format
26
+ * @oncall react_native
27
+ */
28
+
29
+ const rmrf = (pathname) => {
30
+ if (!(0, _fs.existsSync)(pathname)) {
31
+ return;
32
+ }
33
+ (0, _fs.rm)(pathname, {
34
+ maxRetries: 3,
35
+ recursive: true,
36
+ force: true,
37
+ });
38
+ };
39
+
40
+ /**
41
+ * Removes the contents of a directory matching a given pattern, but keeps the directory.
42
+ * @private
43
+ */
44
+ function deleteDirectoryContents(directory, filePattern) {
45
+ return async function deleteDirectoryContentsAction() {
46
+ const base = _path.default.dirname(directory);
47
+ const files = (0, _fs.readdirSync)(base).filter((filename) =>
48
+ filePattern.test(filename)
49
+ );
50
+ for (const filename of files) {
51
+ rmrf(_path.default.join(base, filename));
52
+ }
53
+ };
54
+ }
55
+
56
+ /**
57
+ * Removes a directory recursively.
58
+ * @private
59
+ */
60
+ function deleteDirectory(directory) {
61
+ return async function cleanDirectoryAction() {
62
+ rmrf(directory);
63
+ };
64
+ }
65
+
66
+ /**
67
+ * Deletes the contents of the tmp directory matching a given pattern.
68
+ * @private
69
+ */
70
+ function deleteTmpDirectoryContents(filepattern) {
71
+ return deleteDirectoryContents(_os.default.tmpdir(), filepattern);
72
+ }
73
+
74
+ // The tasks that cleanup various build artefacts.
75
+ const tasks = {
76
+ /**
77
+ * Cleans up the Android Gradle cache
78
+ */
79
+ android: (androidSrcDir) => [
80
+ (0, _utils.task)("🧹 Clean Gradle cache", async function gradle(opts) {
81
+ const gradlew = _path.default.join(
82
+ androidSrcDir ?? "android",
83
+ _utils.isWindows ? "gradlew.bat" : "gradlew"
84
+ );
85
+ if (!(0, _fs.existsSync)(gradlew)) {
86
+ return;
87
+ }
88
+ const script = _path.default.basename(gradlew);
89
+ const cwd = _path.default.dirname(gradlew);
90
+ await (0,
91
+ _execa.default)(_utils.isWindows ? script : `./${script}`, ["clean"], {
92
+ cwd,
93
+ ...opts,
94
+ });
95
+ }),
96
+ ],
97
+ /**
98
+ * Agressively cleans up all Metro caches.
99
+ */
100
+ metro: () => [
101
+ (0, _utils.task)(
102
+ "🧹 Clean Metro cache",
103
+ deleteTmpDirectoryContents(/^metro-.+/)
104
+ ),
105
+ (0, _utils.task)(
106
+ "🧹 Clean Haste cache",
107
+ deleteTmpDirectoryContents(/^haste-map-.+/)
108
+ ),
109
+ (0, _utils.task)(
110
+ "🧹 Clean React Native cache",
111
+ deleteTmpDirectoryContents(/^react-.+/)
112
+ ),
113
+ ],
114
+ /**
115
+ * Cleans up the `node_modules` folder and optionally garbage collects the npm cache.
116
+ */
117
+ npm: (projectRootDir, verifyCache = false) => {
118
+ const _tasks = [
119
+ (0, _utils.task)(
120
+ "🧹 Clean node_modules",
121
+ deleteDirectory(_path.default.join(projectRootDir, "node_modules"))
122
+ ),
123
+ ];
124
+ if (verifyCache) {
125
+ _tasks.push(
126
+ (0, _utils.task)("🔬 Verify npm cache", (opts) =>
127
+ (0, _execa.default)("npm", ["cache", "verify"], {
128
+ cwd: projectRootDir,
129
+ ...opts,
130
+ })
131
+ )
132
+ );
133
+ }
134
+ return _tasks;
135
+ },
136
+ /**
137
+ * Cleans up the Bun cache.
138
+ */
139
+ bun: (projectRootDir) => [
140
+ (0, _utils.task)("🧹 Clean Bun cache", (opts) =>
141
+ (0, _execa.default)("bun", ["pm", "cache", "rm"], {
142
+ cwd: projectRootDir,
143
+ ...opts,
144
+ })
145
+ ),
146
+ ],
147
+ /**
148
+ * Stops Watchman and clears its cache
149
+ */
150
+ watchman: (projectRootDir) => [
151
+ (0, _utils.task)("✋ Stop Watchman", (opts) =>
152
+ (0, _execa.default)(
153
+ _utils.isWindows ? "tskill" : "killall",
154
+ ["watchman"],
155
+ {
156
+ cwd: projectRootDir,
157
+ ...opts,
158
+ }
159
+ )
160
+ ),
161
+ (0, _utils.task)("🧹 Delete Watchman cache", (opts) =>
162
+ (0, _execa.default)("watchman", ["watch-del-all"], {
163
+ cwd: projectRootDir,
164
+ ...opts,
165
+ })
166
+ ),
167
+ ],
168
+ /**
169
+ * Cleans up the Yarn cache
170
+ */
171
+ yarn: (projectRootDir) => [
172
+ (0, _utils.task)("🧹 Clean Yarn cache", (opts) =>
173
+ (0, _execa.default)("yarn", ["cache", "clean"], {
174
+ cwd: projectRootDir,
175
+ ...opts,
176
+ })
177
+ ),
178
+ ],
179
+ };
180
+ exports.tasks = tasks;
181
+ if (_utils.isMacOS) {
182
+ /**
183
+ * Cleans up the local and global CocoaPods cache
184
+ */
185
+ tasks.cocoapods = (projectRootDir) => [
186
+ // TODO: add project root
187
+ (0, _utils.task)(
188
+ "🧹 Clean CocoaPods pod cache",
189
+ function removePodCache(opts) {
190
+ return (0, _execa.default)("bundle", ["exec", "pod", "deintegrate"], {
191
+ cwd: projectRootDir,
192
+ ...opts,
193
+ });
194
+ }
195
+ ),
196
+ ];
197
+ }
198
+
199
+ //
200
+ // Internal CLI
201
+ //
@@ -0,0 +1,47 @@
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
+ * @oncall react_native
10
+ */
11
+
12
+ import type { Task } from "./types";
13
+ type CleanTasks = {
14
+ android: (androidSrcDir: ?string) => Task[],
15
+ metro: () => Task[],
16
+ npm: (projectRootDir: string, verifyCache?: boolean) => Task[],
17
+ bun: (projectRootDir: string) => Task[],
18
+ watchman: (projectRootDir: string) => Task[],
19
+ yarn: (projectRootDir: string) => Task[],
20
+ cocoapods?: (projectRootDir: string) => Task[],
21
+ };
22
+
23
+ /**
24
+ * Removes the contents of a directory matching a given pattern, but keeps the directory.
25
+ * @private
26
+ */
27
+ declare export function deleteDirectoryContents(
28
+ directory: string,
29
+ filePattern: RegExp
30
+ ): Task["action"];
31
+
32
+ /**
33
+ * Removes a directory recursively.
34
+ * @private
35
+ */
36
+ declare export function deleteDirectory(directory: string): Task["action"];
37
+
38
+ /**
39
+ * Deletes the contents of the tmp directory matching a given pattern.
40
+ * @private
41
+ */
42
+ declare export function deleteTmpDirectoryContents(
43
+ filepattern: RegExp
44
+ ): ReturnType<typeof deleteDirectoryContents>;
45
+
46
+ // The tasks that cleanup various build artefacts.
47
+ declare export const tasks: CleanTasks;
@@ -0,0 +1,12 @@
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
+ *
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ export type Task = { label: string; action: () => Promise<unknown> };
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,15 @@
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
+ * @oncall react_native
10
+ */
11
+
12
+ export type Task = {
13
+ label: string,
14
+ action: () => Promise<mixed>,
15
+ };
@@ -0,0 +1,24 @@
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
+ *
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ import type { Task } from "./types";
13
+ export declare function task(label: string, action: Task["action"]): Task;
14
+ export declare const isWindows: any;
15
+ export declare const isMacOS: any;
16
+ export declare const toPascalCase: (label: string) => string;
17
+ type PathCheckResult = { found: boolean; dep: string; description: string };
18
+ export declare function isOnPath(
19
+ dep: string,
20
+ description: string
21
+ ): PathCheckResult;
22
+ export declare function assertDependencies(
23
+ ...deps: ReadonlyArray<ReturnType<typeof isOnPath>>
24
+ ): void;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true,
5
+ });
6
+ exports.assertDependencies = assertDependencies;
7
+ exports.isMacOS = void 0;
8
+ exports.isOnPath = isOnPath;
9
+ exports.isWindows = void 0;
10
+ exports.task = task;
11
+ exports.toPascalCase = void 0;
12
+ var _execa = _interopRequireDefault(require("execa"));
13
+ var _os = _interopRequireDefault(require("os"));
14
+ function _interopRequireDefault(obj) {
15
+ return obj && obj.__esModule ? obj : { default: obj };
16
+ }
17
+ /**
18
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
19
+ *
20
+ * This source code is licensed under the MIT license found in the
21
+ * LICENSE file in the root directory of this source tree.
22
+ *
23
+ *
24
+ * @format
25
+ * @oncall react_native
26
+ */
27
+
28
+ function task(label, action) {
29
+ return {
30
+ label,
31
+ action,
32
+ };
33
+ }
34
+ const isWindows = _os.default.platform() === "win32";
35
+ exports.isWindows = isWindows;
36
+ const isMacOS = _os.default.platform() === "darwin";
37
+ exports.isMacOS = isMacOS;
38
+ const toPascalCase = (label) =>
39
+ label.length === 0 ? "" : label[0].toUpperCase() + label.slice(1);
40
+ exports.toPascalCase = toPascalCase;
41
+ function isOnPath(dep, description) {
42
+ const result = _execa.default.sync(isWindows ? "where" : "which", [dep]);
43
+ return {
44
+ dep,
45
+ description,
46
+ found: result.exitCode === 0,
47
+ };
48
+ }
49
+ function assertDependencies(...deps) {
50
+ for (const { found, dep, description } of deps) {
51
+ if (!found) {
52
+ throw new Error(`"${dep}" not found, ${description}`);
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,34 @@
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
+ * @oncall react_native
10
+ */
11
+
12
+ import type { Task } from "./types";
13
+
14
+ declare export function task(label: string, action: Task["action"]): Task;
15
+
16
+ declare export const isWindows: $FlowFixMe;
17
+ declare export const isMacOS: $FlowFixMe;
18
+
19
+ declare export const toPascalCase: (label: string) => string;
20
+
21
+ type PathCheckResult = {
22
+ found: boolean,
23
+ dep: string,
24
+ description: string,
25
+ };
26
+
27
+ declare export function isOnPath(
28
+ dep: string,
29
+ description: string
30
+ ): PathCheckResult;
31
+
32
+ declare export function assertDependencies(
33
+ ...deps: $ReadOnlyArray<ReturnType<typeof isOnPath>>
34
+ ): void;
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@react-native/core-cli-utils",
3
+ "version": "0.75.0-main",
4
+ "description": "React Native CLI library for Frameworks to build on",
5
+ "main": "index.js",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/facebook/react-native.git",
10
+ "directory": "packages/core-cli-utils"
11
+ },
12
+ "exports": {
13
+ ".": "./dist/index.js",
14
+ "./package.json": "./package.json"
15
+ },
16
+ "homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/core-cli-utils#readme",
17
+ "keywords": [
18
+ "cli-utils",
19
+ "react-native"
20
+ ],
21
+ "bugs": "https://github.com/facebook/react-native/issues",
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "dependencies": {},
29
+ "devDependencies": {}
30
+ }