Skip to content

Commit

Permalink
feat: Add prettier rc, Add cordova support
Browse files Browse the repository at this point in the history
  • Loading branch information
HazAT committed Nov 15, 2017
1 parent 4296540 commit af132c5
Show file tree
Hide file tree
Showing 16 changed files with 215 additions and 64 deletions.
5 changes: 5 additions & 0 deletions .prettierrc
@@ -0,0 +1,5 @@
{
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 90
}
3 changes: 0 additions & 3 deletions .vscode/settings.json
Expand Up @@ -5,9 +5,6 @@
"[javascript]": {
"editor.formatOnSave": true
},
"prettier.singleQuote": true,
"prettier.printWidth": 90,
"prettier.jsxBracketSameLine": true,
"prettier.typescriptEnable": [
"typescript",
"typescriptreact"
Expand Down
19 changes: 19 additions & 0 deletions bin.ts
@@ -0,0 +1,19 @@
#!/usr/bin/env node
import { IArgs, ProjectType } from './lib/Constants';
import { run } from './lib/Setup';
export * from './lib/Setup';

const argv = require('yargs')
.boolean('debug')
.boolean('uninstall')
.option('type', {
choices: Object.keys(ProjectType),
describe: 'Choose a project type',
})
.option('url', {
alias: 'u',
default: 'https://sentry.io/',
describe: 'The url to your Sentry installation',
}).argv;

run(argv as IArgs);
20 changes: 2 additions & 18 deletions index.ts
@@ -1,18 +1,2 @@
#!/usr/bin/env node
import { IArgs, ProjectType } from './lib/Constants';
import { run } from './lib/Setup';

const argv = require('yargs')
.boolean('debug')
.boolean('uninstall')
.option('type', {
choices: Object.keys(ProjectType),
describe: 'Choose a project type'
})
.option('url', {
alias: 'u',
default: 'https://sentry.io/',
describe: 'The url to your Sentry installation'
}).argv;

run(argv as IArgs);
export { IArgs, ProjectType } from './lib/Constants';
export * from './lib/Setup';
29 changes: 28 additions & 1 deletion lib/Constants.ts
Expand Up @@ -2,7 +2,34 @@
export enum ProjectType {
reactNative = 'reactNative',
javascript = 'javascript',
node = 'node'
node = 'node',
cordova = 'cordova',
}

export function getProjectDescription(type: string) {
switch (type) {
case ProjectType.reactNative:
return 'React Native';
case ProjectType.cordova:
return 'Cordova';
case ProjectType.node:
return 'Generic node project';
default:
return 'Generic javascript project';
}
}

export function getProjectTypeChoices() {
const result = [];
for (const type in ProjectType) {
if (ProjectType.hasOwnProperty(type)) {
result.push({
name: getProjectDescription(type),
value: type,
});
}
}
return result;
}

export interface IArgs {
Expand Down
1 change: 1 addition & 0 deletions lib/Helper.ts
Expand Up @@ -64,6 +64,7 @@ export class BottomBar {
function sanitizeArgs(argv: IArgs) {
let baseUrl = argv.url;
baseUrl += baseUrl.endsWith('/') ? '' : '/';
baseUrl = baseUrl.replace(/:\/(?!\/)/g, '://');
argv.url = baseUrl;
}

Expand Down
3 changes: 3 additions & 0 deletions lib/steps/ConfigureProject.ts
@@ -1,6 +1,7 @@
import { Answers } from 'inquirer';
import * as _ from 'lodash';
import { ProjectType } from '../Constants';
import { Cordova } from './configure/Cordova';
import { GenericJavascript } from './configure/GenericJavascript';
import { GenericNode } from './configure/GenericNode';
import { ReactNative } from './configure/ReactNative';
Expand All @@ -16,6 +17,8 @@ export class ConfigureProject extends BaseStep {
switch (projectType) {
case ProjectType.reactNative:
return new ReactNative(this.argv).emit(answers);
case ProjectType.cordova:
return new Cordova(this.argv).emit(answers);
case ProjectType.node:
return new GenericNode(this.argv).emit(answers);
default:
Expand Down
21 changes: 4 additions & 17 deletions lib/steps/DetectProjectType.ts
@@ -1,6 +1,6 @@
import { Answers, prompt, Question } from 'inquirer';
import * as _ from 'lodash';
import { ProjectType } from '../Constants';
import { getProjectTypeChoices, ProjectType } from '../Constants';
import { green } from '../Helper';
import { BaseStep } from './Step';

Expand All @@ -22,25 +22,12 @@ export class DetectProjectType extends BaseStep {
const projectType = this.tryDetectingProjectType();
return prompt([
{
choices: [
{
name: `Generic node project`,
value: ProjectType.node
},
{
name: `Generic javascript project`,
value: ProjectType.javascript
},
{
name: `React Native`,
value: ProjectType.reactNative
}
],
choices: getProjectTypeChoices(),
default: projectType,
message: 'What kind of project are you running:',
name: 'projectType',
type: 'list'
}
type: 'list',
},
]);
}

Expand Down
6 changes: 3 additions & 3 deletions lib/steps/SentryProjectSelector.ts
Expand Up @@ -20,13 +20,13 @@ export class SentryProjectSelector extends BaseStep {
choices: answers.wizard.projects.map((project: any) => {
return {
name: `${project.organization.name} / ${project.name}`,
value: project
value: project,
};
}),
message: 'Please select your project in Sentry:',
name: 'selectedProject',
type: 'list'
}
type: 'list',
},
]);
}
}
112 changes: 112 additions & 0 deletions lib/steps/configure/Cordova.ts
@@ -0,0 +1,112 @@
import * as fs from 'fs';
import { Answers, prompt } from 'inquirer';
import * as _ from 'lodash';
import * as path from 'path';
import { IArgs } from '../../Constants';
import { dim, green, l, nl, red } from '../../Helper';
import { BaseStep } from '../Step';
import { patchMatchingFile } from './FileHelper';
import { SentryCliHelper } from './SentryCliHelper';

