Skip to content

Commit

Permalink
feat: Add travis yml, Add uninstall argument
Browse files Browse the repository at this point in the history
  • Loading branch information
HazAT committed Nov 8, 2017
1 parent 5d384c3 commit feea6ab
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 41 deletions.
3 changes: 3 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
targets:
- github
- npm
15 changes: 15 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
language: node_js
node_js: 8
script: npm run dist && npm pack
before_deploy: mkdir -p build && mv *.tgz build/package.tgz

deploy:
provider: s3
access_key_id: AKIAJKYWAF3QS7SFL75Q
secret_access_key:
secure: ChlFKqMUfbQvGY/mfczQOSorb5ZePWZVbcqkabOEdusXa16I5GxOKjHtf5ND6wo+uQ8w8o6OyfexiEPywdnMJRklp/Byw4PkfLVdk09vR1z1nzXTEPbVFLbDY6b4H6FLeFIsq1ANZTRg12XA3reCkc6i5FmNwtlwvq2sjb/Z2i/VsIW1cPgSpX+ONc4l3c6k8LM9whD1M9/JXFaNfj1IFUNZlrf20RQdUCNPP5BwLqjneXhuw+rBRwJ2sTPgjBQWRa5YKKj+MR3dcw1MlMAwJeiZuTNksipl/CgP1RpyFIgIu9/JS74h4J9RWw/+VsD4pg4bZ7Q4TL0kGDhgwytDa0zSItWAmDSYEy306I2Be3uyhCKafTtoaXgDfaGXdQYDcruQYHoAdzxge2H1s/mc8weLYM0aLmIWzqsX4jktfABrp80INvbxiemoaudUmwsAbw/kfbxcIsPuVjY0kLuT9jyfcvLWVZSsxN5u/kqAVpDPGKl6leb5gQNpr5afUOEXXxkAWXJfU+GQi2Vc1PSX6Uwy0nosWaNN7FTnGjJ3jjJBppOM3n52Wp4IO8Z4wiINQUFRqOUTzZVh9lA1D2jAg/n2Y6w3F+60/+UtjHNswoaw+IszlzMzzNmsDkLAiBv1GHI5BVx7f48+ciMrduiZ+toepRmRHW1E1PLxW+aqLV0=
skip_cleanup: true
acl: public_read
bucket: getsentry-builds
upload-dir: $TRAVIS_REPO_SLUG/$TRAVIS_COMMIT
local_dir: build
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { run } from './lib/Setup';

