@sentry/wizard 3.5.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/bin.ts +1 -34
- package/dist/bin.js +1 -28
- package/dist/bin.js.map +1 -1
- package/dist/lib/Constants.d.ts +2 -0
- package/dist/lib/Constants.js +5 -0
- package/dist/lib/Constants.js.map +1 -1
- package/dist/lib/Helper/Wizard.js +2 -0
- package/dist/lib/Helper/Wizard.js.map +1 -1
- package/dist/lib/Helper/__tests__/SentryCli.js +1 -0
- package/dist/lib/Helper/__tests__/SentryCli.js.map +1 -1
- package/dist/lib/Steps/ChooseIntegration.js +4 -0
- package/dist/lib/Steps/ChooseIntegration.js.map +1 -1
- package/dist/lib/Steps/Integrations/Apple.d.ts +10 -0
- package/dist/lib/Steps/Integrations/Apple.js +92 -0
- package/dist/lib/Steps/Integrations/Apple.js.map +1 -0
- package/dist/lib/Steps/Integrations/NextJsShim.js +1 -0
- package/dist/lib/Steps/Integrations/NextJsShim.js.map +1 -1
- package/dist/lib/Steps/Integrations/SourceMapsShim.d.ts +1 -1
- package/dist/lib/Steps/Integrations/SourceMapsShim.js +2 -1
- package/dist/lib/Steps/Integrations/SourceMapsShim.js.map +1 -1
- package/dist/lib/Steps/Integrations/SvelteKitShim.js +1 -0
- package/dist/lib/Steps/Integrations/SvelteKitShim.js.map +1 -1
- package/dist/package.json +2 -2
- package/dist/src/apple/apple-wizard.d.ts +2 -0
- package/dist/src/apple/apple-wizard.js +197 -0
- package/dist/src/apple/apple-wizard.js.map +1 -0
- package/dist/src/apple/code-tools.d.ts +1 -0
- package/dist/src/apple/code-tools.js +100 -0
- package/dist/src/apple/code-tools.js.map +1 -0
- package/dist/src/apple/templates.d.ts +4 -0
- package/dist/src/apple/templates.js +19 -0
- package/dist/src/apple/templates.js.map +1 -0
- package/dist/src/apple/xcode-manager.d.ts +4 -0
- package/dist/src/apple/xcode-manager.js +145 -0
- package/dist/src/apple/xcode-manager.js.map +1 -0
- package/dist/src/nextjs/nextjs-wizard.js +4 -10
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/sourcemaps/sourcemaps-wizard.js +193 -71
- package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
- package/dist/src/sourcemaps/tools/angular.d.ts +1 -0
- package/dist/src/sourcemaps/tools/angular.js +76 -0
- package/dist/src/sourcemaps/tools/angular.js.map +1 -0
- package/dist/src/sourcemaps/tools/esbuild.js +2 -1
- package/dist/src/sourcemaps/tools/esbuild.js.map +1 -1
- package/dist/src/sourcemaps/tools/rollup.js +2 -1
- package/dist/src/sourcemaps/tools/rollup.js.map +1 -1
- package/dist/src/sourcemaps/tools/sentry-cli.d.ts +1 -0
- package/dist/src/sourcemaps/tools/sentry-cli.js +52 -24
- package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
- package/dist/src/sourcemaps/tools/vite.js +2 -1
- package/dist/src/sourcemaps/tools/vite.js.map +1 -1
- package/dist/src/sourcemaps/tools/webpack.js +2 -1
- package/dist/src/sourcemaps/tools/webpack.js.map +1 -1
- package/dist/src/sourcemaps/utils/detect-tool.d.ts +3 -0
- package/dist/src/sourcemaps/utils/detect-tool.js +73 -0
- package/dist/src/sourcemaps/utils/detect-tool.js.map +1 -0
- package/dist/src/sourcemaps/utils/other-wizards.d.ts +4 -0
- package/dist/src/sourcemaps/utils/other-wizards.js +183 -0
- package/dist/src/sourcemaps/utils/other-wizards.js.map +1 -0
- package/dist/src/sourcemaps/utils/sdk-version.js +14 -13
- package/dist/src/sourcemaps/utils/sdk-version.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup.js +5 -3
- package/dist/src/sveltekit/sdk-setup.js.map +1 -1
- package/dist/src/sveltekit/sveltekit-wizard.js +2 -1
- package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
- package/dist/src/sveltekit/templates.js +1 -1
- package/dist/src/sveltekit/templates.js.map +1 -1
- package/dist/src/telemetry.d.ts +1 -0
- package/dist/src/telemetry.js +7 -1
- package/dist/src/telemetry.js.map +1 -1
- package/dist/src/utils/bash.d.ts +3 -0
- package/dist/src/utils/bash.js +118 -0
- package/dist/src/utils/bash.js.map +1 -0
- package/dist/src/utils/clack-utils.d.ts +12 -8
- package/dist/src/utils/clack-utils.js +83 -40
- package/dist/src/utils/clack-utils.js.map +1 -1
- package/dist/src/utils/package-json.d.ts +19 -0
- package/dist/src/utils/package-json.js +29 -0
- package/dist/src/utils/package-json.js.map +1 -0
- package/dist/src/utils/types.d.ts +4 -0
- package/dist/src/utils/types.js.map +1 -1
- package/lib/Constants.ts +6 -0
- package/lib/Helper/Wizard.ts +3 -0
- package/lib/Helper/__tests__/SentryCli.ts +2 -1
- package/lib/Steps/ChooseIntegration.ts +4 -0
- package/lib/Steps/Integrations/Apple.ts +27 -0
- package/lib/Steps/Integrations/NextJsShim.ts +1 -0
- package/lib/Steps/Integrations/SourceMapsShim.ts +2 -1
- package/lib/Steps/Integrations/SvelteKitShim.ts +1 -0
- package/package-lock.json +8910 -0
- package/package.json +2 -2
- package/src/apple/apple-wizard.ts +150 -0
- package/src/apple/code-tools.ts +81 -0
- package/src/apple/templates.ts +39 -0
- package/src/apple/xcode-manager.ts +147 -0
- package/src/nextjs/nextjs-wizard.ts +6 -10
- package/src/sourcemaps/sourcemaps-wizard.ts +211 -92
- package/src/sourcemaps/tools/angular.ts +42 -0
- package/src/sourcemaps/tools/esbuild.ts +1 -1
- package/src/sourcemaps/tools/rollup.ts +2 -4
- package/src/sourcemaps/tools/sentry-cli.ts +45 -27
- package/src/sourcemaps/tools/vite.ts +1 -1
- package/src/sourcemaps/tools/webpack.ts +1 -1
- package/src/sourcemaps/utils/detect-tool.ts +41 -0
- package/src/sourcemaps/utils/other-wizards.ts +148 -0
- package/src/sourcemaps/utils/sdk-version.ts +9 -16
- package/src/sveltekit/sdk-setup.ts +5 -2
- package/src/sveltekit/sveltekit-wizard.ts +1 -1
- package/src/sveltekit/templates.ts +1 -1
- package/src/telemetry.ts +8 -0
- package/src/utils/bash.ts +44 -0
- package/src/utils/clack-utils.ts +82 -51
- package/src/utils/package-json.ts +45 -0
- package/src/utils/types.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/wizard",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"homepage": "https://github.com/getsentry/sentry-wizard",
|
|
5
5
|
"repository": "https://github.com/getsentry/sentry-wizard",
|
|
6
6
|
"description": "Sentry wizard helping you to configure your project",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@clack/core": "0.3.2",
|
|
27
27
|
"@clack/prompts": "0.6.3",
|
|
28
28
|
"@sentry/cli": "^1.72.0",
|
|
29
|
-
"@sentry/node": "^7.
|
|
29
|
+
"@sentry/node": "^7.57.0",
|
|
30
30
|
"axios": "1.3.5",
|
|
31
31
|
"chalk": "^2.4.1",
|
|
32
32
|
"glob": "^7.1.3",
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/* eslint-disable max-lines */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
5
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
6
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
7
|
+
import clack from '@clack/prompts';
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import * as xcManager from './xcode-manager';
|
|
11
|
+
import * as codeTools from './code-tools';
|
|
12
|
+
import * as bash from '../utils/bash';
|
|
13
|
+
import { WizardOptions } from '../utils/types';
|
|
14
|
+
import * as Sentry from '@sentry/node';
|
|
15
|
+
import { traceStep, withTelemetry } from '../telemetry';
|
|
16
|
+
|
|
17
|
+
const xcode = require('xcode');
|
|
18
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
19
|
+
|
|
20
|
+
import {
|
|
21
|
+
askForProjectSelection,
|
|
22
|
+
askForSelfHosted,
|
|
23
|
+
askForWizardLogin,
|
|
24
|
+
askToInstallSentryCLI,
|
|
25
|
+
SentryProjectData,
|
|
26
|
+
printWelcome,
|
|
27
|
+
abort,
|
|
28
|
+
askForItemSelection,
|
|
29
|
+
} from '../utils/clack-utils';
|
|
30
|
+
|
|
31
|
+
export async function runAppleWizard(options: WizardOptions): Promise<void> {
|
|
32
|
+
return withTelemetry(
|
|
33
|
+
{
|
|
34
|
+
enabled: options.telemetryEnabled,
|
|
35
|
+
integration: 'ios',
|
|
36
|
+
},
|
|
37
|
+
() => runAppleWizardWithTelementry(options),
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function runAppleWizardWithTelementry(
|
|
42
|
+
options: WizardOptions,
|
|
43
|
+
): Promise<void> {
|
|
44
|
+
printWelcome({
|
|
45
|
+
wizardName: 'Sentry Apple Wizard',
|
|
46
|
+
promoCode: options.promoCode,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const hasCli = bash.hasSentryCLI();
|
|
50
|
+
Sentry.setTag('has-cli', hasCli);
|
|
51
|
+
if (!hasCli) {
|
|
52
|
+
if (
|
|
53
|
+
!(await traceStep('Ask for SentryCLI', () => askToInstallSentryCLI()))
|
|
54
|
+
) {
|
|
55
|
+
clack.log.warn(
|
|
56
|
+
"Without sentry-cli, you won't be able to upload debug symbols to Sentry. You can install it later by following the instructions at https://docs.sentry.io/cli/",
|
|
57
|
+
);
|
|
58
|
+
Sentry.setTag('CLI-Installed', false);
|
|
59
|
+
} else {
|
|
60
|
+
await bash.installSentryCLI();
|
|
61
|
+
Sentry.setTag('CLI-Installed', true);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const projectDir = process.cwd();
|
|
66
|
+
const xcodeProjFiles = findFilesWithExtension(projectDir, '.xcodeproj');
|
|
67
|
+
|
|
68
|
+
if (!xcodeProjFiles || xcodeProjFiles.length === 0) {
|
|
69
|
+
clack.log.error(
|
|
70
|
+
'No Xcode project found. Please run this command from the root of your project.',
|
|
71
|
+
);
|
|
72
|
+
await abort();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let xcodeProjFile;
|
|
77
|
+
|
|
78
|
+
if (xcodeProjFiles.length === 1) {
|
|
79
|
+
xcodeProjFile = xcodeProjFiles[0];
|
|
80
|
+
Sentry.setTag('multiple-projects', false);
|
|
81
|
+
} else {
|
|
82
|
+
Sentry.setTag('multiple-projects', true);
|
|
83
|
+
xcodeProjFile = (
|
|
84
|
+
await traceStep('Choose Xcode project', () =>
|
|
85
|
+
askForItemSelection(
|
|
86
|
+
xcodeProjFiles,
|
|
87
|
+
'Which project do you want to add Sentry to?',
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
).value;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const pbxproj = path.join(projectDir, xcodeProjFile, 'project.pbxproj');
|
|
94
|
+
if (!fs.existsSync(pbxproj)) {
|
|
95
|
+
clack.log.error(`No pbxproj found at ${pbxproj}`);
|
|
96
|
+
await abort();
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const { project, apiKey } = await getSentryProjectAndApiKey(
|
|
101
|
+
options.promoCode,
|
|
102
|
+
options.url,
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
traceStep('Update Xcode project', () => {
|
|
106
|
+
xcManager.updateXcodeProject(pbxproj, project, apiKey, true, true);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const projSource = path.join(
|
|
110
|
+
projectDir,
|
|
111
|
+
xcodeProjFile.replace('.xcodeproj', ''),
|
|
112
|
+
);
|
|
113
|
+
const codeAdded = traceStep('Add code snippet', () => {
|
|
114
|
+
return codeTools.addCodeSnippetToProject(
|
|
115
|
+
projSource,
|
|
116
|
+
project.keys[0].dsn.public,
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
if (!codeAdded) {
|
|
120
|
+
clack.log.warn(
|
|
121
|
+
'Added the Sentry dependency to your project but could not add the Sentry code snippet. Please add the code snipped manually by following the docs: https://docs.sentry.io/platforms/apple/guides/ios/#configure',
|
|
122
|
+
);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
clack.log.success('Sentry was successfully added to your project!');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
//Prompt for Sentry project and API key
|
|
130
|
+
async function getSentryProjectAndApiKey(
|
|
131
|
+
promoCode?: string,
|
|
132
|
+
url?: string,
|
|
133
|
+
): Promise<{ project: SentryProjectData; apiKey: { token: string } }> {
|
|
134
|
+
const { url: sentryUrl } = await askForSelfHosted(url);
|
|
135
|
+
|
|
136
|
+
const { projects, apiKeys } = await askForWizardLogin({
|
|
137
|
+
promoCode: promoCode,
|
|
138
|
+
url: sentryUrl,
|
|
139
|
+
platform: 'apple-ios',
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const selectedProject = await askForProjectSelection(projects);
|
|
143
|
+
return { project: selectedProject, apiKey: apiKeys };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
//find files with the given extension
|
|
147
|
+
function findFilesWithExtension(dir: string, extension: string): string[] {
|
|
148
|
+
const files = fs.readdirSync(dir);
|
|
149
|
+
return files.filter((file) => file.endsWith(extension));
|
|
150
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as templates from './templates';
|
|
4
|
+
import * as Sentry from '@sentry/node';
|
|
5
|
+
|
|
6
|
+
const swiftAppLaunchRegex = /(func\s+application\s*\(_\sapplication:[^,]+,\s*didFinishLaunchingWithOptions[^,]+:[^)]+\)\s+->\s+Bool\s+{)|(init\s*\([^)]*\)\s*{)/im;
|
|
7
|
+
const objcAppLaunchRegex = /-\s*\(BOOL\)\s*application:\s*\(UIApplication\s*\*\)\s*application\s+didFinishLaunchingWithOptions:\s*\(NSDictionary\s*\*\)\s*launchOptions\s*{/im;
|
|
8
|
+
const swiftUIRegex = /struct[^:]+:\s*App\s*{/im;
|
|
9
|
+
|
|
10
|
+
function isAppDelegateFile(filePath: string): boolean {
|
|
11
|
+
const appLaunchRegex = filePath.toLowerCase().endsWith(".swift") ? swiftAppLaunchRegex : objcAppLaunchRegex;
|
|
12
|
+
|
|
13
|
+
const fileContent = fs.readFileSync(filePath, 'utf8');
|
|
14
|
+
return appLaunchRegex.test(fileContent) || swiftUIRegex.test(fileContent);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function findAppDidFinishLaunchingWithOptions(dir: string): string | null {
|
|
18
|
+
const files = fs.readdirSync(dir);
|
|
19
|
+
//iterate over subdirectories later,
|
|
20
|
+
//the appdelegate usually is in the top level
|
|
21
|
+
const dirs: string[] = [];
|
|
22
|
+
|
|
23
|
+
for (const file of files) {
|
|
24
|
+
const filePath = path.join(dir, file);
|
|
25
|
+
if (file.endsWith(".swift") || file.endsWith(".m") || file.endsWith(".mm")) {
|
|
26
|
+
if (isAppDelegateFile(filePath)) {
|
|
27
|
+
return filePath;
|
|
28
|
+
}
|
|
29
|
+
} else if (!file.startsWith(".") && !file.endsWith(".xcodeproj") && !file.endsWith(".xcassets") && fs.lstatSync(filePath).isDirectory()) {
|
|
30
|
+
dirs.push(file);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
for (const dr of dirs) {
|
|
35
|
+
const result = findAppDidFinishLaunchingWithOptions(path.join(dir, dr));
|
|
36
|
+
if (result) return result;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function addCodeSnippetToProject(projPath: string, dsn: string): boolean {
|
|
42
|
+
const appDelegate = findAppDidFinishLaunchingWithOptions(projPath);
|
|
43
|
+
if (!appDelegate) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const fileContent = fs.readFileSync(appDelegate, 'utf8');
|
|
48
|
+
const isSwift = appDelegate.toLowerCase().endsWith(".swift");
|
|
49
|
+
const appLaunchRegex = isSwift ? swiftAppLaunchRegex : objcAppLaunchRegex;
|
|
50
|
+
const importStatement = isSwift ? "import Sentry\n" : "@import Sentry;\n";
|
|
51
|
+
const checkForSentryInit = isSwift ? "SentrySDK.start" : "[SentrySDK start";
|
|
52
|
+
let codeSnippet = isSwift ? templates.getSwiftSnippet(dsn) : templates.getObjcSnippet(dsn);
|
|
53
|
+
|
|
54
|
+
Sentry.setTag("code-language", isSwift ? "swift" : "objc");
|
|
55
|
+
Sentry.setTag("ui-engine", swiftUIRegex.test(fileContent) ? "swiftui" : "uikit");
|
|
56
|
+
|
|
57
|
+
if (fileContent.includes(checkForSentryInit)) {
|
|
58
|
+
//already initialized
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let match = appLaunchRegex.exec(fileContent);
|
|
63
|
+
if (!match) {
|
|
64
|
+
const swiftUIMatch = swiftUIRegex.exec(fileContent)
|
|
65
|
+
if (!swiftUIMatch) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
//Is SwiftUI with no init
|
|
69
|
+
match = swiftUIMatch;
|
|
70
|
+
codeSnippet = ` init() {\n${codeSnippet} }`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const insertIndex = match.index + match[0].length;
|
|
74
|
+
const newFileContent = (fileContent.indexOf(importStatement) >= 0 ? "" : importStatement) +
|
|
75
|
+
fileContent.slice(0, insertIndex) + "\n" +
|
|
76
|
+
codeSnippet +
|
|
77
|
+
fileContent.slice(insertIndex);
|
|
78
|
+
fs.writeFileSync(appDelegate, newFileContent, 'utf8');
|
|
79
|
+
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function getRunScriptTemplate(
|
|
2
|
+
orgSlug: string,
|
|
3
|
+
projectSlug: string,
|
|
4
|
+
apiKey: string,
|
|
5
|
+
uploadSource = true,
|
|
6
|
+
): string {
|
|
7
|
+
// eslint-disable-next-line no-useless-escape
|
|
8
|
+
return `# This script is responsable to upload debug symbols and source context for Sentry.\\nif which sentry-cli >/dev/null; then\\nexport SENTRY_ORG=${orgSlug}\\nexport SENTRY_PROJECT=${projectSlug}\\nexport SENTRY_AUTH_TOKEN=${apiKey}\\nERROR=$(sentry-cli debug-files upload ${uploadSource ? "--include-sources " : ""}\"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\\nif [ ! $? -eq 0 ]; then\\necho \"warning: sentry-cli - $ERROR\"\\nfi\\nelse\\necho \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\\nfi\\n`;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const scriptInputPath = "\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}\"";
|
|
12
|
+
|
|
13
|
+
export function getSwiftSnippet(dsn: string): string {
|
|
14
|
+
return ` SentrySDK.start { options in
|
|
15
|
+
options.dsn = "${dsn}"
|
|
16
|
+
options.debug = true // Enabled debug when first installing is always helpful
|
|
17
|
+
options.enableTracing = true
|
|
18
|
+
|
|
19
|
+
// Uncomment the following lines to add more data to your events
|
|
20
|
+
// options.attachScreenshot = true // This adds a screenshot to the error events
|
|
21
|
+
// options.attachViewHierarchy = true // This adds the view hierarchy to the error events
|
|
22
|
+
}
|
|
23
|
+
// Remove the next line after confirming that your Sentry integration is working.
|
|
24
|
+
SentrySDK.capture(message: "This app uses Sentry! :)")\n`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getObjcSnippet(dsn: string): string {
|
|
28
|
+
return ` [SentrySDK startWithConfigureOptions:^(SentryOptions * options) {
|
|
29
|
+
options.dsn = @"${dsn}";
|
|
30
|
+
options.debug = YES; // Enabled debug when first installing is always helpful
|
|
31
|
+
options.enableTracing = YES;
|
|
32
|
+
|
|
33
|
+
//Uncomment the following lines to add more data to your events
|
|
34
|
+
//options.attachScreenshot = YES; //This will add a screenshot to the error events
|
|
35
|
+
//options.attachViewHierarchy = YES; //This will add the view hierarchy to the error events
|
|
36
|
+
}];
|
|
37
|
+
//Remove the next line after confirming that your Sentry integration is working.
|
|
38
|
+
[SentrySDK captureMessage:@"This app uses Sentry!"];\n`;
|
|
39
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/* eslint-disable max-lines */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
5
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
6
|
+
import { SentryCli } from '../../lib/Helper/SentryCli';
|
|
7
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
8
|
+
import clack from '@clack/prompts';
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
import * as fs from 'fs';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import * as templates from './templates';
|
|
13
|
+
const xcode = require('xcode');
|
|
14
|
+
|
|
15
|
+
import { SentryProjectData } from '../utils/clack-utils';
|
|
16
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
17
|
+
|
|
18
|
+
function setDebugInformationFormat(proj: any): void {
|
|
19
|
+
const xcObjects = proj.hash.project.objects;
|
|
20
|
+
const target = proj.getFirstTarget().firstTarget;
|
|
21
|
+
|
|
22
|
+
xcObjects.XCConfigurationList[target.buildConfigurationList].buildConfigurations.forEach((buildConfig: { value: string }) => {
|
|
23
|
+
xcObjects.XCBuildConfiguration[buildConfig.value].buildSettings.DEBUG_INFORMATION_FORMAT = "\"dwarf-with-dsym\"";
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function addSentrySPM(proj: any): void {
|
|
28
|
+
const xcObjects = proj.hash.project.objects;
|
|
29
|
+
|
|
30
|
+
const sentryFrameworkUUID = proj.generateUuid() as string;
|
|
31
|
+
const sentrySPMUUID = proj.generateUuid() as string;
|
|
32
|
+
|
|
33
|
+
//Check whether xcObjects already have sentry framework
|
|
34
|
+
if (xcObjects.PBXFrameworksBuildPhase) {
|
|
35
|
+
for (const key in xcObjects.PBXFrameworksBuildPhase || {}) {
|
|
36
|
+
if (!key.endsWith("_comment")) {
|
|
37
|
+
const frameworks = xcObjects.PBXFrameworksBuildPhase[key].files;
|
|
38
|
+
for (const framework of frameworks) {
|
|
39
|
+
if (framework.comment === "Sentry in Frameworks") {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
xcObjects.PBXBuildFile[sentryFrameworkUUID] = {
|
|
48
|
+
isa: "PBXBuildFile",
|
|
49
|
+
productRef: sentrySPMUUID,
|
|
50
|
+
productRef_comment: "Sentry",
|
|
51
|
+
};
|
|
52
|
+
xcObjects.PBXBuildFile[sentryFrameworkUUID + "_comment"] = "Sentry in Frameworks";
|
|
53
|
+
|
|
54
|
+
for (const key in xcObjects.PBXFrameworksBuildPhase || {}) {
|
|
55
|
+
if (!key.endsWith("_comment")) {
|
|
56
|
+
const frameworks = xcObjects.PBXFrameworksBuildPhase[key].files;
|
|
57
|
+
frameworks.push({
|
|
58
|
+
value: sentryFrameworkUUID,
|
|
59
|
+
comment: "Sentry in Frameworks",
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const target = proj.getFirstTarget().firstTarget;
|
|
65
|
+
if (!target.packageProductDependencies) {
|
|
66
|
+
target.packageProductDependencies = [];
|
|
67
|
+
}
|
|
68
|
+
target.packageProductDependencies.push({
|
|
69
|
+
value: sentrySPMUUID,
|
|
70
|
+
comment: "Sentry",
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const sentrySwiftPackageUUID = proj.generateUuid() as string;
|
|
74
|
+
const xcProject = proj.getFirstProject().firstProject;
|
|
75
|
+
if (!xcProject.packageReferences) {
|
|
76
|
+
xcProject.packageReferences = [];
|
|
77
|
+
}
|
|
78
|
+
xcProject.packageReferences.push({
|
|
79
|
+
value: sentrySwiftPackageUUID,
|
|
80
|
+
comment: "XCRemoteSwiftPackageReference \"sentry-cocoa\"",
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
xcObjects.XCRemoteSwiftPackageReference = {};
|
|
84
|
+
xcObjects.XCRemoteSwiftPackageReference[sentrySwiftPackageUUID] = {
|
|
85
|
+
isa: "XCRemoteSwiftPackageReference",
|
|
86
|
+
repositoryURL: "\"https://github.com/getsentry/sentry-cocoa/\"",
|
|
87
|
+
requirement: {
|
|
88
|
+
kind: "upToNextMajorVersion",
|
|
89
|
+
minimumVersion: "8.0.0",
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
xcObjects.XCRemoteSwiftPackageReference[sentrySwiftPackageUUID + "_comment"] = "XCRemoteSwiftPackageReference \"sentry-cocoa\"";
|
|
93
|
+
|
|
94
|
+
xcObjects.XCSwiftPackageProductDependency = {};
|
|
95
|
+
xcObjects.XCSwiftPackageProductDependency[sentrySPMUUID] =
|
|
96
|
+
{
|
|
97
|
+
isa: "XCSwiftPackageProductDependency",
|
|
98
|
+
package: sentrySwiftPackageUUID,
|
|
99
|
+
package_comment: "XCRemoteSwiftPackageReference \"sentry-cocoa\"",
|
|
100
|
+
productName: "Sentry",
|
|
101
|
+
};
|
|
102
|
+
xcObjects.XCSwiftPackageProductDependency[sentrySPMUUID + "_comment"] = "Sentry";
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function addUploadSymbolsScript(xcodeProject: any, sentryProject: SentryProjectData, apiKeys: { token: string }, uploadSource = true): void {
|
|
106
|
+
const xcObjects = xcodeProject.hash.project.objects;
|
|
107
|
+
|
|
108
|
+
for (const scriptKey in xcObjects.PBXShellScriptBuildPhase || {}) {
|
|
109
|
+
if (!scriptKey.endsWith("_comment")) {
|
|
110
|
+
const script = xcObjects.PBXShellScriptBuildPhase[scriptKey].shellScript;
|
|
111
|
+
//Sentry script already exists, update it
|
|
112
|
+
if (script.includes("sentry-cli")) {
|
|
113
|
+
delete xcObjects.PBXShellScriptBuildPhase[scriptKey];
|
|
114
|
+
delete xcObjects.PBXShellScriptBuildPhase[scriptKey + "_comment"];
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
xcodeProject.addBuildPhase(
|
|
121
|
+
[],
|
|
122
|
+
'PBXShellScriptBuildPhase',
|
|
123
|
+
'Upload Debug Symbols to Sentry',
|
|
124
|
+
null,
|
|
125
|
+
{
|
|
126
|
+
inputFileListPaths: [],
|
|
127
|
+
outputFileListPaths: [],
|
|
128
|
+
inputPaths: [templates.scriptInputPath],
|
|
129
|
+
shellPath: '/bin/sh',
|
|
130
|
+
shellScript: templates.getRunScriptTemplate(sentryProject.organization.slug, sentryProject.slug, apiKeys.token, uploadSource)
|
|
131
|
+
},
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function updateXcodeProject(projectPath: string, sentryProject: SentryProjectData, apiKeys: { token: string }, addSPMReference: boolean, uploadSource = true): void {
|
|
136
|
+
const proj = xcode.project(projectPath);
|
|
137
|
+
proj.parseSync();
|
|
138
|
+
addUploadSymbolsScript(proj, sentryProject, apiKeys, uploadSource);
|
|
139
|
+
if (uploadSource) {
|
|
140
|
+
setDebugInformationFormat(proj);
|
|
141
|
+
}
|
|
142
|
+
if (addSPMReference) {
|
|
143
|
+
addSentrySPM(proj);
|
|
144
|
+
}
|
|
145
|
+
const newContent = proj.writeSync();
|
|
146
|
+
fs.writeFileSync(projectPath, newContent);
|
|
147
|
+
}
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
ensurePackageIsInstalled,
|
|
19
19
|
getPackageDotJson,
|
|
20
20
|
installPackage,
|
|
21
|
+
isUsingTypeScript,
|
|
21
22
|
printWelcome,
|
|
22
23
|
} from '../utils/clack-utils';
|
|
23
24
|
import { WizardOptions } from '../utils/types';
|
|
@@ -59,14 +60,7 @@ export async function runNextjsWizard(options: WizardOptions): Promise<void> {
|
|
|
59
60
|
alreadyInstalled: !!packageJson?.dependencies?.['@sentry/nextjs'],
|
|
60
61
|
});
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
try {
|
|
64
|
-
isUsingTypescript = fs.existsSync(
|
|
65
|
-
path.join(process.cwd(), 'tsconfig.json'),
|
|
66
|
-
);
|
|
67
|
-
} catch {
|
|
68
|
-
// noop - Default to assuming user is not using typescript
|
|
69
|
-
}
|
|
63
|
+
const typeScriptDetected = isUsingTypeScript();
|
|
70
64
|
|
|
71
65
|
const configVariants = ['server', 'client', 'edge'] as const;
|
|
72
66
|
|
|
@@ -114,7 +108,7 @@ export async function runNextjsWizard(options: WizardOptions): Promise<void> {
|
|
|
114
108
|
|
|
115
109
|
if (shouldWriteFile) {
|
|
116
110
|
await fs.promises.writeFile(
|
|
117
|
-
path.join(process.cwd(),
|
|
111
|
+
path.join(process.cwd(), typeScriptDetected ? tsConfig : jsConfig),
|
|
118
112
|
getSentryConfigContents(
|
|
119
113
|
selectedProject.keys[0].dsn.public,
|
|
120
114
|
configVariant,
|
|
@@ -122,7 +116,9 @@ export async function runNextjsWizard(options: WizardOptions): Promise<void> {
|
|
|
122
116
|
{ encoding: 'utf8', flag: 'w' },
|
|
123
117
|
);
|
|
124
118
|
clack.log.success(
|
|
125
|
-
`Created fresh ${chalk.bold(
|
|
119
|
+
`Created fresh ${chalk.bold(
|
|
120
|
+
typeScriptDetected ? tsConfig : jsConfig,
|
|
121
|
+
)}.`,
|
|
126
122
|
);
|
|
127
123
|
}
|
|
128
124
|
}
|