export class Cordova extends BaseStep {
protected answers: Answers;
protected platforms: string[];
protected sentryCliHelper: SentryCliHelper;
protected folderPrefix = 'platforms';

constructor(protected argv: IArgs) {
super(argv);
this.sentryCliHelper = new SentryCliHelper(this.argv);
}

public async emit(answers: Answers) {
if (this.argv.uninstall) {
// return this.uninstall();
}
const sentryCliProperties = this.sentryCliHelper.convertSelectedProjectToProperties(
answers
);
return ['ios', 'android'].map(async (platform: string) => {
try {
await this.addSentryProperties(platform, sentryCliProperties);
green(`Successfully setup ${platform} for cordova`);
} catch (e) {
red(e);
}
});

// return new Promise(async (resolve, reject) => {
// this.answers = answers;
// this.platforms = (await this.platformSelector()).platform;
// const promises = this.platforms.map((platform: string) =>
// this.shouldConfigurePlatform(platform).then(async () => {

// })
// );
// });
}

private addSentryProperties(platform: string, properties: any) {
let rv = Promise.resolve();
// This will create the ios/android folder before trying to write
// sentry.properties in it which would fail otherwise

if (!fs.existsSync(this.folderPrefix)) {
dim(`${this.folderPrefix} folder did not exist, creating it.`);
fs.mkdirSync(this.folderPrefix);
}
if (!fs.existsSync(path.join(this.folderPrefix, platform))) {
dim(`${platform} folder did not exist, creating it.`);
fs.mkdirSync(path.join(this.folderPrefix, platform));
}
const fn = path.join(this.folderPrefix, platform, 'sentry.properties');

rv = rv.then(() =>
fs.writeFileSync(fn, this.sentryCliHelper.dumpProperties(properties))
);

return rv;
}

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
// bring up a useless dialog.

if (
fs.existsSync(path.join(this.folderPrefix, platform, 'sentry.properties')) ||
fs.existsSync(
path.join(process.cwd(), this.folderPrefix, platform, 'sentry.properties')
)
) {
return Promise.reject(
`${platform}/sentry.properties already exists, skipping setup for platform ${
platform
}`
);
}
return Promise.resolve();
}

