1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | exports.CocoaPodsPackageManager = exports.extractMissingDependencyError = exports.CocoaPodsError = void 0;
|
7 | const spawn_async_1 = __importDefault(require("@expo/spawn-async"));
|
8 | const chalk_1 = __importDefault(require("chalk"));
|
9 | const fs_1 = require("fs");
|
10 | const path_1 = __importDefault(require("path"));
|
11 | const PackageManager_1 = require("./PackageManager");
|
12 | class CocoaPodsError extends Error {
|
13 | constructor(message, code, cause) {
|
14 | super(cause ? `${message}\n└─ Cause: ${cause.message}` : message);
|
15 | this.code = code;
|
16 | this.cause = cause;
|
17 | this.name = 'CocoaPodsError';
|
18 | this.isPackageManagerError = true;
|
19 | }
|
20 | }
|
21 | exports.CocoaPodsError = CocoaPodsError;
|
22 | function extractMissingDependencyError(error) {
|
23 |
|
24 | const results = error.match(/Unable to find a specification for ['"`]([\w-_\d\s]+)['"`] depended upon by ['"`]([\w-_\d\s]+)['"`]/);
|
25 | if (results) {
|
26 | return [results[1], results[2]];
|
27 | }
|
28 | return null;
|
29 | }
|
30 | exports.extractMissingDependencyError = extractMissingDependencyError;
|
31 | class CocoaPodsPackageManager {
|
32 | constructor({ cwd, silent }) {
|
33 | this.silent = !!silent;
|
34 | this.options = {
|
35 | cwd,
|
36 | ...(silent
|
37 | ? { stdio: 'pipe' }
|
38 | : {
|
39 | stdio: ['inherit', 'inherit', 'pipe'],
|
40 | }),
|
41 | };
|
42 | }
|
43 | static getPodProjectRoot(projectRoot) {
|
44 | if (CocoaPodsPackageManager.isUsingPods(projectRoot))
|
45 | return projectRoot;
|
46 | const iosProject = path_1.default.join(projectRoot, 'ios');
|
47 | if (CocoaPodsPackageManager.isUsingPods(iosProject))
|
48 | return iosProject;
|
49 | const macOsProject = path_1.default.join(projectRoot, 'macos');
|
50 | if (CocoaPodsPackageManager.isUsingPods(macOsProject))
|
51 | return macOsProject;
|
52 | return null;
|
53 | }
|
54 | static isUsingPods(projectRoot) {
|
55 | return fs_1.existsSync(path_1.default.join(projectRoot, 'Podfile'));
|
56 | }
|
57 | static async gemInstallCLIAsync(nonInteractive = false, spawnOptions = { stdio: 'inherit' }) {
|
58 | const options = ['install', 'cocoapods', '--no-document'];
|
59 | try {
|
60 |
|
61 | await spawn_async_1.default('gem', options, spawnOptions);
|
62 | }
|
63 | catch (error) {
|
64 | if (nonInteractive) {
|
65 | throw new CocoaPodsError('Failed to install CocoaPods CLI with gem (recommended)', 'COMMAND_FAILED', error);
|
66 | }
|
67 |
|
68 | await PackageManager_1.spawnSudoAsync(['gem', ...options], spawnOptions);
|
69 | }
|
70 | }
|
71 | static async brewLinkCLIAsync(spawnOptions = { stdio: 'inherit' }) {
|
72 | await spawn_async_1.default('brew', ['link', 'cocoapods'], spawnOptions);
|
73 | }
|
74 | static async brewInstallCLIAsync(spawnOptions = { stdio: 'inherit' }) {
|
75 | await spawn_async_1.default('brew', ['install', 'cocoapods'], spawnOptions);
|
76 | }
|
77 | static async installCLIAsync({ nonInteractive = false, spawnOptions = { stdio: 'inherit' }, }) {
|
78 | var _a;
|
79 | if (!spawnOptions) {
|
80 | spawnOptions = { stdio: 'inherit' };
|
81 | }
|
82 | const silent = !!spawnOptions.ignoreStdio;
|
83 | try {
|
84 | !silent && console.log(`\u203A Attempting to install CocoaPods CLI with Gem`);
|
85 | await CocoaPodsPackageManager.gemInstallCLIAsync(nonInteractive, spawnOptions);
|
86 | !silent && console.log(`\u203A Successfully installed CocoaPods CLI with Gem`);
|
87 | return true;
|
88 | }
|
89 | catch (error) {
|
90 | if (!silent) {
|
91 | console.log(chalk_1.default.yellow(`\u203A Failed to install CocoaPods CLI with Gem`));
|
92 | console.log(chalk_1.default.red((_a = error.stderr) !== null && _a !== void 0 ? _a : error.message));
|
93 | console.log(`\u203A Attempting to install CocoaPods CLI with Homebrew`);
|
94 | }
|
95 | try {
|
96 | await CocoaPodsPackageManager.brewInstallCLIAsync(spawnOptions);
|
97 | if (!(await CocoaPodsPackageManager.isCLIInstalledAsync(spawnOptions))) {
|
98 | try {
|
99 | await CocoaPodsPackageManager.brewLinkCLIAsync(spawnOptions);
|
100 |
|
101 | if (!(await CocoaPodsPackageManager.isCLIInstalledAsync(spawnOptions))) {
|
102 | throw new CocoaPodsError('CLI could not be installed automatically with gem or Homebrew, please install CocoaPods manually and try again', 'NO_CLI', error);
|
103 | }
|
104 | }
|
105 | catch (error) {
|
106 | throw new CocoaPodsError('Homebrew installation appeared to succeed but CocoaPods CLI not found in PATH and unable to link.', 'NO_CLI', error);
|
107 | }
|
108 | }
|
109 | !silent && console.log(`\u203A Successfully installed CocoaPods CLI with Homebrew`);
|
110 | return true;
|
111 | }
|
112 | catch (error) {
|
113 | !silent &&
|
114 | console.warn(chalk_1.default.yellow(`\u203A Failed to install CocoaPods with Homebrew. Please install CocoaPods CLI manually and try again.`));
|
115 | throw new CocoaPodsError(`Failed to install CocoaPods with Homebrew. Please install CocoaPods CLI manually and try again.`, 'NO_CLI', error);
|
116 | }
|
117 | }
|
118 | }
|
119 | static isAvailable(projectRoot, silent) {
|
120 | if (process.platform !== 'darwin') {
|
121 | !silent && console.log(chalk_1.default.red('CocoaPods is only supported on macOS machines'));
|
122 | return false;
|
123 | }
|
124 | if (!CocoaPodsPackageManager.isUsingPods(projectRoot)) {
|
125 | !silent && console.log(chalk_1.default.yellow('CocoaPods is not supported in this project'));
|
126 | return false;
|
127 | }
|
128 | return true;
|
129 | }
|
130 | static async isCLIInstalledAsync(spawnOptions = { stdio: 'inherit' }) {
|
131 | try {
|
132 | await spawn_async_1.default('pod', ['--version'], spawnOptions);
|
133 | return true;
|
134 | }
|
135 | catch {
|
136 | return false;
|
137 | }
|
138 | }
|
139 | get name() {
|
140 | return 'CocoaPods';
|
141 | }
|
142 | async installAsync({ spinner } = {}) {
|
143 | await this._installAsync({ spinner });
|
144 | }
|
145 | isCLIInstalledAsync() {
|
146 | return CocoaPodsPackageManager.isCLIInstalledAsync(this.options);
|
147 | }
|
148 | installCLIAsync() {
|
149 | return CocoaPodsPackageManager.installCLIAsync({
|
150 | nonInteractive: true,
|
151 | spawnOptions: this.options,
|
152 | });
|
153 | }
|
154 | async _installAsync({ spinner, shouldUpdate = true, } = {}) {
|
155 | var _a;
|
156 | try {
|
157 | return await this._runAsync(['install']);
|
158 | }
|
159 | catch (error) {
|
160 | const output = error.output.join('\n').trim();
|
161 | const isPodRepoUpdateError = output.includes('pod repo update');
|
162 |
|
163 |
|
164 | if (isPodRepoUpdateError && shouldUpdate) {
|
165 | const warningInfo = extractMissingDependencyError(output);
|
166 | let message;
|
167 | if (warningInfo) {
|
168 | message = `Couldn't install: ${warningInfo[1]} » ${chalk_1.default.underline(warningInfo[0])}.`;
|
169 | }
|
170 | else {
|
171 | message = `Couldn't install Pods.`;
|
172 | }
|
173 | message += ` Updating the Pods project and trying again...`;
|
174 | if (spinner) {
|
175 | spinner.text = chalk_1.default.bold(message);
|
176 | }
|
177 | !this.silent && console.warn(chalk_1.default.yellow(message));
|
178 | await this.podRepoUpdateAsync();
|
179 |
|
180 | return await this._installAsync({ spinner, shouldUpdate: false });
|
181 | }
|
182 | else {
|
183 | const cwd = this.options.cwd || process.cwd();
|
184 | if (error.stdout.match(/No [`'"]Podfile[`'"] found in the project directory/)) {
|
185 | error.message = `No Podfile found in directory: ${cwd}. Ensure CocoaPods is setup any try again.`;
|
186 | }
|
187 | else if (isPodRepoUpdateError) {
|
188 | const warningInfo = extractMissingDependencyError(output);
|
189 | let reason;
|
190 | if (warningInfo) {
|
191 | reason = `Couldn't install: ${warningInfo[1]} » ${chalk_1.default.underline(warningInfo[0])}`;
|
192 | }
|
193 | else {
|
194 | reason = `This is often due to native package versions mismatching`;
|
195 | }
|
196 | let solution;
|
197 | if (warningInfo === null || warningInfo === void 0 ? void 0 : warningInfo[0]) {
|
198 |
|
199 | if (warningInfo[0].match(/^(?:@?expo|@?react)(-|\/)/)) {
|
200 | solution = `Ensure the node module "${warningInfo[0]}" is installed in your project, then run \`npx pod-install\` to try again.`;
|
201 | }
|
202 | else {
|
203 | solution = `Ensure the CocoaPod "${warningInfo[0]}" is installed in your project, then run \`npx pod-install\` to try again.`;
|
204 | }
|
205 | }
|
206 | else {
|
207 | solution = `Try deleting the \`ios/Pods\` folder or the \`ios/Podfile.lock\` file and running \`npx pod-install\` to resolve.`;
|
208 | }
|
209 | error.message = `${reason}. ${solution}`;
|
210 | throw new CocoaPodsError('Command `pod repo update` failed.', 'COMMAND_FAILED', error);
|
211 | }
|
212 | else {
|
213 | let stderr = error.stderr.trim();
|
214 |
|
215 | const usefulError = (_a = error.stdout.match(/\[!\]\s((?:.|\n)*)/)) === null || _a === void 0 ? void 0 : _a[1];
|
216 |
|
217 | if (usefulError) {
|
218 |
|
219 | if (error.message.match(/pod exited with non-zero code: 1/)) {
|
220 | error.message = null;
|
221 | }
|
222 |
|
223 | if (stderr.match(/PBXResourcesBuildPhase/)) {
|
224 | stderr = null;
|
225 | }
|
226 | }
|
227 | error.message = [usefulError, error.message, stderr].filter(Boolean).join('\n');
|
228 | }
|
229 | throw new CocoaPodsError('Command `pod install` failed.', 'COMMAND_FAILED', error);
|
230 | }
|
231 | }
|
232 | }
|
233 | async addAsync(...names) {
|
234 | throw new Error('Unimplemented');
|
235 | }
|
236 | async addDevAsync(...names) {
|
237 | throw new Error('Unimplemented');
|
238 | }
|
239 | async versionAsync() {
|
240 | const { stdout } = await spawn_async_1.default('pod', ['--version'], this.options);
|
241 | return stdout.trim();
|
242 | }
|
243 | async getConfigAsync(key) {
|
244 | throw new Error('Unimplemented');
|
245 | }
|
246 | async removeLockfileAsync() {
|
247 | throw new Error('Unimplemented');
|
248 | }
|
249 | async cleanAsync() {
|
250 | throw new Error('Unimplemented');
|
251 | }
|
252 |
|
253 | async podRepoUpdateAsync() {
|
254 | var _a;
|
255 | try {
|
256 | await this._runAsync(['repo', 'update']);
|
257 | }
|
258 | catch (error) {
|
259 | error.message = error.message || ((_a = error.stderr) !== null && _a !== void 0 ? _a : error.stdout);
|
260 | throw new CocoaPodsError('The command `pod repo update` failed', 'COMMAND_FAILED', error);
|
261 | }
|
262 | }
|
263 | async _runAsync(args) {
|
264 | if (!this.silent) {
|
265 | console.log(`> pod ${args.join(' ')}`);
|
266 | }
|
267 | return spawn_async_1.default('pod', [...args], this.options);
|
268 | }
|
269 | }
|
270 | exports.CocoaPodsPackageManager = CocoaPodsPackageManager;
|
271 |
|
\ | No newline at end of file |