@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.
Files changed (221) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/README.md +21 -21
  3. package/bin.ts +5 -0
  4. package/codecov.yml +15 -0
  5. package/dist/bin.js +4 -0
  6. package/dist/bin.js.map +1 -1
  7. package/dist/e2e-tests/jest.config.d.ts +1 -0
  8. package/dist/e2e-tests/jest.config.js +1 -0
  9. package/dist/e2e-tests/jest.config.js.map +1 -1
  10. package/dist/e2e-tests/tests/flutter.test.d.ts +1 -0
  11. package/dist/e2e-tests/tests/flutter.test.js +190 -0
  12. package/dist/e2e-tests/tests/flutter.test.js.map +1 -0
  13. package/dist/e2e-tests/utils/index.d.ts +11 -0
  14. package/dist/e2e-tests/utils/index.js +36 -1
  15. package/dist/e2e-tests/utils/index.js.map +1 -1
  16. package/dist/lib/Constants.d.ts +1 -0
  17. package/dist/lib/Constants.js +5 -0
  18. package/dist/lib/Constants.js.map +1 -1
  19. package/dist/package.json +3 -2
  20. package/dist/src/apple/apple-wizard.js +2 -3
  21. package/dist/src/apple/apple-wizard.js.map +1 -1
  22. package/dist/src/apple/code-tools.d.ts +10 -0
  23. package/dist/src/apple/code-tools.js +16 -12
  24. package/dist/src/apple/code-tools.js.map +1 -1
  25. package/dist/src/apple/fastlane.d.ts +23 -0
  26. package/dist/src/apple/fastlane.js +11 -7
  27. package/dist/src/apple/fastlane.js.map +1 -1
  28. package/dist/src/apple/templates.d.ts +1 -1
  29. package/dist/src/apple/templates.js +0 -2
  30. package/dist/src/apple/templates.js.map +1 -1
  31. package/dist/src/apple/xcode-manager.d.ts +13 -9
  32. package/dist/src/apple/xcode-manager.js +146 -61
  33. package/dist/src/apple/xcode-manager.js.map +1 -1
  34. package/dist/src/flutter/code-tools.d.ts +17 -0
  35. package/dist/src/flutter/code-tools.js +263 -0
  36. package/dist/src/flutter/code-tools.js.map +1 -0
  37. package/dist/src/flutter/flutter-wizard.d.ts +2 -0
  38. package/dist/src/flutter/flutter-wizard.js +171 -0
  39. package/dist/src/flutter/flutter-wizard.js.map +1 -0
  40. package/dist/src/flutter/templates.d.ts +9 -0
  41. package/dist/src/flutter/templates.js +40 -0
  42. package/dist/src/flutter/templates.js.map +1 -0
  43. package/dist/src/nextjs/nextjs-wizard.js +5 -3
  44. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  45. package/dist/src/nuxt/nuxt-wizard.js +6 -4
  46. package/dist/src/nuxt/nuxt-wizard.js.map +1 -1
  47. package/dist/src/nuxt/sdk-setup.d.ts +1 -1
  48. package/dist/src/nuxt/sdk-setup.js +2 -1
  49. package/dist/src/nuxt/sdk-setup.js.map +1 -1
  50. package/dist/src/react-native/react-native-wizard.js +5 -3
  51. package/dist/src/react-native/react-native-wizard.js.map +1 -1
  52. package/dist/src/remix/remix-wizard.js +5 -3
  53. package/dist/src/remix/remix-wizard.js.map +1 -1
  54. package/dist/src/run.d.ts +2 -1
  55. package/dist/src/run.js +40 -32
  56. package/dist/src/run.js.map +1 -1
  57. package/dist/src/sveltekit/sveltekit-wizard.js +5 -3
  58. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  59. package/dist/src/utils/clack-utils.d.ts +4 -2
  60. package/dist/src/utils/clack-utils.js +18 -12
  61. package/dist/src/utils/clack-utils.js.map +1 -1
  62. package/dist/src/utils/package-manager.d.ts +1 -0
  63. package/dist/src/utils/package-manager.js +5 -0
  64. package/dist/src/utils/package-manager.js.map +1 -1
  65. package/dist/src/utils/types.d.ts +9 -0
  66. package/dist/src/utils/types.js.map +1 -1
  67. package/dist/test/apple/cocoapod.test.d.ts +1 -0
  68. package/dist/test/apple/cocoapod.test.js +409 -0
  69. package/dist/test/apple/cocoapod.test.js.map +1 -0
  70. package/dist/test/apple/code-tools.test.d.ts +1 -0
  71. package/dist/test/apple/code-tools.test.js +673 -0
  72. package/dist/test/apple/code-tools.test.js.map +1 -0
  73. package/dist/test/apple/fastfile.test.d.ts +1 -0
  74. package/dist/test/apple/fastfile.test.js +431 -0
  75. package/dist/test/apple/fastfile.test.js.map +1 -0
  76. package/dist/test/apple/templates.test.d.ts +1 -0
  77. package/dist/test/apple/templates.test.js +73 -0
  78. package/dist/test/apple/templates.test.js.map +1 -0
  79. package/dist/test/apple/xcode-manager.test.d.ts +1 -0
  80. package/dist/test/apple/xcode-manager.test.js +834 -0
  81. package/dist/test/apple/xcode-manager.test.js.map +1 -0
  82. package/dist/test/flutter/code-tools.test.d.ts +1 -0
  83. package/dist/test/flutter/code-tools.test.js +84 -0
  84. package/dist/test/flutter/code-tools.test.js.map +1 -0
  85. package/dist/test/flutter/templates.test.d.ts +1 -0
  86. package/dist/test/flutter/templates.test.js +41 -0
  87. package/dist/test/flutter/templates.test.js.map +1 -0
  88. package/dist/test/utils/clack-utils.test.js +89 -0
  89. package/dist/test/utils/clack-utils.test.js.map +1 -1
  90. package/e2e-tests/README.md +5 -1
  91. package/e2e-tests/jest.config.ts +1 -0
  92. package/e2e-tests/test-applications/apple/damaged-missing-configuration-list/Project.xcodeproj/project.pbxproj +52 -0
  93. package/e2e-tests/test-applications/apple/damaged-missing-configuration-list/Project.xcodeproj/xcshareddata/xcschemes/Project1.xcscheme +78 -0
  94. package/e2e-tests/test-applications/apple/no-targets/Project.xcodeproj/project.pbxproj +62 -0
  95. package/e2e-tests/test-applications/apple/no-targets/Project.xcodeproj/xcshareddata/xcschemes/Project1.xcscheme +78 -0
  96. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project.xcodeproj/project.pbxproj +470 -0
  97. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project.xcodeproj/xcshareddata/xcschemes/Project1.xcscheme +78 -0
  98. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project1/ContentView.swift +7 -0
  99. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project1/Project1App.swift +10 -0
  100. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project2/ContentView.swift +7 -0
  101. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project2/Project2App.swift +10 -0
  102. package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Project.xcodeproj/project.pbxproj +382 -0
  103. package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Project.xcodeproj/xcshareddata/xcschemes/Project.xcscheme +78 -0
  104. package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Sources/ContentView.swift +7 -0
  105. package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Sources/MainApp.swift +10 -0
  106. package/e2e-tests/test-applications/flutter-test-app/.metadata +45 -0
  107. package/e2e-tests/test-applications/flutter-test-app/README.md +16 -0
  108. package/e2e-tests/test-applications/flutter-test-app/analysis_options.yaml +28 -0
  109. package/e2e-tests/test-applications/flutter-test-app/android/app/build.gradle +44 -0
  110. package/e2e-tests/test-applications/flutter-test-app/android/app/src/debug/AndroidManifest.xml +7 -0
  111. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/AndroidManifest.xml +45 -0
  112. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/kotlin/com/example/flutter_magic/MainActivity.kt +5 -0
  113. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/drawable/launch_background.xml +12 -0
  114. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/drawable-v21/launch_background.xml +12 -0
  115. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  116. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  117. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  118. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  119. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  120. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/values/styles.xml +18 -0
  121. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/values-night/styles.xml +18 -0
  122. package/e2e-tests/test-applications/flutter-test-app/android/app/src/profile/AndroidManifest.xml +7 -0
  123. package/e2e-tests/test-applications/flutter-test-app/android/build.gradle +18 -0
  124. package/e2e-tests/test-applications/flutter-test-app/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  125. package/e2e-tests/test-applications/flutter-test-app/android/gradle.properties +3 -0
  126. package/e2e-tests/test-applications/flutter-test-app/android/settings.gradle +25 -0
  127. package/e2e-tests/test-applications/flutter-test-app/lib/main.dart +125 -0
  128. package/e2e-tests/test-applications/flutter-test-app/linux/CMakeLists.txt +145 -0
  129. package/e2e-tests/test-applications/flutter-test-app/linux/flutter/CMakeLists.txt +88 -0
  130. package/e2e-tests/test-applications/flutter-test-app/linux/flutter/generated_plugin_registrant.cc +11 -0
  131. package/e2e-tests/test-applications/flutter-test-app/linux/flutter/generated_plugin_registrant.h +15 -0
  132. package/e2e-tests/test-applications/flutter-test-app/linux/flutter/generated_plugins.cmake +23 -0
  133. package/e2e-tests/test-applications/flutter-test-app/linux/main.cc +6 -0
  134. package/e2e-tests/test-applications/flutter-test-app/linux/my_application.cc +124 -0
  135. package/e2e-tests/test-applications/flutter-test-app/linux/my_application.h +18 -0
  136. package/e2e-tests/test-applications/flutter-test-app/macos/Flutter/Flutter-Debug.xcconfig +2 -0
  137. package/e2e-tests/test-applications/flutter-test-app/macos/Flutter/Flutter-Release.xcconfig +2 -0
  138. package/e2e-tests/test-applications/flutter-test-app/macos/Flutter/GeneratedPluginRegistrant.swift +10 -0
  139. package/e2e-tests/test-applications/flutter-test-app/macos/Podfile +43 -0
  140. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/AppDelegate.swift +9 -0
  141. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
  142. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
  143. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +0 -0
  144. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +0 -0
  145. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +0 -0
  146. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +0 -0
  147. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +0 -0
  148. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +0 -0
  149. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Base.lproj/MainMenu.xib +343 -0
  150. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/AppInfo.xcconfig +14 -0
  151. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/Debug.xcconfig +2 -0
  152. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/Release.xcconfig +2 -0
  153. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/Warnings.xcconfig +13 -0
  154. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/DebugProfile.entitlements +12 -0
  155. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Info.plist +32 -0
  156. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/MainFlutterWindow.swift +15 -0
  157. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Release.entitlements +8 -0
  158. package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcodeproj/project.pbxproj +705 -0
  159. package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  160. package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +98 -0
  161. package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcworkspace/contents.xcworkspacedata +7 -0
  162. package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  163. package/e2e-tests/test-applications/flutter-test-app/macos/RunnerTests/RunnerTests.swift +12 -0
  164. package/e2e-tests/test-applications/flutter-test-app/pubspec.lock +213 -0
  165. package/e2e-tests/test-applications/flutter-test-app/pubspec.yaml +89 -0
  166. package/e2e-tests/test-applications/flutter-test-app/test/widget_test.dart +30 -0
  167. package/e2e-tests/test-applications/flutter-test-app/web/favicon.png +0 -0
  168. package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-192.png +0 -0
  169. package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-512.png +0 -0
  170. package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-maskable-192.png +0 -0
  171. package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-maskable-512.png +0 -0
  172. package/e2e-tests/test-applications/flutter-test-app/web/index.html +38 -0
  173. package/e2e-tests/test-applications/flutter-test-app/web/manifest.json +35 -0
  174. package/e2e-tests/test-applications/flutter-test-app/windows/CMakeLists.txt +108 -0
  175. package/e2e-tests/test-applications/flutter-test-app/windows/flutter/CMakeLists.txt +109 -0
  176. package/e2e-tests/test-applications/flutter-test-app/windows/flutter/generated_plugin_registrant.cc +11 -0
  177. package/e2e-tests/test-applications/flutter-test-app/windows/flutter/generated_plugin_registrant.h +15 -0
  178. package/e2e-tests/test-applications/flutter-test-app/windows/flutter/generated_plugins.cmake +23 -0
  179. package/e2e-tests/test-applications/flutter-test-app/windows/runner/CMakeLists.txt +40 -0
  180. package/e2e-tests/test-applications/flutter-test-app/windows/runner/Runner.rc +121 -0
  181. package/e2e-tests/test-applications/flutter-test-app/windows/runner/flutter_window.cpp +71 -0
  182. package/e2e-tests/test-applications/flutter-test-app/windows/runner/flutter_window.h +33 -0
  183. package/e2e-tests/test-applications/flutter-test-app/windows/runner/main.cpp +43 -0
  184. package/e2e-tests/test-applications/flutter-test-app/windows/runner/resource.h +16 -0
  185. package/e2e-tests/test-applications/flutter-test-app/windows/runner/resources/app_icon.ico +0 -0
  186. package/e2e-tests/test-applications/flutter-test-app/windows/runner/runner.exe.manifest +14 -0
  187. package/e2e-tests/test-applications/flutter-test-app/windows/runner/utils.cpp +65 -0
  188. package/e2e-tests/test-applications/flutter-test-app/windows/runner/utils.h +19 -0
  189. package/e2e-tests/test-applications/flutter-test-app/windows/runner/win32_window.cpp +288 -0
  190. package/e2e-tests/test-applications/flutter-test-app/windows/runner/win32_window.h +102 -0
  191. package/e2e-tests/tests/flutter.test.ts +127 -0
  192. package/e2e-tests/utils/index.ts +33 -0
  193. package/lib/Constants.ts +5 -0
  194. package/package.json +3 -2
  195. package/src/apple/apple-wizard.ts +2 -3
  196. package/src/apple/code-tools.ts +21 -6
  197. package/src/apple/fastlane.ts +18 -2
  198. package/src/apple/templates.ts +2 -2
  199. package/src/apple/xcode-manager.ts +186 -99
  200. package/src/flutter/code-tools.ts +284 -0
  201. package/src/flutter/flutter-wizard.ts +164 -0
  202. package/src/flutter/templates.ts +90 -0
  203. package/src/nextjs/nextjs-wizard.ts +5 -2
  204. package/src/nuxt/nuxt-wizard.ts +6 -3
  205. package/src/nuxt/sdk-setup.ts +2 -0
  206. package/src/react-native/react-native-wizard.ts +5 -2
  207. package/src/remix/remix-wizard.ts +5 -2
  208. package/src/run.ts +9 -0
  209. package/src/sveltekit/sveltekit-wizard.ts +5 -2
  210. package/src/utils/clack-utils.ts +16 -4
  211. package/src/utils/package-manager.ts +6 -0
  212. package/src/utils/types.ts +10 -0
  213. package/test/apple/cocoapod.test.ts +306 -0
  214. package/test/apple/code-tools.test.ts +1042 -0
  215. package/test/apple/fastfile.test.ts +550 -0
  216. package/test/apple/templates.test.ts +191 -0
  217. package/test/apple/xcode-manager.test.ts +1066 -0
  218. package/test/flutter/code-tools.test.ts +212 -0
  219. package/test/flutter/templates.test.ts +100 -0
  220. package/test/utils/clack-utils.test.ts +92 -0
  221. package/types/xcode.d.ts +526 -0