private platformSelector() {
return prompt([
{
choices: [
{
checked: true,
name: 'iOS',
value: 'ios',
},
{
checked: true,
name: 'Android',
value: 'android',
},
],
message: 'Select the platforms you like to setup:',
name: 'platform',
type: 'checkbox',
},
]);
}
}
6 changes: 3 additions & 3 deletions lib/steps/configure/FileHelper.ts
@@ -1,14 +1,14 @@
import * as fs from 'fs';
const glob = require('glob');
const fs = require('fs');

export function patchMatchingFile(pattern: string, func: any) {
const matches = glob.sync(pattern, {
ignore: ['node_modules/**', 'ios/Pods/**', '**/Pods/**']
ignore: ['node_modules/**', 'ios/Pods/**', '**/Pods/**'],
});
let rv = Promise.resolve();
matches.forEach((match: string) => {
const contents = fs.readFileSync(match, {
encoding: 'utf-8'
encoding: 'utf-8',
});
rv = rv.then(() => func(contents, match)).then(newContents => {
if (newContents !== null && contents !== undefined && contents !== newContents) {
Expand Down
25 changes: 14 additions & 11 deletions lib/steps/configure/ReactNative.ts
@@ -1,13 +1,15 @@
import * as fs from 'fs';
import { Answers, prompt, Question } from 'inquirer';
import * as _ from 'lodash';
import * as path from 'path';
import { IArgs } from '../../Constants';
import { dim, green, red } from '../../Helper';
import { BaseStep } from '../Step';
import { patchMatchingFile } from './FileHelper';
import { SentryCliHelper } from './SentryCliHelper';

const xcode = require('xcode');
const fs = require('fs');
// const path = require('path');

const OBJC_HEADER =
'\
Expand Down Expand Up @@ -95,8 +97,8 @@ export class ReactNative extends BaseStep {
// without asking the user. This means that re-linking later will not
// bring up a useless dialog.
if (
fs.existsSync(platform + '/sentry.properties') ||
fs.existsSync(process.cwd() + platform + '/sentry.properties')
fs.existsSync(path.join(platform, 'sentry.properties')) ||
fs.existsSync(path.join(process.cwd(), platform, 'sentry.properties'))
) {
return Promise.reject(
`${platform}/sentry.properties already exists, skipping setup for platform ${
Expand All @@ -113,9 +115,10 @@ export class ReactNative extends BaseStep {
// This will create the ios/android folder before trying to write
// sentry.properties in it which would fail otherwise
if (!fs.existsSync(platform)) {
dim(`${platform} folder did not exist, creating it.`);
fs.mkdirSync(platform);
}
const fn = platform + '/sentry.properties';
const fn = path.join(platform, 'sentry.properties');

rv = rv.then(() =>
fs.writeFileSync(fn, this.sentryCliHelper.dumpProperties(properties))
Expand Down Expand Up @@ -245,7 +248,7 @@ export class ReactNative extends BaseStep {
shellPath: '/bin/sh',
shellScript:
'export SENTRY_PROPERTIES=sentry.properties\\n' +
'../node_modules/sentry-cli-binary/bin/sentry-cli upload-dsym'
'../node_modules/sentry-cli-binary/bin/sentry-cli upload-dsym',
}
);
}
Expand All @@ -254,7 +257,7 @@ export class ReactNative extends BaseStep {
proj.addPbxGroup([], 'Frameworks', 'Application');
proj.addFramework('libz.tbd', {
link: true,
target: proj.getFirstTarget().uuid
target: proj.getFirstTarget().uuid,
});
}

Expand Down Expand Up @@ -432,18 +435,18 @@ export class ReactNative extends BaseStep {
{
checked: true,
name: 'iOS',
value: 'ios'
value: 'ios',
},
{
checked: true,
name: 'Android',
value: 'android'
}
value: 'android',
},
],
message: 'Select the platforms you like to setup:',
name: 'platform',
type: 'checkbox'
}
type: 'checkbox',
},
]);
}
}

0 comments on commit af132c5

Please sign in to comment.