@sentry/wizard 3.39.0 → 3.41.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 +12 -1
- package/README.md +21 -21
- package/bin.ts +5 -0
- package/codecov.yml +15 -0
- package/dist/bin.js +4 -0
- package/dist/bin.js.map +1 -1
- package/dist/e2e-tests/jest.config.d.ts +1 -0
- package/dist/e2e-tests/jest.config.js +1 -0
- package/dist/e2e-tests/jest.config.js.map +1 -1
- package/dist/e2e-tests/tests/flutter.test.d.ts +1 -0
- package/dist/e2e-tests/tests/flutter.test.js +190 -0
- package/dist/e2e-tests/tests/flutter.test.js.map +1 -0
- package/dist/e2e-tests/utils/index.d.ts +11 -0
- package/dist/e2e-tests/utils/index.js +36 -1
- package/dist/e2e-tests/utils/index.js.map +1 -1
- package/dist/lib/Constants.d.ts +1 -0
- package/dist/lib/Constants.js +5 -0
- package/dist/lib/Constants.js.map +1 -1
- package/dist/package.json +3 -2
- package/dist/src/apple/apple-wizard.js +2 -3
- package/dist/src/apple/apple-wizard.js.map +1 -1
- package/dist/src/apple/code-tools.d.ts +10 -0
- package/dist/src/apple/code-tools.js +16 -12
- package/dist/src/apple/code-tools.js.map +1 -1
- package/dist/src/apple/fastlane.d.ts +23 -0
- package/dist/src/apple/fastlane.js +11 -7
- package/dist/src/apple/fastlane.js.map +1 -1
- package/dist/src/apple/templates.d.ts +1 -1
- package/dist/src/apple/templates.js +0 -2
- package/dist/src/apple/templates.js.map +1 -1
- package/dist/src/apple/xcode-manager.d.ts +13 -9
- package/dist/src/apple/xcode-manager.js +146 -61
- package/dist/src/apple/xcode-manager.js.map +1 -1
- package/dist/src/flutter/code-tools.d.ts +17 -0
- package/dist/src/flutter/code-tools.js +263 -0
- package/dist/src/flutter/code-tools.js.map +1 -0
- package/dist/src/flutter/flutter-wizard.d.ts +2 -0
- package/dist/src/flutter/flutter-wizard.js +171 -0
- package/dist/src/flutter/flutter-wizard.js.map +1 -0
- package/dist/src/flutter/templates.d.ts +9 -0
- package/dist/src/flutter/templates.js +40 -0
- package/dist/src/flutter/templates.js.map +1 -0
- package/dist/src/nextjs/nextjs-wizard.js +5 -3
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/nuxt/nuxt-wizard.js +6 -4
- package/dist/src/nuxt/nuxt-wizard.js.map +1 -1
- package/dist/src/nuxt/sdk-setup.d.ts +1 -1
- package/dist/src/nuxt/sdk-setup.js +2 -1
- package/dist/src/nuxt/sdk-setup.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.js +5 -3
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/remix/remix-wizard.js +5 -3
- package/dist/src/remix/remix-wizard.js.map +1 -1
- package/dist/src/run.d.ts +2 -1
- package/dist/src/run.js +40 -32
- package/dist/src/run.js.map +1 -1
- package/dist/src/sveltekit/sveltekit-wizard.js +5 -3
- package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
- package/dist/src/utils/clack-utils.d.ts +4 -2
- package/dist/src/utils/clack-utils.js +18 -12
- package/dist/src/utils/clack-utils.js.map +1 -1
- package/dist/src/utils/package-manager.d.ts +1 -0
- package/dist/src/utils/package-manager.js +5 -0
- package/dist/src/utils/package-manager.js.map +1 -1
- package/dist/src/utils/types.d.ts +9 -0
- package/dist/src/utils/types.js.map +1 -1
- package/dist/test/apple/cocoapod.test.d.ts +1 -0
- package/dist/test/apple/cocoapod.test.js +409 -0
- package/dist/test/apple/cocoapod.test.js.map +1 -0
- package/dist/test/apple/code-tools.test.d.ts +1 -0
- package/dist/test/apple/code-tools.test.js +673 -0
- package/dist/test/apple/code-tools.test.js.map +1 -0
- package/dist/test/apple/fastfile.test.d.ts +1 -0
- package/dist/test/apple/fastfile.test.js +431 -0
- package/dist/test/apple/fastfile.test.js.map +1 -0
- package/dist/test/apple/templates.test.d.ts +1 -0
- package/dist/test/apple/templates.test.js +73 -0
- package/dist/test/apple/templates.test.js.map +1 -0
- package/dist/test/apple/xcode-manager.test.d.ts +1 -0
- package/dist/test/apple/xcode-manager.test.js +834 -0
- package/dist/test/apple/xcode-manager.test.js.map +1 -0
- package/dist/test/flutter/code-tools.test.d.ts +1 -0
- package/dist/test/flutter/code-tools.test.js +84 -0
- package/dist/test/flutter/code-tools.test.js.map +1 -0
- package/dist/test/flutter/templates.test.d.ts +1 -0
- package/dist/test/flutter/templates.test.js +41 -0
- package/dist/test/flutter/templates.test.js.map +1 -0
- package/dist/test/utils/clack-utils.test.js +89 -0
- package/dist/test/utils/clack-utils.test.js.map +1 -1
- package/e2e-tests/README.md +5 -1
- package/e2e-tests/jest.config.ts +1 -0
- package/e2e-tests/test-applications/apple/damaged-missing-configuration-list/Project.xcodeproj/project.pbxproj +52 -0
- package/e2e-tests/test-applications/apple/damaged-missing-configuration-list/Project.xcodeproj/xcshareddata/xcschemes/Project1.xcscheme +78 -0
- package/e2e-tests/test-applications/apple/no-targets/Project.xcodeproj/project.pbxproj +62 -0
- package/e2e-tests/test-applications/apple/no-targets/Project.xcodeproj/xcshareddata/xcschemes/Project1.xcscheme +78 -0
- package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project.xcodeproj/project.pbxproj +470 -0
- package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project.xcodeproj/xcshareddata/xcschemes/Project1.xcscheme +78 -0
- package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project1/ContentView.swift +7 -0
- package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project1/Project1App.swift +10 -0
- package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project2/ContentView.swift +7 -0
- package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project2/Project2App.swift +10 -0
- package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Project.xcodeproj/project.pbxproj +382 -0
- package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Project.xcodeproj/xcshareddata/xcschemes/Project.xcscheme +78 -0
- package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Sources/ContentView.swift +7 -0
- package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Sources/MainApp.swift +10 -0
- package/e2e-tests/test-applications/flutter-test-app/.metadata +45 -0
- package/e2e-tests/test-applications/flutter-test-app/README.md +16 -0
- package/e2e-tests/test-applications/flutter-test-app/analysis_options.yaml +28 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/build.gradle +44 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/debug/AndroidManifest.xml +7 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/AndroidManifest.xml +45 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/kotlin/com/example/flutter_magic/MainActivity.kt +5 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/drawable/launch_background.xml +12 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/drawable-v21/launch_background.xml +12 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/values/styles.xml +18 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/values-night/styles.xml +18 -0
- package/e2e-tests/test-applications/flutter-test-app/android/app/src/profile/AndroidManifest.xml +7 -0
- package/e2e-tests/test-applications/flutter-test-app/android/build.gradle +18 -0
- package/e2e-tests/test-applications/flutter-test-app/android/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/e2e-tests/test-applications/flutter-test-app/android/gradle.properties +3 -0
- package/e2e-tests/test-applications/flutter-test-app/android/settings.gradle +25 -0
- package/e2e-tests/test-applications/flutter-test-app/lib/main.dart +125 -0
- package/e2e-tests/test-applications/flutter-test-app/linux/CMakeLists.txt +145 -0
- package/e2e-tests/test-applications/flutter-test-app/linux/flutter/CMakeLists.txt +88 -0
- package/e2e-tests/test-applications/flutter-test-app/linux/flutter/generated_plugin_registrant.cc +11 -0
- package/e2e-tests/test-applications/flutter-test-app/linux/flutter/generated_plugin_registrant.h +15 -0
- package/e2e-tests/test-applications/flutter-test-app/linux/flutter/generated_plugins.cmake +23 -0
- package/e2e-tests/test-applications/flutter-test-app/linux/main.cc +6 -0
- package/e2e-tests/test-applications/flutter-test-app/linux/my_application.cc +124 -0
- package/e2e-tests/test-applications/flutter-test-app/linux/my_application.h +18 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Flutter/Flutter-Debug.xcconfig +2 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Flutter/Flutter-Release.xcconfig +2 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Flutter/GeneratedPluginRegistrant.swift +10 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Podfile +43 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/AppDelegate.swift +9 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Base.lproj/MainMenu.xib +343 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/AppInfo.xcconfig +14 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/Debug.xcconfig +2 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/Release.xcconfig +2 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/Warnings.xcconfig +13 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/DebugProfile.entitlements +12 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Info.plist +32 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/MainFlutterWindow.swift +15 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Release.entitlements +8 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcodeproj/project.pbxproj +705 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +98 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcworkspace/contents.xcworkspacedata +7 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/e2e-tests/test-applications/flutter-test-app/macos/RunnerTests/RunnerTests.swift +12 -0
- package/e2e-tests/test-applications/flutter-test-app/pubspec.lock +213 -0
- package/e2e-tests/test-applications/flutter-test-app/pubspec.yaml +89 -0
- package/e2e-tests/test-applications/flutter-test-app/test/widget_test.dart +30 -0
- package/e2e-tests/test-applications/flutter-test-app/web/favicon.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-192.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-512.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-maskable-192.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-maskable-512.png +0 -0
- package/e2e-tests/test-applications/flutter-test-app/web/index.html +38 -0
- package/e2e-tests/test-applications/flutter-test-app/web/manifest.json +35 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/CMakeLists.txt +108 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/flutter/CMakeLists.txt +109 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/flutter/generated_plugin_registrant.cc +11 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/flutter/generated_plugin_registrant.h +15 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/flutter/generated_plugins.cmake +23 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/CMakeLists.txt +40 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/Runner.rc +121 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/flutter_window.cpp +71 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/flutter_window.h +33 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/main.cpp +43 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/resource.h +16 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/resources/app_icon.ico +0 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/runner.exe.manifest +14 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/utils.cpp +65 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/utils.h +19 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/win32_window.cpp +288 -0
- package/e2e-tests/test-applications/flutter-test-app/windows/runner/win32_window.h +102 -0
- package/e2e-tests/tests/flutter.test.ts +127 -0
- package/e2e-tests/utils/index.ts +33 -0
- package/lib/Constants.ts +5 -0
- package/package.json +3 -2
- package/src/apple/apple-wizard.ts +2 -3
- package/src/apple/code-tools.ts +21 -6
- package/src/apple/fastlane.ts +18 -2
- package/src/apple/templates.ts +2 -2
- package/src/apple/xcode-manager.ts +186 -99
- package/src/flutter/code-tools.ts +284 -0
- package/src/flutter/flutter-wizard.ts +164 -0
- package/src/flutter/templates.ts +90 -0
- package/src/nextjs/nextjs-wizard.ts +5 -2
- package/src/nuxt/nuxt-wizard.ts +6 -3
- package/src/nuxt/sdk-setup.ts +2 -0
- package/src/react-native/react-native-wizard.ts +5 -2
- package/src/remix/remix-wizard.ts +5 -2
- package/src/run.ts +9 -0
- package/src/sveltekit/sveltekit-wizard.ts +5 -2
- package/src/utils/clack-utils.ts +16 -4
- package/src/utils/package-manager.ts +6 -0
- package/src/utils/types.ts +10 -0
- package/test/apple/cocoapod.test.ts +306 -0
- package/test/apple/code-tools.test.ts +1042 -0
- package/test/apple/fastfile.test.ts +550 -0
- package/test/apple/templates.test.ts +191 -0
- package/test/apple/xcode-manager.test.ts +1066 -0
- package/test/flutter/code-tools.test.ts +212 -0
- package/test/flutter/templates.test.ts +100 -0
- package/test/utils/clack-utils.test.ts +92 -0
- package/types/xcode.d.ts +526 -0
package/src/run.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { runReactNativeWizard } from './react-native/react-native-wizard';
|
|
|
5
5
|
|
|
6
6
|
import { run as legacyRun } from '../lib/Setup';
|
|
7
7
|
import type { PreselectedProject, WizardOptions } from './utils/types';
|
|
8
|
+
import { runFlutterWizard } from './flutter/flutter-wizard';
|
|
8
9
|
import { runAndroidWizard } from './android/android-wizard';
|
|
9
10
|
import { runAppleWizard } from './apple/apple-wizard';
|
|
10
11
|
import { runNextjsWizard } from './nextjs/nextjs-wizard';
|
|
@@ -18,6 +19,7 @@ import type { PackageDotJson } from './utils/package-json';
|
|
|
18
19
|
|
|
19
20
|
type WizardIntegration =
|
|
20
21
|
| 'reactNative'
|
|
22
|
+
| 'flutter'
|
|
21
23
|
| 'ios'
|
|
22
24
|
| 'android'
|
|
23
25
|
| 'cordova'
|
|
@@ -54,6 +56,7 @@ type Args = {
|
|
|
54
56
|
org?: string;
|
|
55
57
|
project?: string;
|
|
56
58
|
saas?: boolean;
|
|
59
|
+
forceInstall?: boolean;
|
|
57
60
|
};
|
|
58
61
|
|
|
59
62
|
function preSelectedProjectArgsToObject(
|
|
@@ -100,6 +103,7 @@ export async function run(argv: Args) {
|
|
|
100
103
|
message: 'What do you want to set up?',
|
|
101
104
|
options: [
|
|
102
105
|
{ value: 'reactNative', label: 'React Native' },
|
|
106
|
+
{ value: 'flutter', label: 'Flutter' },
|
|
103
107
|
{ value: 'ios', label: 'iOS' },
|
|
104
108
|
{ value: 'android', label: 'Android' },
|
|
105
109
|
{ value: 'cordova', label: 'Cordova' },
|
|
@@ -129,6 +133,7 @@ export async function run(argv: Args) {
|
|
|
129
133
|
projectSlug: finalArgs.project,
|
|
130
134
|
saas: finalArgs.saas,
|
|
131
135
|
preSelectedProject: preSelectedProjectArgsToObject(finalArgs),
|
|
136
|
+
forceInstall: finalArgs.forceInstall,
|
|
132
137
|
};
|
|
133
138
|
|
|
134
139
|
switch (integration) {
|
|
@@ -139,6 +144,10 @@ export async function run(argv: Args) {
|
|
|
139
144
|
});
|
|
140
145
|
break;
|
|
141
146
|
|
|
147
|
+
case 'flutter':
|
|
148
|
+
await runFlutterWizard(wizardOptions);
|
|
149
|
+
break;
|
|
150
|
+
|
|
142
151
|
case 'ios':
|
|
143
152
|
await runAppleWizard(wizardOptions);
|
|
144
153
|
break;
|
|
@@ -41,10 +41,12 @@ export async function runSvelteKitWizard(
|
|
|
41
41
|
export async function runSvelteKitWizardWithTelemetry(
|
|
42
42
|
options: WizardOptions,
|
|
43
43
|
): Promise<void> {
|
|
44
|
+
const { promoCode, telemetryEnabled, forceInstall } = options;
|
|
45
|
+
|
|
44
46
|
printWelcome({
|
|
45
47
|
wizardName: 'Sentry SvelteKit Wizard',
|
|
46
|
-
promoCode
|
|
47
|
-
telemetryEnabled
|
|
48
|
+
promoCode,
|
|
49
|
+
telemetryEnabled,
|
|
48
50
|
});
|
|
49
51
|
|
|
50
52
|
await confirmContinueIfNoOrDirtyGitRepo();
|
|
@@ -98,6 +100,7 @@ export async function runSvelteKitWizardWithTelemetry(
|
|
|
98
100
|
packageName: '@sentry/sveltekit@^8',
|
|
99
101
|
packageNameDisplayLabel: '@sentry/sveltekit',
|
|
100
102
|
alreadyInstalled: sdkAlreadyInstalled,
|
|
103
|
+
forceInstall,
|
|
101
104
|
});
|
|
102
105
|
|
|
103
106
|
await addDotEnvSentryBuildPluginFile(authToken);
|
package/src/utils/clack-utils.ts
CHANGED
|
@@ -207,6 +207,8 @@ export async function confirmContinueIfNoOrDirtyGitRepo(): Promise<void> {
|
|
|
207
207
|
if (!continueWithoutGit) {
|
|
208
208
|
await abort(undefined, 0);
|
|
209
209
|
}
|
|
210
|
+
// return early to avoid checking for uncommitted files
|
|
211
|
+
return;
|
|
210
212
|
}
|
|
211
213
|
|
|
212
214
|
const uncommittedOrUntrackedFiles = getUncommittedOrUntrackedFiles();
|
|
@@ -247,7 +249,10 @@ export function isInGitRepo() {
|
|
|
247
249
|
export function getUncommittedOrUntrackedFiles(): string[] {
|
|
248
250
|
try {
|
|
249
251
|
const gitStatus = childProcess
|
|
250
|
-
.execSync('git status --porcelain=v1'
|
|
252
|
+
.execSync('git status --porcelain=v1', {
|
|
253
|
+
// we only care about stdout
|
|
254
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
255
|
+
})
|
|
251
256
|
.toString();
|
|
252
257
|
|
|
253
258
|
const files = gitStatus
|
|
@@ -356,6 +361,7 @@ export async function installPackage({
|
|
|
356
361
|
askBeforeUpdating = true,
|
|
357
362
|
packageNameDisplayLabel,
|
|
358
363
|
packageManager,
|
|
364
|
+
forceInstall = false,
|
|
359
365
|
}: {
|
|
360
366
|
/** The string that is passed to the package manager CLI as identifier to install (e.g. `@sentry/nextjs`, or `@sentry/nextjs@^8`) */
|
|
361
367
|
packageName: string;
|
|
@@ -364,6 +370,8 @@ export async function installPackage({
|
|
|
364
370
|
/** Overrides what is shown in the installation logs in place of the `packageName` option. Useful if the `packageName` is ugly (e.g. `@sentry/nextjs@^8`) */
|
|
365
371
|
packageNameDisplayLabel?: string;
|
|
366
372
|
packageManager?: PackageManager;
|
|
373
|
+
/** Add force install flag to command to skip install precondition fails */
|
|
374
|
+
forceInstall?: boolean;
|
|
367
375
|
}): Promise<{ packageManager?: PackageManager }> {
|
|
368
376
|
return traceStep('install-package', async () => {
|
|
369
377
|
if (alreadyInstalled && askBeforeUpdating) {
|
|
@@ -393,7 +401,9 @@ export async function installPackage({
|
|
|
393
401
|
try {
|
|
394
402
|
await new Promise<void>((resolve, reject) => {
|
|
395
403
|
childProcess.exec(
|
|
396
|
-
`${pkgManager.installCommand} ${packageName} ${pkgManager.flags}
|
|
404
|
+
`${pkgManager.installCommand} ${packageName} ${pkgManager.flags} ${
|
|
405
|
+
forceInstall ? pkgManager.forceInstallFlag : ''
|
|
406
|
+
}`,
|
|
397
407
|
(err, stdout, stderr) => {
|
|
398
408
|
if (err) {
|
|
399
409
|
// Write a log file so we can better troubleshoot issues
|
|
@@ -881,7 +891,8 @@ export async function getOrAskForProjectData(
|
|
|
881
891
|
| 'javascript-sveltekit'
|
|
882
892
|
| 'apple-ios'
|
|
883
893
|
| 'android'
|
|
884
|
-
| 'react-native'
|
|
894
|
+
| 'react-native'
|
|
895
|
+
| 'flutter',
|
|
885
896
|
): Promise<{
|
|
886
897
|
sentryUrl: string;
|
|
887
898
|
selfHosted: boolean;
|
|
@@ -1043,7 +1054,8 @@ async function askForWizardLogin(options: {
|
|
|
1043
1054
|
| 'javascript-sveltekit'
|
|
1044
1055
|
| 'apple-ios'
|
|
1045
1056
|
| 'android'
|
|
1046
|
-
| 'react-native'
|
|
1057
|
+
| 'react-native'
|
|
1058
|
+
| 'flutter';
|
|
1047
1059
|
orgSlug?: string;
|
|
1048
1060
|
projectSlug?: string;
|
|
1049
1061
|
}): Promise<WizardProjectData> {
|
|
@@ -14,6 +14,7 @@ export interface PackageManager {
|
|
|
14
14
|
/* The command that the package manager uses to run a script from package.json */
|
|
15
15
|
runScriptCommand: string;
|
|
16
16
|
flags: string;
|
|
17
|
+
forceInstallFlag: string;
|
|
17
18
|
detect: () => boolean;
|
|
18
19
|
addOverride: (pkgName: string, pkgVersion: string) => Promise<void>;
|
|
19
20
|
}
|
|
@@ -25,6 +26,7 @@ export const BUN: PackageManager = {
|
|
|
25
26
|
buildCommand: 'bun run build',
|
|
26
27
|
runScriptCommand: 'bun run',
|
|
27
28
|
flags: '',
|
|
29
|
+
forceInstallFlag: '--force',
|
|
28
30
|
detect: () =>
|
|
29
31
|
['bun.lockb', 'bun.lock'].some((lockFile) =>
|
|
30
32
|
fs.existsSync(path.join(process.cwd(), lockFile)),
|
|
@@ -49,6 +51,7 @@ export const YARN_V1: PackageManager = {
|
|
|
49
51
|
buildCommand: 'yarn build',
|
|
50
52
|
runScriptCommand: 'yarn',
|
|
51
53
|
flags: '--ignore-workspace-root-check',
|
|
54
|
+
forceInstallFlag: '--force',
|
|
52
55
|
detect: () => {
|
|
53
56
|
try {
|
|
54
57
|
return fs
|
|
@@ -80,6 +83,7 @@ export const YARN_V2: PackageManager = {
|
|
|
80
83
|
buildCommand: 'yarn build',
|
|
81
84
|
runScriptCommand: 'yarn',
|
|
82
85
|
flags: '',
|
|
86
|
+
forceInstallFlag: '--force',
|
|
83
87
|
detect: () => {
|
|
84
88
|
try {
|
|
85
89
|
return fs
|
|
@@ -110,6 +114,7 @@ export const PNPM: PackageManager = {
|
|
|
110
114
|
buildCommand: 'pnpm build',
|
|
111
115
|
runScriptCommand: 'pnpm',
|
|
112
116
|
flags: '--ignore-workspace-root-check',
|
|
117
|
+
forceInstallFlag: '--force',
|
|
113
118
|
detect: () => fs.existsSync(path.join(process.cwd(), 'pnpm-lock.yaml')),
|
|
114
119
|
addOverride: async (pkgName, pkgVersion): Promise<void> => {
|
|
115
120
|
const packageDotJson = await getPackageDotJson();
|
|
@@ -135,6 +140,7 @@ export const NPM: PackageManager = {
|
|
|
135
140
|
buildCommand: 'npm run build',
|
|
136
141
|
runScriptCommand: 'npm run',
|
|
137
142
|
flags: '',
|
|
143
|
+
forceInstallFlag: '--force',
|
|
138
144
|
detect: () => fs.existsSync(path.join(process.cwd(), 'package-lock.json')),
|
|
139
145
|
addOverride: async (pkgName, pkgVersion): Promise<void> => {
|
|
140
146
|
const packageDotJson = await getPackageDotJson();
|
package/src/utils/types.ts
CHANGED
|
@@ -57,6 +57,16 @@ export type WizardOptions = {
|
|
|
57
57
|
* If this is set, the wizard will skip the login and project selection step.
|
|
58
58
|
*/
|
|
59
59
|
preSelectedProject?: PreselectedProject;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Force-install the SDK package to continue with the installation in case
|
|
63
|
+
* any package manager checks are failing (e.g. peer dependency versions).
|
|
64
|
+
*
|
|
65
|
+
* Use with caution and only if you know what you're doing.
|
|
66
|
+
*
|
|
67
|
+
* Does not apply to all wizard flows (currently NPM only)
|
|
68
|
+
*/
|
|
69
|
+
forceInstall?: boolean;
|
|
60
70
|
};
|
|
61
71
|
|
|
62
72
|
export interface Feature {
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/node';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import {
|
|
6
|
+
addCocoaPods,
|
|
7
|
+
podInstall,
|
|
8
|
+
usesCocoaPod,
|
|
9
|
+
} from '../../src/apple/cocoapod';
|
|
10
|
+
import * as bash from '../../src/utils/bash';
|
|
11
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
12
|
+
import * as clack from '@clack/prompts';
|
|
13
|
+
|
|
14
|
+
jest.mock('../../src/utils/bash');
|
|
15
|
+
jest.spyOn(Sentry, 'setTag').mockImplementation();
|
|
16
|
+
jest.spyOn(Sentry, 'captureException').mockImplementation();
|
|
17
|
+
|
|
18
|
+
const clackSpinnerMock = {
|
|
19
|
+
start: jest.fn(),
|
|
20
|
+
stop: jest.fn(),
|
|
21
|
+
message: jest.fn(),
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
describe('cocoapod', () => {
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
jest.spyOn(clack, 'spinner').mockReturnValue(clackSpinnerMock);
|
|
27
|
+
jest.spyOn(clack.log, 'error').mockImplementation();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
jest.clearAllMocks();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('usesCocoaPod', () => {
|
|
35
|
+
describe('Podfile exists', () => {
|
|
36
|
+
it('should return true', () => {
|
|
37
|
+
// -- Arrange --
|
|
38
|
+
const projPath = path.join(os.tmpdir(), 'test-project-with-podfile');
|
|
39
|
+
const tempDir = fs.mkdtempSync(projPath);
|
|
40
|
+
|
|
41
|
+
const podfile = path.join(tempDir, 'Podfile');
|
|
42
|
+
fs.writeFileSync(podfile, '');
|
|
43
|
+
|
|
44
|
+
// -- Act --
|
|
45
|
+
const result = usesCocoaPod(tempDir);
|
|
46
|
+
|
|
47
|
+
// -- Assert --
|
|
48
|
+
expect(result).toBeTruthy();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('Podfile does not exist', () => {
|
|
53
|
+
it('should return false', () => {
|
|
54
|
+
// -- Arrange --
|
|
55
|
+
const projPath = path.join(os.tmpdir(), 'test-project-without-podfile');
|
|
56
|
+
const tempDir = fs.mkdtempSync(projPath);
|
|
57
|
+
|
|
58
|
+
// -- Act --
|
|
59
|
+
const result = usesCocoaPod(tempDir);
|
|
60
|
+
|
|
61
|
+
// -- Assert --
|
|
62
|
+
expect(result).toBeFalsy();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('addCocoaPods', () => {
|
|
68
|
+
describe('Podfile does not exist', () => {
|
|
69
|
+
it('should throw an error', async () => {
|
|
70
|
+
// -- Arrange --
|
|
71
|
+
const projPath = path.join(os.tmpdir(), 'test-project-without-podfile');
|
|
72
|
+
const tempDir = fs.mkdtempSync(projPath);
|
|
73
|
+
|
|
74
|
+
// -- Act & Assert --
|
|
75
|
+
await expect(addCocoaPods(tempDir)).rejects.toThrow(
|
|
76
|
+
'ENOENT: no such file or directory, open',
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('Podfile exists', () => {
|
|
82
|
+
describe('Podfile includes Sentry pod', () => {
|
|
83
|
+
const variations = [
|
|
84
|
+
{
|
|
85
|
+
case: 'simple',
|
|
86
|
+
content: 'pod "Sentry"',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
case: 'with-swiftui',
|
|
90
|
+
content: 'pod "SentrySwiftUI"',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
case: 'leading-space',
|
|
94
|
+
content: ' pod "Sentry"',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
case: 'leading-space-and-swiftui',
|
|
98
|
+
content: ' pod "SentrySwiftUI"',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
case: 'trailing-space',
|
|
102
|
+
content: 'pod "Sentry" ',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
case: 'trailing-space-and-swiftui',
|
|
106
|
+
content: 'pod "SentrySwiftUI" ',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
case: 'single-quotes',
|
|
110
|
+
content: "pod 'Sentry'",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
case: 'double-quotes',
|
|
114
|
+
content: 'pod "Sentry"',
|
|
115
|
+
},
|
|
116
|
+
];
|
|
117
|
+
for (const variation of variations) {
|
|
118
|
+
it(`should not change the Podfile for ${variation.case}`, async () => {
|
|
119
|
+
// -- Arrange --
|
|
120
|
+
const projPath = fs.mkdtempSync(path.join(os.tmpdir(), 'project'));
|
|
121
|
+
fs.mkdirSync(projPath, {
|
|
122
|
+
recursive: true,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const podfile = path.join(projPath, 'Podfile');
|
|
126
|
+
fs.writeFileSync(podfile, variation.content, 'utf8');
|
|
127
|
+
|
|
128
|
+
// -- Act --
|
|
129
|
+
const result = await addCocoaPods(projPath);
|
|
130
|
+
|
|
131
|
+
// -- Assert --
|
|
132
|
+
expect(result).toBeTruthy();
|
|
133
|
+
expect(fs.readFileSync(podfile, 'utf8')).toBe(variation.content);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe('Podfile includes no other pods', () => {
|
|
139
|
+
describe('Podfile does not include use_frameworks!', () => {
|
|
140
|
+
it('should not change the Podfile', async () => {
|
|
141
|
+
// -- Arrange --
|
|
142
|
+
const projPath = fs.mkdtempSync(path.join(os.tmpdir(), 'project'));
|
|
143
|
+
fs.mkdirSync(projPath, {
|
|
144
|
+
recursive: true,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const podfile = path.join(projPath, 'Podfile');
|
|
148
|
+
fs.writeFileSync(podfile, '', 'utf8');
|
|
149
|
+
|
|
150
|
+
// -- Act --
|
|
151
|
+
const result = await addCocoaPods(projPath);
|
|
152
|
+
|
|
153
|
+
// -- Assert --
|
|
154
|
+
expect(result).toBeFalsy();
|
|
155
|
+
expect(fs.readFileSync(podfile, 'utf8')).toBe('');
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
describe('Podfile includes use_frameworks!', () => {
|
|
160
|
+
it('should change the Podfile', async () => {
|
|
161
|
+
// -- Arrange --
|
|
162
|
+
const projPath = fs.mkdtempSync(path.join(os.tmpdir(), 'project'));
|
|
163
|
+
fs.mkdirSync(projPath, {
|
|
164
|
+
recursive: true,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const podfile = path.join(projPath, 'Podfile');
|
|
168
|
+
fs.writeFileSync(podfile, `use_frameworks!`, 'utf8');
|
|
169
|
+
|
|
170
|
+
// -- Act --
|
|
171
|
+
const result = await addCocoaPods(projPath);
|
|
172
|
+
|
|
173
|
+
// -- Assert --
|
|
174
|
+
expect(result).toBeTruthy();
|
|
175
|
+
expect(fs.readFileSync(podfile, 'utf8')).toBe(
|
|
176
|
+
`use_frameworks!\npod 'Sentry'\n`,
|
|
177
|
+
);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
describe('Podfile includes other pods', () => {
|
|
183
|
+
it('should append Sentry pod after last pod', async () => {
|
|
184
|
+
// -- Arrange --
|
|
185
|
+
const projPath = fs.mkdtempSync(path.join(os.tmpdir(), 'project'));
|
|
186
|
+
fs.mkdirSync(projPath, {
|
|
187
|
+
recursive: true,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const podfile = path.join(projPath, 'Podfile');
|
|
191
|
+
fs.writeFileSync(podfile, 'pod "OtherPod"', 'utf8');
|
|
192
|
+
|
|
193
|
+
// -- Act --
|
|
194
|
+
const result = await addCocoaPods(projPath);
|
|
195
|
+
|
|
196
|
+
// -- Assert --
|
|
197
|
+
expect(result).toBeTruthy();
|
|
198
|
+
expect(fs.readFileSync(podfile, 'utf8')).toBe(
|
|
199
|
+
`pod "OtherPod"\npod 'Sentry'\n`,
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
describe('podInstall', () => {
|
|
207
|
+
let workDir: string;
|
|
208
|
+
|
|
209
|
+
beforeEach(() => {
|
|
210
|
+
workDir = path.join(os.tmpdir(), 'test-project');
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
describe('any bash scripts fail', () => {
|
|
214
|
+
beforeEach(() => {
|
|
215
|
+
jest.spyOn(bash, 'execute').mockRejectedValue(new Error('test error'));
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('should not throw an error', async () => {
|
|
219
|
+
// -- Act & Assert --
|
|
220
|
+
await expect(podInstall(workDir)).resolves.not.toThrow();
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('should set tag', async () => {
|
|
224
|
+
// -- Act --
|
|
225
|
+
await podInstall(workDir);
|
|
226
|
+
|
|
227
|
+
// -- Assert --
|
|
228
|
+
expect(Sentry.setTag).toHaveBeenCalledWith('pods-installed', false);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('should capture exception', async () => {
|
|
232
|
+
// -- Act --
|
|
233
|
+
await podInstall(workDir);
|
|
234
|
+
|
|
235
|
+
// -- Assert --
|
|
236
|
+
expect(Sentry.captureException).toHaveBeenCalledWith(
|
|
237
|
+
'Sentry pod install failed.',
|
|
238
|
+
);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('should start and stop spinner', async () => {
|
|
242
|
+
// -- Act --
|
|
243
|
+
await podInstall(workDir);
|
|
244
|
+
|
|
245
|
+
// -- Assert --
|
|
246
|
+
expect(clackSpinnerMock.start).toHaveBeenCalledWith(
|
|
247
|
+
"Running 'pod install'. This may take a few minutes...",
|
|
248
|
+
);
|
|
249
|
+
expect(clackSpinnerMock.stop).toHaveBeenCalledWith(
|
|
250
|
+
'Failed to install pods.',
|
|
251
|
+
);
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
describe('all bash scripts work', () => {
|
|
256
|
+
beforeEach(() => {
|
|
257
|
+
jest.spyOn(bash, 'execute').mockResolvedValue('');
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('should call pod update and install', async () => {
|
|
261
|
+
// -- Act --
|
|
262
|
+
await podInstall(workDir);
|
|
263
|
+
|
|
264
|
+
// -- Assert --
|
|
265
|
+
expect(bash.execute).toHaveBeenCalledWith(
|
|
266
|
+
`cd ${workDir} && pod repo update`,
|
|
267
|
+
);
|
|
268
|
+
expect(bash.execute).toHaveBeenCalledWith(
|
|
269
|
+
`cd ${workDir} && pod install --silent`,
|
|
270
|
+
);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it('should set tag', async () => {
|
|
274
|
+
// -- Act --
|
|
275
|
+
await podInstall(workDir);
|
|
276
|
+
|
|
277
|
+
// -- Assert --
|
|
278
|
+
expect(Sentry.setTag).toHaveBeenCalledWith('pods-installed', true);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it('should start and stop spinner', async () => {
|
|
282
|
+
// -- Act --
|
|
283
|
+
await podInstall(workDir);
|
|
284
|
+
|
|
285
|
+
// -- Assert --
|
|
286
|
+
expect(clackSpinnerMock.start).toHaveBeenCalledWith(
|
|
287
|
+
"Running 'pod install'. This may take a few minutes...",
|
|
288
|
+
);
|
|
289
|
+
expect(clackSpinnerMock.stop).toHaveBeenCalledWith('Pods installed.');
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
describe('dir not given', () => {
|
|
294
|
+
it('should use current directory', async () => {
|
|
295
|
+
// -- Act --
|
|
296
|
+
await podInstall();
|
|
297
|
+
|
|
298
|
+
// -- Assert --
|
|
299
|
+
expect(bash.execute).toHaveBeenCalledWith(`cd . && pod repo update`);
|
|
300
|
+
expect(bash.execute).toHaveBeenCalledWith(
|
|
301
|
+
`cd . && pod install --silent`,
|
|
302
|
+
);
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
});
|