Skip to content

Commit

Permalink
feat(rn): Add support for RN TypeScript and other templates (#185)
Browse files Browse the repository at this point in the history
  • Loading branch information
krystofwoldrich authored Aug 29, 2022
1 parent 67d8e37 commit 18ae57a
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 23 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 2.1.0

- feat(rn): Add support for RN TypeScript and other templates

## 2.0.2

- fix(electron): Remove Electron symbols.js script
Expand Down
2 changes: 1 addition & 1 deletion lib/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export interface Args {
debug: boolean;
uninstall: boolean;
integration: Integration;
platform: Platform;
platform: Platform[];
skipConnect: boolean;
quiet: boolean;
}
Expand Down
10 changes: 8 additions & 2 deletions lib/Helper/File.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as fs from 'fs';
const glob = require('glob');
import * as glob from 'glob';

const IGNORE_PATTERN = ['node_modules/**', 'ios/Pods/**', '**/Pods/**'];

Expand Down Expand Up @@ -31,6 +31,12 @@ export function patchMatchingFile(
return rv;
}

export function matchFiles(globPattern: string): string[] {
return glob.sync(globPattern, {
ignore: IGNORE_PATTERN,
});
}

export function exists(globPattern: string): boolean {
const matches = glob.sync(globPattern, {
ignore: IGNORE_PATTERN,
Expand All @@ -54,7 +60,7 @@ export function matchesContent(
return false;
}
return matches.reduce((prev: boolean, match: string) => {
return (
return !!(
prev &&
fs
.readFileSync(match)
Expand Down
4 changes: 4 additions & 0 deletions lib/Helper/Logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export function dim(msg: string): void {
return l(Chalk.dim(prepareMessage(msg)));
}

export function yellow(msg: string): void {
return l(Chalk.yellow(prepareMessage(msg)));
}

export function debug(msg: any): void {
return l(Chalk.italic.yellow(prepareMessage(msg)));
}
2 changes: 1 addition & 1 deletion lib/Helper/__tests__/SentryCli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { SentryCli } from '../SentryCli';
const args: Args = {
debug: false,
integration: Integration.reactNative,
platform: Platform.ios,
platform: [Platform.ios],
quiet: false,
skipConnect: false,
uninstall: false,
Expand Down
45 changes: 29 additions & 16 deletions lib/Steps/Integrations/ReactNative.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import * as _ from 'lodash';
import * as path from 'path';

import { Args } from '../../Constants';
import { exists, matchesContent, patchMatchingFile } from '../../Helper/File';
import { dim, green, red } from '../../Helper/Logging';
import { exists, matchesContent, matchFiles, patchMatchingFile } from '../../Helper/File';
import { dim, green, red, yellow } from '../../Helper/Logging';
import { SentryCli } from '../../Helper/SentryCli';
import { MobileProject } from './MobileProject';

Expand Down Expand Up @@ -51,20 +51,7 @@ export class ReactNative extends MobileProject {
);
dim(`✅ Patched build.gradle file.`);
}
await patchMatchingFile(
`index.${platform}.js`,
this._patchJs.bind(this),
answers,
platform,
);
// rm 0.49 introduced an App.js for both platforms
await patchMatchingFile(
'App.js',
this._patchJs.bind(this),
answers,
platform,
);
dim(`✅ Patched App.js file.`);
await this._patchJsSentryInit(platform, answers);
await this._addSentryProperties(platform, sentryCliProperties);
dim(`✅ Added sentry.properties file to ${platform}`);

Expand Down Expand Up @@ -132,6 +119,32 @@ export class ReactNative extends MobileProject {
return result;
}

private async _patchJsSentryInit(
platform: string,
answers: Answers,
): Promise<void> {
const prefixGlob = '{.,./src}';
const suffixGlob = '@(j|t|cj|mj)s?(x)';
const platformGlob = `index.${platform}.${suffixGlob}`;
// rm 0.49 introduced an App.js for both platforms
const universalGlob = `App.${suffixGlob}`;
const jsFileGlob = `${prefixGlob}/+(${platformGlob}|${universalGlob})`;

const jsFileToPatch = matchFiles(jsFileGlob);
if (jsFileToPatch.length !== 0) {
await patchMatchingFile(
jsFileGlob,
this._patchJs.bind(this),
answers,
platform,
);
dim(`✅ Patched ${jsFileToPatch.join(', ')} file(s).`);
} else {
dim(`🚨 Could not find ${platformGlob} nor ${universalGlob} files.`);
yellow('❓ Please, visit https://docs.sentry.io/platforms/react-native');
}
}

private _addSentryProperties(
platform: string,
properties: any,
Expand Down
67 changes: 67 additions & 0 deletions lib/Steps/Integrations/__tests__/ReactNative.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
jest.mock('../../../Helper/Logging.ts'); // We mock logging to not pollute the output
import * as fs from 'fs';
import { Answers } from 'inquirer';
import * as process from 'process';
import * as rimraf from 'rimraf';

import { Args, Integration, Platform } from '../../../Constants';
import { ReactNative } from '../ReactNative';

const testDir = 'rn-test';
const iosIndexJs = 'index.ios.js';
const appTsx = 'src/App.tsx';

const dummyJsContent = 'import React from "react";\n';

const testArgs = {
debug: false,
integration: Integration.reactNative,
platform: [Platform.ios],
quiet: true,
skipConnect: true,
uninstall: false,
url: 'https://not.used',
};

const testAnswers: Answers = {
shouldConfigurePlatforms: { 'ios': true },
config: {
dsn: {
public: 'dns.public.com',
},
},
};

describe('ReactNative', () => {

const defaultCwd = process.cwd();

beforeEach(() => {
rimraf.sync(testDir);
fs.mkdirSync(testDir);
process.chdir(testDir);
fs.writeFileSync(iosIndexJs, dummyJsContent);
fs.mkdirSync('src');
fs.writeFileSync(appTsx, dummyJsContent);
});

afterEach(() => {
process.chdir(defaultCwd);
rimraf.sync(testDir);
});

test('patches js files', async () => {
const project = new ReactNative(testArgs as Args);
await project.emit(testAnswers);

const patchedIosIndexJs = fs.readFileSync(iosIndexJs, 'utf8');
const patchedAppTsx = fs.readFileSync(appTsx, 'utf8');
const expectedPatch = 'import React from "react";\n\n' +
'import * as Sentry from \'@sentry/react-native\';\n\n' +
'Sentry.init({ \n' +
' dsn: \'dns.public.com\', \n' +
'});\n\n';
expect(patchedIosIndexJs).toEqual(expectedPatch);
expect(patchedAppTsx).toEqual(expectedPatch);
});
});
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,17 @@
},
"devDependencies": {
"@sentry-internal/eslint-config-sdk": "^6.2.1",
"@types/glob": "^7.2.0",
"@types/inquirer": "^0.0.43",
"@types/jest": "^23.3.2",
"@types/lodash": "^4.14.144",
"@types/node": "^10.11.0",
"@types/rimraf": "^3.0.2",
"@types/semver": "^7.3.7",
"eslint": "^7.21.0",
"jest": "^26.6.3",
"prettier": "^1.14.3",
"rimraf": "^3.0.2",
"ts-jest": "^26.5.5",
"ts-node": "^7.0.1",
"tslint": "^5.11.0",
Expand Down
27 changes: 24 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,14 @@
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==

"@types/glob@*", "@types/glob@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==
dependencies:
"@types/minimatch" "*"
"@types/node" "*"

"@types/graceful-fs@^4.1.2":
version "4.1.5"
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15"
Expand Down Expand Up @@ -671,15 +679,20 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008"
integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==

"@types/minimatch@*":
version "3.0.5"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==

"@types/node@*":
version "14.14.41"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.41.tgz#d0b939d94c1d7bd53d04824af45f1139b8c45615"
integrity sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==

"@types/node@^10.11.0":
version "10.17.58"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.58.tgz#10682f6016fd866725c36d22ce6bbbd029bf4545"
integrity sha512-Dn5RBxLohjdHFj17dVVw3rtrZAeXeWg+LQfvxDIW/fdPkSiuQk7h3frKMYtsQhtIW42wkErDcy9UMVxhGW4O7w==
version "10.17.60"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b"
integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==

"@types/normalize-package-data@^2.4.0":
version "2.4.0"
Expand All @@ -691,6 +704,14 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.3.tgz#ef65165aea2924c9359205bf748865b8881753c0"
integrity sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==

"@types/rimraf@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.2.tgz#a63d175b331748e5220ad48c901d7bbf1f44eef8"
integrity sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==
dependencies:
"@types/glob" "*"
"@types/node" "*"

"@types/rx-core-binding@*":
version "4.0.4"
resolved "https://registry.yarnpkg.com/@types/rx-core-binding/-/rx-core-binding-4.0.4.tgz#d969d32f15a62b89e2862c17b3ee78fe329818d3"
Expand Down

0 comments on commit 18ae57a

Please sign in to comment.