@@ -6,7 +6,8 @@ const chalk = require('chalk');
66const pbxFile = require('xcode/lib/pbxFile');
77
88const PLATFORMS = ['android', 'ios'];
9- const OBJC_HEADER = '\
9+ const OBJC_HEADER =
10+ '\
1011#if __has_include(<React/RNSentry.h>)\n\
1112#import <React/RNSentry.h> // This is used for versions of react >= 0.40\n\
1213#else\n\
@@ -20,10 +21,12 @@ let didShowInfoHint = false;
2021let configurePlatform = {};
2122
2223function getPlatformName(platform) {
23- return {
24- 'android': 'Android',
25- 'ios': 'iOS',
26- }[platform] || platform;
24+ return (
25+ {
26+ android: 'Android',
27+ ios: 'iOS'
28+ }[platform] || platform
29+ );
2730}
2831
2932function considerShowingInfoHint() {
@@ -32,8 +35,9 @@ function considerShowingInfoHint() {
3235 }
3336
3437 let {green, dim} = chalk;
35- function l(msg) { console.log(msg); }
36-
38+ function l(msg) {
39+ console.log(msg);
40+ }
3741
3842 l('');
3943 l(green('You are about to configure Sentry for React Native'));
@@ -59,50 +63,60 @@ function shouldConfigurePlatform(platform) {
5963 return Promise.resolve(true);
6064 }
6165 considerShowingInfoHint();
62- return inquirer.prompt([{
63- type: 'list',
64- name: 'configure',
65- message: `Do you want to configure Sentry for ${getPlatformName(platform)}?`,
66- choices: [
67- {
68- name: 'Yes',
69- value: true
70- },
66+ return inquirer
67+ .prompt([
7168 {
72- name: 'No (or later)',
73- value: false
69+ type: 'list',
70+ name: 'configure',
71+ message: `Do you want to configure Sentry for ${getPlatformName(platform)}?`,
72+ choices: [
73+ {
74+ name: 'Yes',
75+ value: true
76+ },
77+ {
78+ name: 'No (or later)',
79+ value: false
80+ }
81+ ]
7482 }
75- ]
76- }]) .then(function(answers) {
77- configurePlatform[platform] = answers.configure;
78- return Promise.resolve(answers.configure);
79- });
83+ ])
84+ .then(function(answers) {
85+ configurePlatform[platform] = answers.configure;
86+ return Promise.resolve(answers.configure);
87+ });
8088}
8189
8290function getDsn(platform) {
8391 considerShowingInfoHint();
84- return inquirer.prompt([{
85- type: 'input',
86- default: cachedDsn || process.env.SENTRY_DSN || 'YOUR_DSN_HERE',
87- message: 'The DSN for ' + getPlatformName(platform),
88- name: 'dsn',
89- validate: function(value) {
90- let m = value.match(/^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)$/);
91- if (!m) {
92- return 'invalid dsn format';
93- }
94- if (m[1] !== 'http' && m[1] !== 'https') {
95- return 'unsupported protocol for dsn: ' + m[1];
96- }
97- if (!m[3]) {
98- return 'missing secret in dsn';
92+ return inquirer
93+ .prompt([
94+ {
95+ type: 'input',
96+ default: cachedDsn || process.env.SENTRY_DSN || 'YOUR_DSN_HERE',
97+ message: 'The DSN for ' + getPlatformName(platform),
98+ name: 'dsn',
99+ validate: function(value) {
100+ let m = value.match(
101+ /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)$/
102+ );
103+ if (!m) {
104+ return 'invalid dsn format';
105+ }
106+ if (m[1] !== 'http' && m[1] !== 'https') {
107+ return 'unsupported protocol for dsn: ' + m[1];
108+ }
109+ if (!m[3]) {
110+ return 'missing secret in dsn';
111+ }
112+ return true;
113+ }
99114 }
100- return true;
101- }
102- }]).then(function(answers) {
103- cachedDsn = answers.dsn;
104- return Promise.resolve(answers.dsn);
105- });
115+ ])
116+ .then(function(answers) {
117+ cachedDsn = answers.dsn;
118+ return Promise.resolve(answers.dsn);
119+ });
106120}
107121
108122function getDefaultUrl() {
@@ -116,30 +130,41 @@ function getDefaultUrl() {
116130}
117131
118132function getProperties(platform) {
119- return inquirer.prompt([{
120- type: 'input',
121- default: cachedProps['defaults/url'] || process.env.SENTRY_URL || getDefaultUrl(),
122- message: 'The Sentry Server URL for ' + getPlatformName(platform),
123- name: 'defaults/url',
124- }, {
125- type: 'input',
126- default: cachedProps['defaults/org'] || process.env.SENTRY_ORG || 'your-org-slug',
127- message: 'The Organization for ' + getPlatformName(platform),
128- name: 'defaults/org',
129- }, {
130- type: 'input',
131- default: cachedProps['defaults/project'] || process.env.SENTRY_PROJECT || 'your-project-slug',
132- message: 'The Project for ' + getPlatformName(platform),
133- name: 'defaults/project',
134- }, {
135- type: 'password',
136- default: cachedProps['auth/token'] || process.env.SENTRY_AUTH_TOKEN || 'YOUR_AUTH_TOKEN',
137- message: 'The Auth-Token for ' + getPlatformName(platform),
138- name: 'auth/token',
139- }]).then(function(answers) {
140- cachedProps = answers;
141- return Promise.resolve(answers);
142- });
133+ return inquirer
134+ .prompt([
135+ {
136+ type: 'input',
137+ default: cachedProps['defaults/url'] || process.env.SENTRY_URL || getDefaultUrl(),
138+ message: 'The Sentry Server URL for ' + getPlatformName(platform),
139+ name: 'defaults/url'
140+ },
141+ {
142+ type: 'input',
143+ default: cachedProps['defaults/org'] || process.env.SENTRY_ORG || 'your-org-slug',
144+ message: 'The Organization for ' + getPlatformName(platform),
145+ name: 'defaults/org'
146+ },
147+ {
148+ type: 'input',
149+ default:
150+ cachedProps['defaults/project'] ||
151+ process.env.SENTRY_PROJECT ||
152+ 'your-project-slug',
153+ message: 'The Project for ' + getPlatformName(platform),
154+ name: 'defaults/project'
155+ },
156+ {
157+ type: 'password',
158+ default:
159+ cachedProps['auth/token'] || process.env.SENTRY_AUTH_TOKEN || 'YOUR_AUTH_TOKEN',
160+ message: 'The Auth-Token for ' + getPlatformName(platform),
161+ name: 'auth/token'
162+ }
163+ ])
164+ .then(function(answers) {
165+ cachedProps = answers;
166+ return Promise.resolve(answers);
167+ });
143168}
144169
145170function dumpProperties(props) {
@@ -159,10 +184,7 @@ function dumpProperties(props) {
159184function patchAppDelegate(contents) {
160185 // add the header if it's not there yet.
161186 if (!contents.match(/#import "RNSentry.h"/)) {
162- contents = contents.replace(
163- /(#import <React\/RCTRootView.h>)/,
164- '$1\n' + OBJC_HEADER
165- );
187+ contents = contents.replace(/(#import <React\/RCTRootView.h>)/, '$1\n' + OBJC_HEADER);
166188 }
167189
168190 // add root view init.
@@ -190,16 +212,23 @@ function patchIndexJs(contents, filename) {
190212 }
191213
192214 let platform = filename.match(/index\.([^.]+?)\.js/)[1];
193- return shouldConfigurePlatform(platform).then(( shouldConfigure) => {
215+ return shouldConfigurePlatform(platform).then(shouldConfigure => {
194216 if (!shouldConfigure) {
195217 return null;
196218 }
197219
198220 return getDsn(platform).then(function(dsn) {
199- return Promise.resolve(contents.replace(/^([^]*)(import\s+[^;]*?;$)/m, function(match) {
200- return match + '\n\nimport { Sentry } from \'react-native-sentry\';\n\n' +
201- 'Sentry.config(' + JSON.stringify(dsn) + ').install();\n';
202- }));
221+ return Promise.resolve(
222+ contents.replace(/^([^]*)(import\s+[^;]*?;$)/m, function(match) {
223+ return (
224+ match +
225+ "\n\nimport { Sentry } from 'react-native-sentry';\n\n" +
226+ 'Sentry.config(' +
227+ JSON.stringify(dsn) +
228+ ').install();\n'
229+ );
230+ })
231+ );
203232 });
204233 });
205234}
@@ -210,33 +239,38 @@ function patchBuildGradle(contents) {
210239 return Promise.resolve(null);
211240 }
212241
213- return shouldConfigurePlatform('android').then(( shouldConfigure) => {
242+ return shouldConfigurePlatform('android').then(shouldConfigure => {
214243 if (!shouldConfigure) {
215244 return null;
216245 }
217246
218- return Promise.resolve(contents.replace(
219- /^apply from: "..\/..\/node_modules\/react-native\/react.gradle"/m,
220- function(match) {
221- return match + '\n' + applyFrom;
222- }
223- ));
247+ return Promise.resolve(
248+ contents.replace(
249+ /^apply from: "..\/..\/node_modules\/react-native\/react.gradle"/m,
250+ function(match) {
251+ return match + '\n' + applyFrom;
252+ }
253+ )
254+ );
224255 });
225256}
226257
227258function patchExistingXcodeBuildScripts(buildScripts) {
228259 for (let script of buildScripts) {
229- if (!script.shellScript.match(/packager\/react-native-xcode\.sh\b/) ||
230- script.shellScript.match(/sentry-cli\s+react-native[\s-]xcode/)) {
260+ if (
261+ !script.shellScript.match(/packager\/react-native-xcode\.sh\b/) ||
262+ script.shellScript.match(/sentry-cli\s+react-native[\s-]xcode/)
263+ ) {
231264 continue;
232265 }
233266 let code = JSON.parse(script.shellScript);
234- code = (
267+ code =
235268 'export SENTRY_PROPERTIES=sentry.properties\n' +
236269 code.replace(/^.*?\/packager\/react-native-xcode\.sh\s*/m, function(match) {
237- return '../node_modules/sentry-cli-binary/bin/sentry-cli react-native xcode ' + match;
238- })
239- );
270+ return (
271+ '../node_modules/sentry-cli-binary/bin/sentry-cli react-native xcode ' + match
272+ );
273+ });
240274 script.shellScript = JSON.stringify(code);
241275 }
242276}
@@ -255,10 +289,9 @@ function addNewXcodeBuildPhaseForSymbols(buildScripts, proj) {
255289 null,
256290 {
257291 shellPath: '/bin/sh',
258- shellScript: (
292+ shellScript:
259293 'export SENTRY_PROPERTIES=sentry.properties\\n' +
260- '../node_modules/sentry-cli-binary/bin/sentry-cli upload-dsym'
261- )
294+ '../node_modules/sentry-cli-binary/bin/sentry-cli upload-dsym'
262295 }
263296 );
264297}
@@ -300,7 +333,7 @@ function patchXcodeProj(contents, filename) {
300333 if (newContents === contents) {
301334 resolve(null);
302335 } else {
303- return shouldConfigurePlatform('ios').then(( shouldConfigure) => {
336+ return shouldConfigurePlatform('ios').then(shouldConfigure => {
304337 resolve(shouldConfigure ? newContents : null);
305338 });
306339 }
@@ -349,14 +382,16 @@ function addSentryProperties() {
349382 continue;
350383 }
351384
352- rv = rv.then(() => shouldConfigurePlatform(platform).then((shouldConfigure) => {
353- if (!shouldConfigure) {
354- return null;
355- }
356- return getProperties(platform).then((props) => {
357- fs.writeFileSync(fn, dumpProperties(props));
358- });
359- }));
385+ rv = rv.then(() =>
386+ shouldConfigurePlatform(platform).then(shouldConfigure => {
387+ if (!shouldConfigure) {
388+ return null;
389+ }
390+ return getProperties(platform).then(props => {
391+ fs.writeFileSync(fn, dumpProperties(props));
392+ });
393+ })
394+ );
360395 }
361396
362397 return rv;
0 commit comments