@@ -0,0 +1,550 @@
1
+ import * as fs from 'fs';
2
+ import * as os from 'os';
3
+ import * as path from 'path';
4
+ import {
5
+ addSentryToFastlane,
6
+ exportForTesting,
7
+ fastFile,
8
+ } from '../../src/apple/fastlane';
9
+ // @ts-ignore - clack is ESM and TS complains about that. It works though
10
+ import * as clack from '@clack/prompts';
11
+
12
+ describe('fastlane', () => {
13
+ beforeEach(() => {
14
+ jest.spyOn(clack.log, 'warn').mockImplementation();
15
+ jest.spyOn(clack, 'select').mockResolvedValue(undefined);
16
+ });
17
+
18
+ describe('#fastFile', () => {
19
+ describe('file exists', () => {
20
+ it('should return path', () => {
21
+ // -- Arrange --
22
+ const { fastlaneDir, projectPath } = createFastlaneDir();
23
+ const fastfile = createFastfile(fastlaneDir, 'lane :test do');
24
+
25
+ // -- Act --
26
+ const result = fastFile(projectPath);
27
+
28
+ // -- Assert --
29
+ expect(result).toBe(fastfile);
30
+ });
31
+ });
32
+
33
+ describe('file does not exist', () => {
34
+ it('should return null', () => {
35
+ // -- Arrange --
36
+ const { projectPath } = createFastlaneDir();
37
+ // do not create Fastfile
38
+
39
+ // -- Act --
40
+ const result = fastFile(projectPath);
41
+
42
+ // -- Assert --
43
+ expect(result).toBeNull();
44
+ });
45
+ });
46
+ });
47
+
48
+ describe('#findIOSPlatform', () => {
49
+ describe('platform block detection', () => {
50
+ const variations: {
51
+ name: string;
52
+ content: string;
53
+ expected: { index: number; length: number };
54
+ }[] = [
55
+ {
56
+ name: 'no platform',
57
+ content: `lane :test do
58
+ end`,
59
+ expected: { index: 0, length: 17 },
60
+ },
61
+ {
62
+ name: 'platform is ios',
63
+ content: `platform: ios
64
+ lane :test do
65
+ end`,
66
+ expected: { index: 0, length: 31 },
67
+ },
68
+ {
69
+ name: 'platform is ios and other platform',
70
+ content: `platform: ios
71
+ end
72
+ platform: android
73
+ lane :test do
74
+ end`,
75
+ expected: { index: 0, length: 57 },
76
+ },
77
+ {
78
+ name: 'platform is ios and other platform',
79
+ content: `
80
+ \t\tplatform: ios
81
+ \t\tend
82
+ \t\tplatform: android
83
+ \t\t\tlane :test do
84
+ \t\t\tend`,
85
+ expected: { index: 0, length: 66 },
86
+ },
87
+ ];
88
+
89
+ for (const variation of variations) {
90
+ describe(`${variation.name}`, () => {
91
+ it('should return null', () => {
92
+ // -- Act --
93
+ const result = exportForTesting.findIOSPlatform(variation.content);
94
+
95
+ // -- Assert --
96
+ expect(result).toEqual(variation.expected);
97
+ });
98
+ });
99
+ }
100
+ });
101
+
102
+ describe('platform block not found', () => {
103
+ it('should return full content', () => {
104
+ // -- Arrange --
105
+ const content = `
106
+ lane :test do
107
+ puts 'Hello, world!'
108
+ end`;
109
+
110
+ // -- Act --
111
+ const result = exportForTesting.findIOSPlatform(content);
112
+
113
+ // -- Assert --
114
+ expect(result).toEqual({ index: 0, length: 65 });
115
+ });
116
+ });
117
+
118
+ describe('invalid platform block', () => {
119
+ it('should return null', () => {
120
+ // -- Arrange --
121
+ // platform block is not opened with `do`
122
+ const content = `
123
+ platform :ios\n
124
+ lane :test do
125
+ puts 'Hello, world!'
126
+ end
127
+ end
128
+ `;
129
+
130
+ // -- Act --
131
+ const result = exportForTesting.findIOSPlatform(content);
132
+
133
+ // -- Assert --
134
+ expect(result).toBeNull();
135
+ });
136
+ });
137
+
138
+ describe('platform block is not closed', () => {
139
+ it('should return null', () => {
140
+ // -- Arrange --
141
+ const content = `
142
+ platform :ios do
143
+ lane :test do
144
+ puts 'Hello, world!'
145
+ end
146
+ `;
147
+
148
+ // -- Act --
149
+ const result = exportForTesting.findIOSPlatform(content);
150
+
151
+ // -- Assert --
152
+ expect(result).toBeNull();
153
+ });
154
+ });
155
+
156
+ describe('multiple platforms detected', () => {
157
+ it('should return block with ios platform', () => {
158
+ // -- Arrange --
159
+ const content = `
160
+ fastlane_version '2.53.1'
161
+
162
+ before_all do
163
+ ensure_git_branch
164
+ ensure_git_status_clean
165
+ git_pull
166
+ end
167
+
168
+ platform :ios do
169
+ # iOS Lanes
170
+ end
171
+
172
+ platform :android do
173
+ # Android Lanes
174
+ end
175
+ `;
176
+ // -- Act --
177
+ const result = exportForTesting.findIOSPlatform(content);
178
+
179
+ // -- Assert --
180
+ expect(result).toEqual({ index: 121, length: 15 });
181
+ });
182
+ });
183
+ });
184
+
185
+ describe('#findLanes', () => {
186
+ describe('lanes detection', () => {
187
+ describe('valid cases', () => {
188
+ const variations: {
189
+ name: string;
190
+ content: string;
191
+ expected: { index: number; length: number; name: string }[] | null;
192
+ }[] = [
193
+ {
194
+ name: 'single lane',
195
+ content: `
196
+ lane :test do
197
+ puts 'Hello, world!'
198
+ end
199
+ `,
200
+ expected: [{ index: 17, length: 25, name: 'test' }],
201
+ },
202
+ {
203
+ name: 'multiple lanes',
204
+ content: `
205
+ lane :test do
206
+ puts 'Hello, world!'
207
+ end
208
+ lane :test2 do
209
+ puts 'Hello, world!'
210
+ end`,
211
+ expected: [
212
+ { index: 17, length: 25, name: 'test' },
213
+ { index: 65, length: 25, name: 'test2' },
214
+ ],
215
+ },
216
+ ];
217
+
218
+ for (const variation of variations) {
219
+ describe(`${variation.name}`, () => {
220
+ it('should return lanes', () => {
221
+ // -- Act --
222
+ const result = exportForTesting.findLanes(variation.content);
223
+
224
+ // -- Assert --
225
+ expect(result).toEqual(variation.expected);
226
+ });
227
+ });
228
+ }
229
+ });
230
+
231
+ describe('invalid cases', () => {
232
+ describe('lane is not indented', () => {
233
+ it('should return null', () => {
234
+ // -- Arrange --
235
+ const content = `lane :test do\nend`;
236
+
237
+ // -- Act --
238
+ const result = exportForTesting.findLanes(content);
239
+
240
+ // -- Assert --
241
+ expect(result).toBeNull();
242
+ });
243
+ });
244
+
245
+ describe('lane is not closed', () => {
246
+ it('should return null', () => {
247
+ // -- Arrange --
248
+ const content = ` lane :test do\n`;
249
+
250
+ // -- Act --
251
+ const result = exportForTesting.findLanes(content);
252
+
253
+ // -- Assert --
254
+ expect(result).toBeNull();
255
+ });
256
+ });
257
+ });
258
+ });
259
+ });
260
+
261
+ describe('#addSentryToLane', () => {
262
+ describe('sentry_cli is not present', () => {
263
+ it('should return original content', () => {
264
+ // -- Arrange --
265
+ const content = `
266
+ platform :ios do
267
+ lane :test do
268
+ puts 'Hello, world!'
269
+ end
270
+ end
271
+ `;
272
+ const lane = { index: 34, length: 25, name: 'test' };
273
+
274
+ // -- Act --
275
+ const result = exportForTesting.addSentryToLane(
276
+ content,
277
+ lane,
278
+ 'test-org',
279
+ 'test-project',
280
+ );
281
+
282
+ // -- Assert --
283
+ expect(result).toBe(`
284
+ platform :ios do
285
+ lane :test do
286
+ puts 'Hello, world!'
287
+
288
+ sentry_cli(
289
+ org_slug: 'test-org',
290
+ project_slug: 'test-project',
291
+ include_sources: true
292
+ )
293
+ end
294
+ end
295
+ `);
296
+ });
297
+ });
298
+
299
+ describe('sentry_cli is present', () => {
300
+ it('should return updated content', () => {
301
+ // -- Arrange --
302
+ const content = `
303
+ platform :ios do
304
+ lane :test do
305
+ puts 'Hello, world!'
306
+
307
+ sentry_cli(org_slug: 'test-org', project_slug: 'test-project')
308
+ end
309
+ end
310
+ `;
311
+ const lane = { index: 34, length: 92, name: 'test' };
312
+
313
+ // -- Act --
314
+ const result = exportForTesting.addSentryToLane(
315
+ content,
316
+ lane,
317
+ 'test-org',
318
+ 'test-project',
319
+ );
320
+
321
+ // -- Assert --
322
+ expect(result).toBe(
323
+ `
324
+ platform :ios do
325
+ lane :test do
326
+ puts 'Hello, world!'
327
+
328
+ sentry_cli(
329
+ org_slug: 'test-org',
330
+ project_slug: 'test-project',
331
+ include_sources: true
332
+ )
333
+ end
334
+ end
335
+ `,
336
+ );
337
+ });
338
+ });
339
+ });
340
+
341
+ describe('#addSentryToFastlane', () => {
342
+ const org = 'test-org';
343
+ const project = 'test-project';
344
+
345
+ describe('Fastfile not found', () => {
346
+ it('should return false', async () => {
347
+ // -- Arrange --
348
+ const { projectPath } = createFastlaneDir();
349
+ const fastfilePath = path.join(projectPath, 'Fastfile');
350
+ // do not create Fastfile
351
+
352
+ // -- Act --
353
+ const result = await addSentryToFastlane(projectPath, org, project);
354
+
355
+ // -- Assert --
356
+ expect(result).toBe(false);
357
+ expect(fs.existsSync(fastfilePath)).toBe(false);
358
+ });
359
+ });
360
+
361
+ describe('platform not found', () => {
362
+ it('should return false', async () => {
363
+ // -- Arrange --
364
+ const { fastlaneDir, projectPath } = createFastlaneDir();
365
+ const fastfilePath = createFastfile(
366
+ fastlaneDir,
367
+ `
368
+ platform :ios
369
+ lane :test do
370
+ puts 'Hello, world!'
371
+ end
372
+ end
373
+ `,
374
+ );
375
+ const originalContent = fs.readFileSync(fastfilePath, 'utf8');
376
+
377
+ // -- Act --
378
+ const result = await addSentryToFastlane(projectPath, org, project);
379
+
380
+ // -- Assert --
381
+ expect(result).toBe(false);
382
+ expect(fs.readFileSync(fastfilePath, 'utf8')).toBe(originalContent);
383
+ });
384
+ });
385
+
386
+ describe('no lanes', () => {
387
+ it('should return false', async () => {
388
+ // -- Arrange --
389
+ const { fastlaneDir, projectPath } = createFastlaneDir();
390
+ createFastfile(fastlaneDir, `platform :ios`);
391
+
392
+ // -- Act --
393
+ const result = await addSentryToFastlane(projectPath, org, project);
394
+
395
+ // -- Assert --
396
+ expect(result).toBe(false);
397
+ });
398
+
399
+ it('should warn user', async () => {
400
+ // -- Arrange --
401
+ const { fastlaneDir, projectPath } = createFastlaneDir();
402
+ createFastfile(fastlaneDir, `platform :ios`);
403
+
404
+ // -- Act --
405
+ const result = await addSentryToFastlane(projectPath, org, project);
406
+
407
+ // -- Assert --
408
+ expect(result).toBe(false);
409
+ expect(clack.log.warn).toHaveBeenCalledWith(
410
+ 'No suitable lanes in your Fastfile.',
411
+ );
412
+ });
413
+ });
414
+
415
+ describe('single lane', () => {
416
+ it('should return true', async () => {
417
+ // -- Arrange --
418
+ const { fastlaneDir, projectPath } = createFastlaneDir();
419
+ const fastfilePath = createFastfile(
420
+ fastlaneDir,
421
+ `
422
+ platform :ios do
423
+ lane :test do
424
+ puts 'Hello, world!'
425
+ end
426
+ end
427
+ `,
428
+ );
429
+
430
+ // -- Act --
431
+ const result = await addSentryToFastlane(projectPath, org, project);
432
+
433
+ // -- Assert --
434
+ expect(result).toBe(true);
435
+ expect(fs.readFileSync(fastfilePath, 'utf8')).toBe(
436
+ `
437
+ platform :ios do
438
+ lane :test do
439
+ puts 'Hello, world!'
440
+
441
+ sentry_cli(
442
+ org_slug: 'test-org',
443
+ project_slug: 'test-project',
444
+ include_sources: true
445
+ )
446
+ end
447
+ end
448
+ `,
449
+ );
450
+ });
451
+ });
452
+
453
+ describe('multiple lanes', () => {
454
+ let fastfilePath: string;
455
+ let projectPath: string;
456
+ let originalContent: string;
457
+
458
+ beforeEach(() => {
459
+ const createdFastlaneDir = createFastlaneDir();
460
+ projectPath = createdFastlaneDir.projectPath;
461
+ fastfilePath = createFastfile(
462
+ createdFastlaneDir.fastlaneDir,
463
+ `platform :ios do
464
+ lane :test do
465
+ puts 'Hello, world!'
466
+ end
467
+
468
+ lane :beta do
469
+ puts 'Beta lane'
470
+ end
471
+ end
472
+ `,
473
+ );
474
+ });
475
+
476
+ describe('no lane selected', () => {
477
+ it('should not modify Fastfile', async () => {
478
+ // -- Arrange --
479
+ originalContent = fs.readFileSync(fastfilePath, 'utf8');
480
+ jest.spyOn(clack, 'select').mockResolvedValue(undefined);
481
+
482
+ // -- Act --
483
+ const result = await addSentryToFastlane(projectPath, org, project);
484
+
485
+ // -- Assert --
486
+ expect(result).toBe(false);
487
+ expect(fs.readFileSync(fastfilePath, 'utf8')).toBe(originalContent);
488
+ });
489
+ });
490
+
491
+ describe('lane selected', () => {
492
+ it('should modify only selected lane', async () => {
493
+ // -- Arrange --
494
+ jest.spyOn(clack, 'select').mockResolvedValue({
495
+ value: 'beta',
496
+ index: 1,
497
+ });
498
+
499
+ // -- Act --
500
+ const result = await addSentryToFastlane(projectPath, org, project);
501
+
502
+ // -- Assert --
503
+ expect(result).toBe(true);
504
+ expect(fs.readFileSync(fastfilePath, 'utf8')).toBe(
505
+ `platform :ios do
506
+ lane :test do
507
+ puts 'Hello, world!'
508
+ end
509
+
510
+ lane :beta do
511
+ puts 'Beta lane'
512
+
513
+ sentry_cli(
514
+ org_slug: 'test-org',
515
+ project_slug: 'test-project',
516
+ include_sources: true
517
+ )
518
+ end
519
+ end
520
+ `,
521
+ );
522
+ expect(clack.select).toHaveBeenCalledWith({
523
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
524
+ maxItems: expect.any(Number),
525
+ message: 'Select lane to add Sentry to:',
526
+ options: [
527
+ { value: { value: 'test', index: 0 }, label: 'test' },
528
+ { value: { value: 'beta', index: 1 }, label: 'beta' },
529
+ ],
530
+ });
531
+ });
532
+ });
533
+ });
534
+ });
535
+ });
536
+
537
+ function createFastlaneDir() {
538
+ const projectPath = fs.mkdtempSync(path.join(os.tmpdir(), 'test-project'));
539
+ const fastlaneDir = path.join(projectPath, 'fastlane');
540
+ fs.mkdirSync(fastlaneDir, {
541
+ recursive: true,
542
+ });
543
+ return { fastlaneDir, projectPath };
544
+ }
545
+
546
+ function createFastfile(fastlaneDir: string, content: string) {
547
+ const fastfile = path.join(fastlaneDir, 'Fastfile');
548
+ fs.writeFileSync(fastfile, content);
549
+ return fastfile;
550
+ }