Skip to content

Commit 8d0df34

Browse files
committed
Merge branch 'feature/android-native-client' of github.com:getsentry/react-native-sentry into feature/android-native-client
2 parents 34bb26e + d1e5a53 commit 8d0df34

File tree

4 files changed

+123
-8
lines changed

4 files changed

+123
-8
lines changed

examples/ReactNativeExample/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"dependencies": {
1010
"react": "^16.0.0-alpha.6",
11-
"react-native": "^0.43.4",
11+
"react-native": "^0.44.0",
1212
"react-native-sentry": "file:../../"
1313
}
1414
}

package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@
2121
},
2222
"dependencies": {
2323
"raven-js": "^3.15.0",
24-
"sentry-cli-binary": "^1.6.0"
24+
"sentry-cli-binary": "^1.6.0",
25+
"inquirer": "3.0.6",
26+
"glob": "7.1.1"
27+
},
28+
"rnpm": {
29+
"commands": {
30+
"postlink": "node node_modules/react-native-sentry/scripts/postlink"
31+
}
2532
}
2633
}

scripts/postlink

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
let glob = require('glob');
2+
let fs = require('fs');
3+
let inquirer = require('inquirer');
4+
5+
let OBJC_HEADER = '\
6+
#if __has_include(<React/RNSentry.h>)\n\
7+
#import <React/RNSentry.h> // This is used for versions of react >= 0.40\n\
8+
#else\n\
9+
#import "RNSentry.h" // This is used for versions of react < 0.40\n\
10+
#endif';
11+
12+
let cachedDsn = null;
13+
14+
function getDsn() {
15+
if (cachedDsn !== null) {
16+
return Promise.resolve(cachedDsn);
17+
}
18+
19+
return inquirer.prompt([{
20+
type: 'input',
21+
default: 'YOUR_DSN_HERE',
22+
message: 'The DSN for your mobile application',
23+
name: 'dsn',
24+
}]).then(function(answers) {
25+
cachedDsn = answers.dsn;
26+
return Promise.resolve(answers.dsn);
27+
});
28+
}
29+
30+
function patchAppDelegate(contents) {
31+
// add the header if it's not there yet.
32+
if (!contents.match(/#import "RNSentry.h"/)) {
33+
contents = contents.replace(
34+
/(#import <React\/RCTRootView.h>)/,
35+
'$1\n' + OBJC_HEADER
36+
);
37+
}
38+
39+
// add root view init.
40+
let rootViewMatch = contents.match(/RCTRootView\s*\*\s*([^\s=]+)\s*=\s*\[/);
41+
if (rootViewMatch) {
42+
let rootViewInit = '[RNSentry installWithRootView:' + rootViewMatch[1] + '];';
43+
if (contents.indexOf(rootViewInit) < 0) {
44+
contents = contents.replace(
45+
/^(\s*)RCTRootView\s*\*\s*[^\s=]+\s*=\s*\[([^]*?\s*\]\s*;\s*$)/m,
46+
function(match, indent) {
47+
return match.trimRight() + '\n' + indent + rootViewInit + '\n';
48+
}
49+
);
50+
}
51+
}
52+
53+
return Promise.resolve(contents);
54+
}
55+
56+
function patchIndexJs(contents) {
57+
if (contents.match(/Sentry.config\(/)) {
58+
return Promise.resolve(contents);
59+
}
60+
61+
return getDsn().then(function(dsn) {
62+
return Promise.resolve(contents.replace(/^([^]*)(import\s+[^;]*?;$)/m, function(match) {
63+
return match + '\n\nimport { Sentry } from \'react-native-sentry\';\n\n' +
64+
'Sentry.config(' + JSON.stringify(dsn) + ').install();\n';
65+
}));
66+
});
67+
}
68+
69+
function patchBuildGradle(contents) {
70+
let applyFrom = 'apply from: "../../node_modules/react-native-sentry/sentry.gradle"';
71+
if (contents.indexOf(applyFrom) >= 0) {
72+
return Promise.resolve(contents);
73+
}
74+
75+
return Promise.resolve(contents.replace(
76+
/^apply from: "..\/..\/node_modules\/react-native\/react.gradle"/m,
77+
function(match) {
78+
return match + '\n' + applyFrom;
79+
}
80+
));
81+
}
82+
83+
function patchMatchingFile(pattern, func) {
84+
let matches = glob.sync(pattern, {
85+
ignore: 'node_modules/**'
86+
});
87+
let rv = Promise.resolve();
88+
matches.forEach(function(match) {
89+
let contents = fs.readFileSync(match, {
90+
encoding: 'utf-8'
91+
});
92+
rv = rv.then(() => func(contents)).then(function(newContents) {
93+
if (contents != newContents) {
94+
fs.writeFileSync(match, newContents);
95+
}
96+
});
97+
});
98+
return rv;
99+
}
100+
101+
Promise.resolve()
102+
.then(() => patchMatchingFile('**/AppDelegate.m', patchAppDelegate))
103+
.then(() => patchMatchingFile('index.*.js', patchIndexJs))
104+
.then(() => patchMatchingFile('**/app/build.gradle', patchBuildGradle))
105+
.catch(function(e) {
106+
console.log('Could not link react-native-sentry: ' + e);
107+
return Promise.resolve();
108+
});

sentry.gradle

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ gradle.projectsEvaluated {
55
// resources task. From the "assetsDir" property we can extract in which
66
// assets folder the task is operating. This folder matches where react native
77
// will place the bundles.
8-
def releasesForAssets = [:];
8+
def releasesForFolder = [:];
99
android.applicationVariants.each { variant ->
1010
def releaseName = "${variant.getApplicationId()}-${variant.getVersionName()}";
1111
variant.outputs.each { output ->
12-
def processTask = output.getProcessResources() as Task;
13-
def assetDir = processTask.getProperties().get("assetsDir");
14-
def releases = releasesForAssets.get(assetDir.toString()) as List<String>;
12+
def processTask = output.getProcessResources();
13+
def resDir = processTask.getResDir();
14+
def releases = releasesForFolder.get(resDir.toString()) as List<String>;
1515
if (releases == null) {
1616
releases = [];
17-
releasesForAssets.put(assetDir.toString(), releases);
17+
releasesForFolder.put(resDir.toString(), releases);
1818
}
1919
def versionCode = output.getVersionCode();
2020
releases.add([releaseName, versionCode]);
@@ -31,7 +31,7 @@ gradle.projectsEvaluated {
3131
def outputs = bundleTask.getOutputs();
3232
def allReleases = [:];
3333
outputs.getFiles().each { file ->
34-
def releases = releasesForAssets.get(file.toString());
34+
def releases = releasesForFolder.get(file.toString());
3535
if (releases != null) {
3636
releases.each { item ->
3737
def codes = allReleases[item[0]] as List<String>;

0 commit comments

Comments
 (0)