const argv = require('yargs')
.boolean('debug')
.boolean('uninstall')
.option('type', {
choices: Object.keys(ProjectType),
describe: 'Choose a project type'
Expand Down
1 change: 1 addition & 0 deletions lib/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export enum ProjectType {
export interface IArgs {
url: string;
debug: boolean;
uninstall: boolean;
type: ProjectType;
}

Expand Down
12 changes: 7 additions & 5 deletions lib/Helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ function prepareMessage(msg: any) {
return msg;
}
if (msg instanceof Error) {
return `${msg.name}: ${msg.message}`;
return `${msg.name}: ${msg.message} ${msg.stack || ''}`;
}
return JSON.stringify(msg);
return JSON.stringify(msg, null, '\t');
}

export function l(msg: string) {
Expand Down Expand Up @@ -53,9 +53,11 @@ export class BottomBar {

public static hide() {
clearInterval(BottomBar.interval);
BottomBar.bar.updateBottomBar('');
nl();
BottomBar.bar.close();
if (BottomBar.bar) {
BottomBar.bar.updateBottomBar('');
nl();
BottomBar.bar.close();
}
}
}

Expand Down
23 changes: 12 additions & 11 deletions lib/Setup.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import * as _ from 'lodash';
import { IArgs } from './Constants';
import { green, red, startWizard } from './Helper';
import * as Step from './steps';

export function run(argv: IArgs) {
startWizard(
argv,
Step.Initial,
Step.Welcome,
Step.DetectProjectType,
Step.OpenSentry,
Step.WaitForSentry,
Step.SentryProjectSelector,
Step.ConfigureProject,
Step.Result
);
let steps = [Step.Initial, Step.Welcome, Step.DetectProjectType];
if (argv.uninstall === false) {
steps = _.concat(
steps,
Step.OpenSentry,
Step.WaitForSentry,
Step.SentryProjectSelector
);
}
steps = _.concat(steps, Step.ConfigureProject, Step.Result);
startWizard(argv, ...steps);
}
6 changes: 5 additions & 1 deletion lib/steps/Result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { BaseStep } from './Step';
export class Result extends BaseStep {
public async emit(answers: Answers) {
this.debug(JSON.stringify(answers, null, '\t'));
green('🎉 Successfully setup Sentry for your project 🎉');
if (this.argv.uninstall) {
green('😢 Successfully removed Sentry for your project 😢');
} else {
green('🎉 Successfully setup Sentry for your project 🎉');
}
return {};
}
}
181 changes: 157 additions & 24 deletions lib/steps/configure/ReactNative.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ export class ReactNative extends BaseStep {
}

public async emit(answers: Answers) {
if (this.argv.uninstall) {
return this.uninstall();
}
const sentryCliProperties = this.sentryCliHelper.convertSelectedProjectToProperties(
answers
);
Expand Down Expand Up @@ -76,6 +79,17 @@ export class ReactNative extends BaseStep {
});
}

private async uninstall() {
await patchMatchingFile(
'**/*.xcodeproj/project.pbxproj',
this.unpatchXcodeProj.bind(this)
);
await patchMatchingFile('**/AppDelegate.m', this.unpatchAppDelegate.bind(this));
await patchMatchingFile('**/app/build.gradle', this.unpatchBuildGradle.bind(this));
green(`Successfully removed Sentry`);
return {};
}

private shouldConfigurePlatform(platform: string) {
// if a sentry.properties file exists for the platform we want to configure
// without asking the user. This means that re-linking later will not
Expand Down Expand Up @@ -110,30 +124,6 @@ export class ReactNative extends BaseStep {
return rv;
}

private patchAppDelegate(contents: string) {
// add the header if it's not there yet.
if (!contents.match(/#import "RNSentry.h"/)) {
contents = contents.replace(
/(#import <React\/RCTRootView.h>)/,
'$1\n' + OBJC_HEADER
);
}

// add root view init.
const rootViewMatch = contents.match(/RCTRootView\s*\*\s*([^\s=]+)\s*=\s*\[/);
if (rootViewMatch) {
const rootViewInit = '[RNSentry installWithRootView:' + rootViewMatch[1] + '];';
if (contents.indexOf(rootViewInit) < 0) {
contents = contents.replace(
/^(\s*)RCTRootView\s*\*\s*[^\s=]+\s*=\s*\[([^]*?\s*\]\s*;\s*$)/m,
(match, indent) => match.trim() + '\n' + indent + rootViewInit + '\n'
);
}
}

return Promise.resolve(contents);
}

private patchAppJs(contents: string, filename: string) {
// since the init call could live in other places too, we really only
// want to do this if we managed to patch any of the other files as well.
Expand Down Expand Up @@ -192,6 +182,8 @@ export class ReactNative extends BaseStep {
);
}

// ANDROID -----------------------------------------

private patchBuildGradle(contents: string) {
const applyFrom =
'apply from: "../../node_modules/react-native-sentry/sentry.gradle"';
Expand All @@ -206,6 +198,17 @@ export class ReactNative extends BaseStep {
);
}

private unpatchBuildGradle(contents: string) {
return Promise.resolve(
contents.replace(
/^\s*apply from: ["']..\/..\/node_modules\/react-native-sentry\/sentry.gradle["'];?\s*?\r?\n/m,
''
)
);
}

// IOS -----------------------------------------

private patchExistingXcodeBuildScripts(buildScripts: any) {
for (const script of buildScripts) {
if (
Expand Down Expand Up @@ -255,6 +258,30 @@ export class ReactNative extends BaseStep {
});
}

private patchAppDelegate(contents: string) {
// add the header if it's not there yet.
if (!contents.match(/#import "RNSentry.h"/)) {
contents = contents.replace(
/(#import <React\/RCTRootView.h>)/,
'$1\n' + OBJC_HEADER
);
}

// add root view init.
const rootViewMatch = contents.match(/RCTRootView\s*\*\s*([^\s=]+)\s*=\s*\[/);
if (rootViewMatch) {
const rootViewInit = '[RNSentry installWithRootView:' + rootViewMatch[1] + '];';
if (contents.indexOf(rootViewInit) < 0) {
contents = contents.replace(
/^(\s*)RCTRootView\s*\*\s*[^\s=]+\s*=\s*\[([^]*?\s*\]\s*;\s*$)/m,
(match, indent) => match.trim() + '\n' + indent + rootViewInit + '\n'
);
}
}

return Promise.resolve(contents);
}

private patchXcodeProj(contents: string, filename: string) {
const proj = xcode.project(filename);
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -292,6 +319,112 @@ export class ReactNative extends BaseStep {
});
}

private unpatchAppDelegate(contents: string) {
return Promise.resolve(
contents
.replace(/^#if __has_include\(<React\/RNSentry.h>\)[^]*?\#endif\r?\n/m, '')
.replace(/^#import\s+(?:<React\/RNSentry.h>|"RNSentry.h")\s*?\r?\n/m, '')
.replace(/(\r?\n|^)\s*\[RNSentry\s+installWithRootView:.*?\];\s*?\r?\n/m, '')
);
}

private unpatchXcodeBuildScripts(proj: any) {
const scripts = proj.hash.project.objects.PBXShellScriptBuildPhase || {};
const firstTarget = proj.getFirstTarget().uuid;
const nativeTargets = proj.hash.project.objects.PBXNativeTarget;

// scripts to patch partially. Run this first so that we don't
// accidentally delete some scripts later entirely that we only want to
// rewrite.
for (const key of Object.keys(scripts)) {
const script = scripts[key];

// ignore comments
if (typeof script === 'string') {
continue;
}

// ignore scripts that do not invoke the react-native-xcode command.
if (!script.shellScript.match(/sentry-cli\s+react-native[\s-]xcode\b/)) {
continue;
}

script.shellScript = JSON.stringify(
JSON.parse(script.shellScript)
// "legacy" location for this. This is what happens if users followed
// the old documentation for where to add the bundle command
.replace(
/^..\/node_modules\/react-native-sentry\/bin\/bundle-frameworks\s*?\r\n?/m,
''
)
// legacy location for dsym upload
.replace(
/^..\/node_modules\/sentry-cli-binary\/bin\/sentry-cli upload-dsym\s*?\r?\n/m,
''
)
// remove sentry properties export
.replace(/^export SENTRY_PROPERTIES=sentry.properties\r?\n/m, '')
// unwrap react-native-xcode.sh command. In case someone replaced it
// entirely with the sentry-cli command we need to put the original
// version back in.
.replace(
/^(?:..\/node_modules\/sentry-cli-binary\/bin\/)?sentry-cli\s+react-native[\s-]xcode(\s+.*?)$/m,
(match: any, m1: string) => {
const rv = m1.trim();
if (rv === '') {
return '../node_modules/react-native/packager/react-native-xcode.sh';
} else {
return rv;
}
}
)
);
}

// scripts to kill entirely.
for (const key of Object.keys(scripts)) {
const script = scripts[key];

// ignore comments and keys that got deleted
if (typeof script === 'string' || script === undefined) {
continue;
}

if (
script.shellScript.match(/react-native-sentry\/bin\/bundle-frameworks\b/) ||
script.shellScript.match(/sentry-cli-binary\/bin\/sentry-cli\s+upload-dsym\b/)
) {
delete scripts[key];
delete scripts[key + '_comment'];
const phases = nativeTargets[firstTarget].buildPhases;
if (phases) {
for (let i = 0; i < phases.length; i++) {
if (phases[i].value === key) {
phases.splice(i, 1);
break;
}
}
}
continue;
}
}
}

private unpatchXcodeProj(contents: string, filename: string) {
const proj = xcode.project(filename);
return new Promise((resolve, reject) => {
proj.parse((err: any) => {
if (err) {
reject(err);
return;
}

this.unpatchXcodeBuildScripts(proj);
resolve(proj.writeSync());
});
});
}

private platformSelector() {
return prompt([
{
Expand Down

0 comments on commit feea6ab

Please sign in to comment.