@sentry/wizard 4.5.0 → 4.6.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 (228) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/README.md +23 -19
  3. package/dist/bin.js +13 -0
  4. package/dist/bin.js.map +1 -1
  5. package/dist/e2e-tests/tests/nextjs-14.test.js +3 -2
  6. package/dist/e2e-tests/tests/nextjs-14.test.js.map +1 -1
  7. package/dist/e2e-tests/tests/nextjs-15.test.js +2 -2
  8. package/dist/e2e-tests/tests/nextjs-15.test.js.map +1 -1
  9. package/dist/e2e-tests/utils/index.d.ts +1 -1
  10. package/dist/e2e-tests/utils/index.js +20 -2
  11. package/dist/e2e-tests/utils/index.js.map +1 -1
  12. package/dist/lib/Constants.d.ts +2 -0
  13. package/dist/lib/Constants.js.map +1 -1
  14. package/dist/lib/Helper/File.d.ts +1 -1
  15. package/dist/lib/Helper/File.js +1 -3
  16. package/dist/lib/Helper/File.js.map +1 -1
  17. package/dist/lib/Helper/Logging.d.ts +3 -0
  18. package/dist/lib/Helper/Logging.js +3 -0
  19. package/dist/lib/Helper/Logging.js.map +1 -1
  20. package/dist/lib/Helper/Package.d.ts +5 -3
  21. package/dist/lib/Helper/Package.js +2 -2
  22. package/dist/lib/Helper/Package.js.map +1 -1
  23. package/dist/lib/Helper/SentryCli.d.ts +20 -7
  24. package/dist/lib/Helper/SentryCli.js +21 -13
  25. package/dist/lib/Helper/SentryCli.js.map +1 -1
  26. package/dist/lib/Helper/Wizard.js +9 -5
  27. package/dist/lib/Helper/Wizard.js.map +1 -1
  28. package/dist/lib/Helper/__tests__/SentryCli.js +21 -4
  29. package/dist/lib/Helper/__tests__/SentryCli.js.map +1 -1
  30. package/dist/lib/Setup.d.ts +3 -1
  31. package/dist/lib/Setup.js.map +1 -1
  32. package/dist/lib/Steps/Integrations/BaseIntegration.js +1 -2
  33. package/dist/lib/Steps/Integrations/BaseIntegration.js.map +1 -1
  34. package/dist/lib/Steps/Integrations/Cordova.js +14 -10
  35. package/dist/lib/Steps/Integrations/Cordova.js.map +1 -1
  36. package/dist/lib/Steps/Integrations/Electron.d.ts +4 -1
  37. package/dist/lib/Steps/Integrations/Electron.js +1 -1
  38. package/dist/lib/Steps/Integrations/Electron.js.map +1 -1
  39. package/dist/lib/Steps/Integrations/MobileProject.d.ts +3 -1
  40. package/dist/lib/Steps/Integrations/MobileProject.js +1 -1
  41. package/dist/lib/Steps/Integrations/MobileProject.js.map +1 -1
  42. package/dist/lib/Steps/PromptForParameters.d.ts +4 -1
  43. package/dist/lib/Steps/PromptForParameters.js.map +1 -1
  44. package/dist/lib/Steps/SentryProjectSelector.d.ts +42 -1
  45. package/dist/lib/Steps/SentryProjectSelector.js +1 -1
  46. package/dist/lib/Steps/SentryProjectSelector.js.map +1 -1
  47. package/dist/lib/Steps/WaitForSentry.d.ts +3 -1
  48. package/dist/lib/Steps/WaitForSentry.js +4 -4
  49. package/dist/lib/Steps/WaitForSentry.js.map +1 -1
  50. package/dist/lib/Types.d.ts +14 -0
  51. package/dist/lib/Types.js +3 -0
  52. package/dist/lib/Types.js.map +1 -0
  53. package/dist/lib/__tests__/Env.js +6 -13
  54. package/dist/lib/__tests__/Env.js.map +1 -1
  55. package/dist/src/android/android-wizard.js +15 -12
  56. package/dist/src/android/android-wizard.js.map +1 -1
  57. package/dist/src/android/code-tools.js +1 -1
  58. package/dist/src/android/code-tools.js.map +1 -1
  59. package/dist/src/android/gradle.js +4 -4
  60. package/dist/src/android/gradle.js.map +1 -1
  61. package/dist/src/android/manifest.js +1 -1
  62. package/dist/src/android/manifest.js.map +1 -1
  63. package/dist/src/apple/apple-wizard.d.ts +2 -2
  64. package/dist/src/apple/apple-wizard.js +37 -118
  65. package/dist/src/apple/apple-wizard.js.map +1 -1
  66. package/dist/src/apple/check-installed-cli.d.ts +1 -0
  67. package/dist/src/apple/check-installed-cli.js +60 -0
  68. package/dist/src/apple/check-installed-cli.js.map +1 -0
  69. package/dist/src/apple/cocoapod.js +1 -1
  70. package/dist/src/apple/cocoapod.js.map +1 -1
  71. package/dist/src/apple/code-tools.js +1 -1
  72. package/dist/src/apple/code-tools.js.map +1 -1
  73. package/dist/src/apple/configure-fastlane.d.ts +5 -0
  74. package/dist/src/apple/configure-fastlane.js +66 -0
  75. package/dist/src/apple/configure-fastlane.js.map +1 -0
  76. package/dist/src/apple/fastlane.d.ts +1 -1
  77. package/dist/src/apple/fastlane.js +5 -5
  78. package/dist/src/apple/fastlane.js.map +1 -1
  79. package/dist/src/apple/lookup-xcode-project.d.ts +7 -0
  80. package/dist/src/apple/lookup-xcode-project.js +98 -0
  81. package/dist/src/apple/lookup-xcode-project.js.map +1 -0
  82. package/dist/src/apple/options.d.ts +4 -0
  83. package/dist/src/apple/options.js +3 -0
  84. package/dist/src/apple/options.js.map +1 -0
  85. package/dist/src/apple/search-xcode-project-at-path.d.ts +1 -0
  86. package/dist/src/apple/search-xcode-project-at-path.js +70 -0
  87. package/dist/src/apple/search-xcode-project-at-path.js.map +1 -0
  88. package/dist/src/apple/xcode-manager.js +1 -1
  89. package/dist/src/apple/xcode-manager.js.map +1 -1
  90. package/dist/src/flutter/code-tools.js +3 -3
  91. package/dist/src/flutter/code-tools.js.map +1 -1
  92. package/dist/src/flutter/flutter-wizard.js +21 -15
  93. package/dist/src/flutter/flutter-wizard.js.map +1 -1
  94. package/dist/src/flutter/templates.js +4 -4
  95. package/dist/src/flutter/templates.js.map +1 -1
  96. package/dist/src/nextjs/nextjs-wizard.js +118 -43
  97. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  98. package/dist/src/nextjs/templates.d.ts +10 -1
  99. package/dist/src/nextjs/templates.js +191 -63
  100. package/dist/src/nextjs/templates.js.map +1 -1
  101. package/dist/src/nuxt/nuxt-wizard.js +21 -16
  102. package/dist/src/nuxt/nuxt-wizard.js.map +1 -1
  103. package/dist/src/nuxt/sdk-example.js +3 -3
  104. package/dist/src/nuxt/sdk-example.js.map +1 -1
  105. package/dist/src/nuxt/sdk-setup.js +9 -9
  106. package/dist/src/nuxt/sdk-setup.js.map +1 -1
  107. package/dist/src/nuxt/templates.js +173 -58
  108. package/dist/src/nuxt/templates.js.map +1 -1
  109. package/dist/src/nuxt/utils.js +6 -3
  110. package/dist/src/nuxt/utils.js.map +1 -1
  111. package/dist/src/react-native/expo-env-file.js +1 -1
  112. package/dist/src/react-native/expo-env-file.js.map +1 -1
  113. package/dist/src/react-native/expo-metro.js +4 -4
  114. package/dist/src/react-native/expo-metro.js.map +1 -1
  115. package/dist/src/react-native/expo.js +4 -4
  116. package/dist/src/react-native/expo.js.map +1 -1
  117. package/dist/src/react-native/javascript.js +7 -7
  118. package/dist/src/react-native/javascript.js.map +1 -1
  119. package/dist/src/react-native/metro.js +8 -8
  120. package/dist/src/react-native/metro.js.map +1 -1
  121. package/dist/src/react-native/react-native-wizard.d.ts +1 -1
  122. package/dist/src/react-native/react-native-wizard.js +36 -31
  123. package/dist/src/react-native/react-native-wizard.js.map +1 -1
  124. package/dist/src/react-native/uninstall.js +8 -5
  125. package/dist/src/react-native/uninstall.js.map +1 -1
  126. package/dist/src/react-native/xcode.d.ts +2 -1
  127. package/dist/src/react-native/xcode.js +1 -2
  128. package/dist/src/react-native/xcode.js.map +1 -1
  129. package/dist/src/remix/codemods/handle-error.js +4 -1
  130. package/dist/src/remix/codemods/handle-error.js.map +1 -1
  131. package/dist/src/remix/remix-wizard.js +23 -18
  132. package/dist/src/remix/remix-wizard.js.map +1 -1
  133. package/dist/src/remix/sdk-example.js +163 -64
  134. package/dist/src/remix/sdk-example.js.map +1 -1
  135. package/dist/src/remix/sdk-setup.js +11 -7
  136. package/dist/src/remix/sdk-setup.js.map +1 -1
  137. package/dist/src/run.d.ts +3 -1
  138. package/dist/src/run.js +29 -9
  139. package/dist/src/run.js.map +1 -1
  140. package/dist/src/sourcemaps/sourcemaps-wizard.js +30 -28
  141. package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
  142. package/dist/src/sourcemaps/tools/angular.js +3 -3
  143. package/dist/src/sourcemaps/tools/angular.js.map +1 -1
  144. package/dist/src/sourcemaps/tools/create-react-app.js +3 -3
  145. package/dist/src/sourcemaps/tools/create-react-app.js.map +1 -1
  146. package/dist/src/sourcemaps/tools/esbuild.js +6 -6
  147. package/dist/src/sourcemaps/tools/esbuild.js.map +1 -1
  148. package/dist/src/sourcemaps/tools/nextjs.js +5 -5
  149. package/dist/src/sourcemaps/tools/nextjs.js.map +1 -1
  150. package/dist/src/sourcemaps/tools/remix.js +4 -4
  151. package/dist/src/sourcemaps/tools/remix.js.map +1 -1
  152. package/dist/src/sourcemaps/tools/rollup.js +6 -6
  153. package/dist/src/sourcemaps/tools/rollup.js.map +1 -1
  154. package/dist/src/sourcemaps/tools/sentry-cli.js +15 -15
  155. package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
  156. package/dist/src/sourcemaps/tools/tsc.js +6 -6
  157. package/dist/src/sourcemaps/tools/tsc.js.map +1 -1
  158. package/dist/src/sourcemaps/tools/vite.js +12 -12
  159. package/dist/src/sourcemaps/tools/vite.js.map +1 -1
  160. package/dist/src/sourcemaps/tools/webpack.js +10 -10
  161. package/dist/src/sourcemaps/tools/webpack.js.map +1 -1
  162. package/dist/src/sourcemaps/utils/detect-tool.js +2 -2
  163. package/dist/src/sourcemaps/utils/detect-tool.js.map +1 -1
  164. package/dist/src/sourcemaps/utils/other-wizards.js +5 -5
  165. package/dist/src/sourcemaps/utils/other-wizards.js.map +1 -1
  166. package/dist/src/sourcemaps/utils/sdk-version.js +7 -7
  167. package/dist/src/sourcemaps/utils/sdk-version.js.map +1 -1
  168. package/dist/src/sveltekit/sdk-example.js +1 -1
  169. package/dist/src/sveltekit/sdk-example.js.map +1 -1
  170. package/dist/src/sveltekit/sdk-setup.js +15 -14
  171. package/dist/src/sveltekit/sdk-setup.js.map +1 -1
  172. package/dist/src/sveltekit/sveltekit-wizard.js +25 -20
  173. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  174. package/dist/src/sveltekit/templates.js +126 -37
  175. package/dist/src/sveltekit/templates.js.map +1 -1
  176. package/dist/src/telemetry.js +11 -0
  177. package/dist/src/telemetry.js.map +1 -1
  178. package/dist/src/utils/{clack-utils.d.ts → clack/index.d.ts} +45 -7
  179. package/dist/src/utils/{clack-utils.js → clack/index.js} +72 -19
  180. package/dist/src/utils/clack/index.js.map +1 -0
  181. package/dist/src/utils/debug.js +1 -1
  182. package/dist/src/utils/debug.js.map +1 -1
  183. package/dist/src/utils/find-files-with-extension.d.ts +1 -0
  184. package/dist/src/utils/find-files-with-extension.js +39 -0
  185. package/dist/src/utils/find-files-with-extension.js.map +1 -0
  186. package/dist/src/utils/package-manager.d.ts +6 -1
  187. package/dist/src/utils/package-manager.js +25 -19
  188. package/dist/src/utils/package-manager.js.map +1 -1
  189. package/dist/src/utils/sentrycli-utils.js +0 -1
  190. package/dist/src/utils/sentrycli-utils.js.map +1 -1
  191. package/dist/src/utils/types.d.ts +4 -0
  192. package/dist/src/utils/types.js.map +1 -1
  193. package/dist/src/version.d.ts +1 -1
  194. package/dist/src/version.js +1 -1
  195. package/dist/src/version.js.map +1 -1
  196. package/dist/test/android/code-tools.test.js +0 -1
  197. package/dist/test/android/code-tools.test.js.map +1 -1
  198. package/dist/test/apple/cocoapod.test.js +1 -1
  199. package/dist/test/apple/cocoapod.test.js.map +1 -1
  200. package/dist/test/apple/code-tools.test.js +1 -1
  201. package/dist/test/apple/code-tools.test.js.map +1 -1
  202. package/dist/test/apple/fastfile.test.js +1 -1
  203. package/dist/test/apple/fastfile.test.js.map +1 -1
  204. package/dist/test/apple/xcode-manager.test.js +26 -2
  205. package/dist/test/apple/xcode-manager.test.js.map +1 -1
  206. package/dist/test/flutter/code-tools.test.js +0 -2
  207. package/dist/test/flutter/code-tools.test.js.map +1 -1
  208. package/dist/test/flutter/templates.test.js +23 -23
  209. package/dist/test/flutter/templates.test.js.map +1 -1
  210. package/dist/test/nextjs/templates.test.js +128 -83
  211. package/dist/test/nextjs/templates.test.js.map +1 -1
  212. package/dist/test/react-native/expo-metro.test.js +1 -1
  213. package/dist/test/react-native/expo-metro.test.js.map +1 -1
  214. package/dist/test/react-native/javascript.test.js +1 -1
  215. package/dist/test/react-native/javascript.test.js.map +1 -1
  216. package/dist/test/react-native/metro.test.js +1 -1
  217. package/dist/test/react-native/metro.test.js.map +1 -1
  218. package/dist/test/sourcemaps/tools/sentry-cli.test.js +5 -5
  219. package/dist/test/sourcemaps/tools/sentry-cli.test.js.map +1 -1
  220. package/dist/test/utils/{clack-utils.test.js → clack/index.test.js} +91 -18
  221. package/dist/test/utils/clack/index.test.js.map +1 -0
  222. package/dist/test/utils/package-manager.test.d.ts +1 -0
  223. package/dist/test/utils/package-manager.test.js +29 -0
  224. package/dist/test/utils/package-manager.test.js.map +1 -0
  225. package/package.json +1 -1
  226. package/dist/src/utils/clack-utils.js.map +0 -1
  227. package/dist/test/utils/clack-utils.test.js.map +0 -1
  228. /package/dist/test/utils/{clack-utils.test.d.ts → clack/index.test.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"gradle.js","sourceRoot":"","sources":["../../../src/android/gradle.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport * as fs from 'fs';\nimport { abortIfCancelled, askForItemSelection } from '../utils/clack-utils';\nimport {\n plugin,\n pluginKts,\n pluginsBlock,\n pluginsBlockKts,\n sourceContext,\n sourceContextKts,\n} from './templates';\nimport * as bash from '../utils/bash';\nimport * as Sentry from '@sentry/node';\n// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport { fetchSdkVersion } from '../utils/release-registry';\n\n/**\n * A Gradle project may contain multiple modules, some of them may be applications, some of them may be libraries.\n * We are only interested in applications. For example:\n *\n * myproject/\n * app/\n * lib1/\n * lib2/\n * wearApp/\n *\n * In this case^ we are interested in app/ and wearApp/\n *\n * @param buildGradleFiles a list of build.gradle(.kts) paths that contain the com.android.application plugin\n * @returns the selected project for setting up\n */\nexport async function selectAppFile(\n buildGradleFiles: string[],\n): Promise<string> {\n const appFiles = [];\n for (let index = 0; index < buildGradleFiles.length; index++) {\n const file = buildGradleFiles[index];\n const text = fs.readFileSync(file, 'utf8');\n if (/\\(?[\"']com\\.android\\.application[\"']\\)?(?!.*\\S)/.test(text)) {\n appFiles.push(file);\n }\n }\n\n if (appFiles.length === 0) {\n Sentry.setTag('custom-build-logic', true);\n const appFile = await abortIfCancelled(\n clack.text({\n message: `Unable to find your app's directory. \n Please enter the relative path to your app's build.gradle file from the root project`,\n placeholder: 'app/build.gradle.kts',\n validate(value) {\n if (!value.includes('.gradle') || !fs.existsSync(value))\n return `Not a valid gradle file.`;\n },\n }),\n );\n return appFile;\n }\n\n let appFile;\n if (appFiles.length === 1) {\n Sentry.setTag('multiple-projects', false);\n appFile = appFiles[0];\n } else {\n Sentry.setTag('multiple-projects', true);\n appFile = (\n await askForItemSelection(\n appFiles,\n 'Which project do you want to add Sentry to?',\n )\n ).value;\n }\n Sentry.setTag('custom-build-logic', false);\n return appFile;\n}\n\n/**\n * Patches a build.gradle(.kts) file that contains `com.android.application` plugin.\n * There are multiple cases we have to handle here:\n * - An existing `plugins {}` block:\n * - We just have to add our plugin inside the block\n * - No existing `plugins {}` block\n * - We have to add the entire block in the beginning of the file, BUT *after imports*\n *\n * For example (2nd case):\n *\n * ```\n * import net.ltgt.gradle.errorprone.errorprone\n *\n * // our plugins block goes here <--\n * plugins {\n * id(\"io.sentry.android.gradle\") version \"3.12.0\"\n * }\n *\n * apply(plugin = \"com.android.application\")\n *\n * android {\n * ...\n * }\n * ```\n *\n * In the end we run `./gradlew` to verify the config is build-able and not broken.\n *\n * @param appFile the selected Gradle application project\n * @returns true if successfully added Sentry Gradle config, false otherwise\n */\nexport async function addGradlePlugin(\n appFile: string,\n orgSlug: string,\n projectSlug: string,\n): Promise<boolean> {\n const gradleScript = fs.readFileSync(appFile, 'utf8');\n\n if (/\\(?[\"']io\\.sentry\\.android\\.gradle[\"']\\)?/.test(gradleScript)) {\n // sentry gradle plugin is already installed\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold(\n 'Sentry Gradle plugin',\n )} is already added to the project.`,\n ),\n );\n maybeAddSourceContextConfig(appFile, gradleScript, orgSlug, projectSlug);\n return true;\n }\n\n const pluginVersion = await fetchSdkVersion(\n 'sentry.java.android.gradle-plugin',\n );\n const pluginsBlockMatch = /plugins\\s*{[^{}]*}/.exec(gradleScript);\n let newGradleScript;\n if (!pluginsBlockMatch) {\n // no \"plugins {}\" block, we can just add our own after imports\n const regex = /import\\s+[\\w.]+/gm;\n let importsMatch = regex.exec(gradleScript);\n let insertIndex = 0;\n while (importsMatch) {\n insertIndex = importsMatch.index + importsMatch[0].length + 1;\n importsMatch = regex.exec(gradleScript);\n }\n\n if (appFile.endsWith('.kts')) {\n newGradleScript =\n gradleScript.slice(0, insertIndex) +\n pluginsBlockKts(pluginVersion) +\n gradleScript.slice(insertIndex);\n } else {\n newGradleScript =\n gradleScript.slice(0, insertIndex) +\n pluginsBlock(pluginVersion) +\n gradleScript.slice(insertIndex);\n }\n } else {\n const insertIndex =\n pluginsBlockMatch.index + pluginsBlockMatch[0].length - 1;\n if (appFile.endsWith('.kts')) {\n newGradleScript =\n gradleScript.slice(0, insertIndex) +\n pluginKts(pluginVersion) +\n gradleScript.slice(insertIndex);\n } else {\n newGradleScript =\n gradleScript.slice(0, insertIndex) +\n plugin(pluginVersion) +\n gradleScript.slice(insertIndex);\n }\n }\n fs.writeFileSync(appFile, newGradleScript, 'utf8');\n\n maybeAddSourceContextConfig(appFile, newGradleScript, orgSlug, projectSlug);\n\n const buildSpinner = clack.spinner();\n\n buildSpinner.start(\n 'Running ./gradlew to verify changes (this may take a few minutes)...',\n );\n\n try {\n await bash.execute('./gradlew');\n buildSpinner.stop(\n chalk.greenBright(\n `${chalk.bold('Sentry Gradle plugin')} added to the project.`,\n ),\n );\n } catch (e) {\n buildSpinner.stop();\n Sentry.captureException('Gradle Sync failed');\n return false;\n }\n\n return true;\n}\n\n/**\n * Looks for the applications packageName (namespace) in the specified build.gradle(.kts) file.\n *\n * ```\n * android {\n * namespace 'my.package.name' <-- this is what we extract\n *\n * compileSdkVersion = 31\n * ...\n * }\n * ```\n * @param appFile\n * @returns the packageName(namespace) of the app if available\n */\nexport function getNamespace(appFile: string): string | undefined {\n const gradleScript = fs.readFileSync(appFile, 'utf8');\n\n const namespaceMatch = /namespace\\s*=?\\s*['\"]([^'\"]+)['\"]/i.exec(\n gradleScript,\n );\n if (!namespaceMatch || namespaceMatch.length <= 1) {\n clack.log.warn('Unable to determine application package name.');\n Sentry.captureException('No package name');\n return undefined;\n }\n\n const namespace = namespaceMatch[1];\n return namespace;\n}\n\n/**\n * Adds source context configuration to the gradleScript if `sentry {}` block is not yet configured,\n *\n * @param appFile\n * @param gradleScript\n */\nfunction maybeAddSourceContextConfig(\n appFile: string,\n gradleScript: string,\n orgSlug: string,\n projectSlug: string,\n) {\n if (!/sentry\\s*\\{[^}]*\\}/i.test(gradleScript)) {\n // if no sentry {} block is configured, we add our own with source context enabled\n if (appFile.endsWith('.kts')) {\n fs.appendFileSync(\n appFile,\n sourceContextKts(orgSlug, projectSlug),\n 'utf8',\n );\n } else {\n fs.appendFileSync(appFile, sourceContext(orgSlug, projectSlug), 'utf8');\n }\n }\n}\n"]}
1
+ {"version":3,"file":"gradle.js","sourceRoot":"","sources":["../../../src/android/gradle.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport * as fs from 'fs';\nimport { abortIfCancelled, askForItemSelection } from '../utils/clack';\nimport {\n plugin,\n pluginKts,\n pluginsBlock,\n pluginsBlockKts,\n sourceContext,\n sourceContextKts,\n} from './templates';\nimport * as bash from '../utils/bash';\nimport * as Sentry from '@sentry/node';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport { fetchSdkVersion } from '../utils/release-registry';\n\n/**\n * A Gradle project may contain multiple modules, some of them may be applications, some of them may be libraries.\n * We are only interested in applications. For example:\n *\n * myproject/\n * app/\n * lib1/\n * lib2/\n * wearApp/\n *\n * In this case^ we are interested in app/ and wearApp/\n *\n * @param buildGradleFiles a list of build.gradle(.kts) paths that contain the com.android.application plugin\n * @returns the selected project for setting up\n */\nexport async function selectAppFile(\n buildGradleFiles: string[],\n): Promise<string> {\n const appFiles = [];\n for (let index = 0; index < buildGradleFiles.length; index++) {\n const file = buildGradleFiles[index];\n const text = fs.readFileSync(file, 'utf8');\n if (/\\(?[\"']com\\.android\\.application[\"']\\)?(?!.*\\S)/.test(text)) {\n appFiles.push(file);\n }\n }\n\n if (appFiles.length === 0) {\n Sentry.setTag('custom-build-logic', true);\n const appFile = await abortIfCancelled(\n clack.text({\n message: `Unable to find your app's directory. \n Please enter the relative path to your app's build.gradle file from the root project`,\n placeholder: 'app/build.gradle.kts',\n validate(value) {\n if (!value.includes('.gradle') || !fs.existsSync(value))\n return `Not a valid gradle file.`;\n },\n }),\n );\n return appFile;\n }\n\n let appFile;\n if (appFiles.length === 1) {\n Sentry.setTag('multiple-projects', false);\n appFile = appFiles[0];\n } else {\n Sentry.setTag('multiple-projects', true);\n appFile = (\n await askForItemSelection(\n appFiles,\n 'Which project do you want to add Sentry to?',\n )\n ).value;\n }\n Sentry.setTag('custom-build-logic', false);\n return appFile;\n}\n\n/**\n * Patches a build.gradle(.kts) file that contains `com.android.application` plugin.\n * There are multiple cases we have to handle here:\n * - An existing `plugins {}` block:\n * - We just have to add our plugin inside the block\n * - No existing `plugins {}` block\n * - We have to add the entire block in the beginning of the file, BUT *after imports*\n *\n * For example (2nd case):\n *\n * ```\n * import net.ltgt.gradle.errorprone.errorprone\n *\n * // our plugins block goes here <--\n * plugins {\n * id(\"io.sentry.android.gradle\") version \"3.12.0\"\n * }\n *\n * apply(plugin = \"com.android.application\")\n *\n * android {\n * ...\n * }\n * ```\n *\n * In the end we run `./gradlew` to verify the config is build-able and not broken.\n *\n * @param appFile the selected Gradle application project\n * @returns true if successfully added Sentry Gradle config, false otherwise\n */\nexport async function addGradlePlugin(\n appFile: string,\n orgSlug: string,\n projectSlug: string,\n): Promise<boolean> {\n const gradleScript = fs.readFileSync(appFile, 'utf8');\n\n if (/\\(?[\"']io\\.sentry\\.android\\.gradle[\"']\\)?/.test(gradleScript)) {\n // sentry gradle plugin is already installed\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold(\n 'Sentry Gradle plugin',\n )} is already added to the project.`,\n ),\n );\n maybeAddSourceContextConfig(appFile, gradleScript, orgSlug, projectSlug);\n return true;\n }\n\n const pluginVersion = await fetchSdkVersion(\n 'sentry.java.android.gradle-plugin',\n );\n const pluginsBlockMatch = /plugins\\s*{[^{}]*}/.exec(gradleScript);\n let newGradleScript;\n if (!pluginsBlockMatch) {\n // no \"plugins {}\" block, we can just add our own after imports\n const regex = /import\\s+[\\w.]+/gm;\n let importsMatch = regex.exec(gradleScript);\n let insertIndex = 0;\n while (importsMatch) {\n insertIndex = importsMatch.index + importsMatch[0].length + 1;\n importsMatch = regex.exec(gradleScript);\n }\n\n if (appFile.endsWith('.kts')) {\n newGradleScript =\n gradleScript.slice(0, insertIndex) +\n pluginsBlockKts(pluginVersion) +\n gradleScript.slice(insertIndex);\n } else {\n newGradleScript =\n gradleScript.slice(0, insertIndex) +\n pluginsBlock(pluginVersion) +\n gradleScript.slice(insertIndex);\n }\n } else {\n const insertIndex =\n pluginsBlockMatch.index + pluginsBlockMatch[0].length - 1;\n if (appFile.endsWith('.kts')) {\n newGradleScript =\n gradleScript.slice(0, insertIndex) +\n pluginKts(pluginVersion) +\n gradleScript.slice(insertIndex);\n } else {\n newGradleScript =\n gradleScript.slice(0, insertIndex) +\n plugin(pluginVersion) +\n gradleScript.slice(insertIndex);\n }\n }\n fs.writeFileSync(appFile, newGradleScript, 'utf8');\n\n maybeAddSourceContextConfig(appFile, newGradleScript, orgSlug, projectSlug);\n\n const buildSpinner = clack.spinner();\n\n buildSpinner.start(\n 'Running ./gradlew to verify changes (this may take a few minutes)...',\n );\n\n try {\n await bash.execute('./gradlew');\n buildSpinner.stop(\n chalk.greenBright(\n `${chalk.bold('Sentry Gradle plugin')} added to the project.`,\n ),\n );\n } catch (e) {\n buildSpinner.stop();\n Sentry.captureException('Gradle Sync failed');\n return false;\n }\n\n return true;\n}\n\n/**\n * Looks for the applications packageName (namespace) in the specified build.gradle(.kts) file.\n *\n * ```\n * android {\n * namespace 'my.package.name' <-- this is what we extract\n *\n * compileSdkVersion = 31\n * ...\n * }\n * ```\n * @param appFile\n * @returns the packageName(namespace) of the app if available\n */\nexport function getNamespace(appFile: string): string | undefined {\n const gradleScript = fs.readFileSync(appFile, 'utf8');\n\n const namespaceMatch = /namespace\\s*=?\\s*['\"]([^'\"]+)['\"]/i.exec(\n gradleScript,\n );\n if (!namespaceMatch || namespaceMatch.length <= 1) {\n clack.log.warn('Unable to determine application package name.');\n Sentry.captureException('No package name');\n return undefined;\n }\n\n const namespace = namespaceMatch[1];\n return namespace;\n}\n\n/**\n * Adds source context configuration to the gradleScript if `sentry {}` block is not yet configured,\n *\n * @param appFile\n * @param gradleScript\n */\nfunction maybeAddSourceContextConfig(\n appFile: string,\n gradleScript: string,\n orgSlug: string,\n projectSlug: string,\n) {\n if (!/sentry\\s*\\{[^}]*\\}/i.test(gradleScript)) {\n // if no sentry {} block is configured, we add our own with source context enabled\n if (appFile.endsWith('.kts')) {\n fs.appendFileSync(\n appFile,\n sourceContextKts(orgSlug, projectSlug),\n 'utf8',\n );\n } else {\n fs.appendFileSync(appFile, sourceContext(orgSlug, projectSlug), 'utf8');\n }\n }\n}\n"]}
@@ -30,7 +30,7 @@ exports.getMainActivity = exports.addManifestSnippet = void 0;
30
30
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
31
31
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
32
32
  const fs = __importStar(require("fs"));
33
- // @ts-ignore - clack is ESM and TS complains about that. It works though
33
+ // @ts-expect-error - clack is ESM and TS complains about that. It works though
34
34
  const clack = __importStar(require("@clack/prompts"));
35
35
  const Sentry = __importStar(require("@sentry/node"));
36
36
  const templates_1 = require("./templates");
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/android/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport * as fs from 'fs';\n// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport { manifest } from './templates';\nimport xml, { Attributes, ElementCompact } from 'xml-js';\nimport chalk from 'chalk';\n\n/**\n * Looks for the closing </application> tag in the manifest and adds the Sentry config after it.\n *\n * For example:\n * ```xml\n * <manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n * xmlns:tools=\"http://schemas.android.com/tools\">\n *\n * <application>\n * ...\n * // this is what we add and more\n * <meta-data android:name=\"io.sentry.dsn\" android:value=\"__dsn__\" />\n * </application> <!-- we are looking for this one\n * </manifest>\n * ```\n *\n * @param manifestFile the path to the main AndroidManifest.xml file\n * @param dsn\n * @returns true if successfully patched the manifest, false otherwise\n */\nexport function addManifestSnippet(manifestFile: string, dsn: string): boolean {\n if (!fs.existsSync(manifestFile)) {\n clack.log.warn('AndroidManifest.xml not found.');\n Sentry.captureException('No AndroidManifest file');\n return false;\n }\n\n const manifestContent = fs.readFileSync(manifestFile, 'utf8');\n\n if (/android:name=\"io\\.sentry[^\"]*\"/i.test(manifestContent)) {\n // sentry is already configured\n clack.log.success(chalk.greenBright('Sentry SDK is already configured.'));\n return true;\n }\n\n const applicationMatch = /<\\/application>/i.exec(manifestContent);\n if (!applicationMatch) {\n clack.log.warn('<application> tag not found within the manifest.');\n Sentry.captureException('No <application> tag');\n return false;\n }\n\n const insertionIndex = applicationMatch.index;\n const newContent =\n manifestContent.slice(0, insertionIndex) +\n manifest(dsn) +\n manifestContent.slice(insertionIndex);\n fs.writeFileSync(manifestFile, newContent, 'utf8');\n\n clack.log.success(\n chalk.greenBright(\n `Updated ${chalk.bold(\n 'AndroidManifest.xml',\n )} with the Sentry SDK configuration.`,\n ),\n );\n\n return true;\n}\n\n/**\n * There might be multiple <activity> in the manifest, as well as multiple <activity-alias> with category LAUNCHER,\n * but only one main activity with action MAIN. We are looking for this one by parsing xml and walking it.\n *\n * In addition, older Android versions required to specify the packag name in the manifest,\n * while the new ones - in the Gradle config. So we are just sanity checking if the package name\n * is in the manifest and returning it as well.\n *\n * For example:\n *\n * ```xml\n * <manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n * xmlns:tools=\"http://schemas.android.com/tools\"\n * package=\"com.example.sample\">\n *\n * <application>\n * <activity\n * android:name=\"ui.MainActivity\"\n * ...other props>\n * <intent-filter>\n * <action android:name=\"android.intent.action.MAIN\" /> <!-- we are looking for this one\n *\n * <category android:name=\"android.intent.category.LAUNCHER\" />\n * </intent-filter>\n * </activity>\n * </application>\n * </manifest>\n * ```\n *\n * @param manifestFile path to the AndroidManifest.xml file\n * @returns package name (if available in the manifest) + the main activity name\n */\nexport function getMainActivity(manifestFile: string): {\n packageName?: string;\n activityName?: string;\n} {\n if (!fs.existsSync(manifestFile)) {\n clack.log.warn('AndroidManifest.xml not found.');\n Sentry.captureException('No AndroidManifest file');\n return {};\n }\n\n const manifestContent = fs.readFileSync(manifestFile, 'utf8');\n const converted: ElementCompact = xml.xml2js(manifestContent, {\n compact: true,\n });\n const activities: ElementCompact[] | ElementCompact | undefined =\n converted.manifest?.application?.activity;\n const packageName: string | undefined =\n converted.manifest?._attributes?.['package'];\n\n if (!activities) {\n clack.log.warn('No activity found in AndroidManifest.');\n Sentry.captureException('No Activity');\n return {};\n }\n\n let mainActivity;\n if (Array.isArray(activities)) {\n const withIntentFilter = activities.filter((a) => !!a['intent-filter']);\n mainActivity = withIntentFilter.find((a) => isMainActivity(a));\n } else if (isMainActivity(activities)) {\n mainActivity = activities;\n }\n\n if (!mainActivity) {\n clack.log.warn('No main activity found in AndroidManifest.');\n Sentry.captureException('No Main Activity');\n return {};\n }\n\n const attrs = mainActivity._attributes;\n const activityName = attrs?.['android:name'] as string | undefined;\n return { packageName: packageName, activityName: activityName };\n}\n\nfunction isMainActivity(activity: ElementCompact): boolean {\n const intentFilters: ElementCompact[] | ElementCompact =\n activity['intent-filter'];\n if (Array.isArray(intentFilters)) {\n return intentFilters.some((i) => {\n const action: ElementCompact[] | ElementCompact | undefined = i.action;\n return hasMainAction(action);\n });\n } else {\n const action: ElementCompact[] | ElementCompact | undefined =\n intentFilters.action;\n return hasMainAction(action);\n }\n}\n\nfunction hasMainAction(\n action: ElementCompact[] | ElementCompact | undefined,\n): boolean {\n if (!action) {\n return false;\n }\n\n function isMain(attrs?: Attributes): boolean {\n return attrs?.['android:name'] === 'android.intent.action.MAIN';\n }\n\n if (Array.isArray(action)) {\n return action.some((c) => {\n return isMain(c._attributes);\n });\n } else {\n return isMain(action._attributes);\n }\n}\n"]}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/android/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport * as fs from 'fs';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport { manifest } from './templates';\nimport xml, { Attributes, ElementCompact } from 'xml-js';\nimport chalk from 'chalk';\n\n/**\n * Looks for the closing </application> tag in the manifest and adds the Sentry config after it.\n *\n * For example:\n * ```xml\n * <manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n * xmlns:tools=\"http://schemas.android.com/tools\">\n *\n * <application>\n * ...\n * // this is what we add and more\n * <meta-data android:name=\"io.sentry.dsn\" android:value=\"__dsn__\" />\n * </application> <!-- we are looking for this one\n * </manifest>\n * ```\n *\n * @param manifestFile the path to the main AndroidManifest.xml file\n * @param dsn\n * @returns true if successfully patched the manifest, false otherwise\n */\nexport function addManifestSnippet(manifestFile: string, dsn: string): boolean {\n if (!fs.existsSync(manifestFile)) {\n clack.log.warn('AndroidManifest.xml not found.');\n Sentry.captureException('No AndroidManifest file');\n return false;\n }\n\n const manifestContent = fs.readFileSync(manifestFile, 'utf8');\n\n if (/android:name=\"io\\.sentry[^\"]*\"/i.test(manifestContent)) {\n // sentry is already configured\n clack.log.success(chalk.greenBright('Sentry SDK is already configured.'));\n return true;\n }\n\n const applicationMatch = /<\\/application>/i.exec(manifestContent);\n if (!applicationMatch) {\n clack.log.warn('<application> tag not found within the manifest.');\n Sentry.captureException('No <application> tag');\n return false;\n }\n\n const insertionIndex = applicationMatch.index;\n const newContent =\n manifestContent.slice(0, insertionIndex) +\n manifest(dsn) +\n manifestContent.slice(insertionIndex);\n fs.writeFileSync(manifestFile, newContent, 'utf8');\n\n clack.log.success(\n chalk.greenBright(\n `Updated ${chalk.bold(\n 'AndroidManifest.xml',\n )} with the Sentry SDK configuration.`,\n ),\n );\n\n return true;\n}\n\n/**\n * There might be multiple <activity> in the manifest, as well as multiple <activity-alias> with category LAUNCHER,\n * but only one main activity with action MAIN. We are looking for this one by parsing xml and walking it.\n *\n * In addition, older Android versions required to specify the packag name in the manifest,\n * while the new ones - in the Gradle config. So we are just sanity checking if the package name\n * is in the manifest and returning it as well.\n *\n * For example:\n *\n * ```xml\n * <manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n * xmlns:tools=\"http://schemas.android.com/tools\"\n * package=\"com.example.sample\">\n *\n * <application>\n * <activity\n * android:name=\"ui.MainActivity\"\n * ...other props>\n * <intent-filter>\n * <action android:name=\"android.intent.action.MAIN\" /> <!-- we are looking for this one\n *\n * <category android:name=\"android.intent.category.LAUNCHER\" />\n * </intent-filter>\n * </activity>\n * </application>\n * </manifest>\n * ```\n *\n * @param manifestFile path to the AndroidManifest.xml file\n * @returns package name (if available in the manifest) + the main activity name\n */\nexport function getMainActivity(manifestFile: string): {\n packageName?: string;\n activityName?: string;\n} {\n if (!fs.existsSync(manifestFile)) {\n clack.log.warn('AndroidManifest.xml not found.');\n Sentry.captureException('No AndroidManifest file');\n return {};\n }\n\n const manifestContent = fs.readFileSync(manifestFile, 'utf8');\n const converted: ElementCompact = xml.xml2js(manifestContent, {\n compact: true,\n });\n const activities: ElementCompact[] | ElementCompact | undefined =\n converted.manifest?.application?.activity;\n const packageName: string | undefined =\n converted.manifest?._attributes?.['package'];\n\n if (!activities) {\n clack.log.warn('No activity found in AndroidManifest.');\n Sentry.captureException('No Activity');\n return {};\n }\n\n let mainActivity;\n if (Array.isArray(activities)) {\n const withIntentFilter = activities.filter((a) => !!a['intent-filter']);\n mainActivity = withIntentFilter.find((a) => isMainActivity(a));\n } else if (isMainActivity(activities)) {\n mainActivity = activities;\n }\n\n if (!mainActivity) {\n clack.log.warn('No main activity found in AndroidManifest.');\n Sentry.captureException('No Main Activity');\n return {};\n }\n\n const attrs = mainActivity._attributes;\n const activityName = attrs?.['android:name'] as string | undefined;\n return { packageName: packageName, activityName: activityName };\n}\n\nfunction isMainActivity(activity: ElementCompact): boolean {\n const intentFilters: ElementCompact[] | ElementCompact =\n activity['intent-filter'];\n if (Array.isArray(intentFilters)) {\n return intentFilters.some((i) => {\n const action: ElementCompact[] | ElementCompact | undefined = i.action;\n return hasMainAction(action);\n });\n } else {\n const action: ElementCompact[] | ElementCompact | undefined =\n intentFilters.action;\n return hasMainAction(action);\n }\n}\n\nfunction hasMainAction(\n action: ElementCompact[] | ElementCompact | undefined,\n): boolean {\n if (!action) {\n return false;\n }\n\n function isMain(attrs?: Attributes): boolean {\n return attrs?.['android:name'] === 'android.intent.action.MAIN';\n }\n\n if (Array.isArray(action)) {\n return action.some((c) => {\n return isMain(c._attributes);\n });\n } else {\n return isMain(action._attributes);\n }\n}\n"]}
@@ -1,2 +1,2 @@
1
- import { WizardOptions } from '../utils/types';
2
- export declare function runAppleWizard(options: WizardOptions): Promise<void>;
1
+ import { AppleWizardOptions } from './options';
2
+ export declare function runAppleWizard(options: AppleWizardOptions): Promise<void>;
@@ -32,21 +32,19 @@ exports.runAppleWizard = void 0;
32
32
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
33
33
  /* eslint-disable @typescript-eslint/no-unsafe-call */
34
34
  /* eslint-disable @typescript-eslint/no-unused-vars */
35
- // @ts-ignore - clack is ESM and TS complains about that. It works though
35
+ // @ts-expect-error - clack is ESM and TS complains about that. It works though
36
36
  const prompts_1 = __importDefault(require("@clack/prompts"));
37
- const chalk_1 = __importDefault(require("chalk"));
38
- const fs = __importStar(require("fs"));
39
- const path = __importStar(require("path"));
40
- const xcode_manager_1 = require("./xcode-manager");
41
- const codeTools = __importStar(require("./code-tools"));
42
- const bash = __importStar(require("../utils/bash"));
43
- const SentryUtils = __importStar(require("../utils/sentrycli-utils"));
44
37
  const Sentry = __importStar(require("@sentry/node"));
38
+ const chalk_1 = __importDefault(require("chalk"));
45
39
  const telemetry_1 = require("../telemetry");
40
+ const SentryUtils = __importStar(require("../utils/sentrycli-utils"));
46
41
  const cocoapod = __importStar(require("./cocoapod"));
47
- const fastlane = __importStar(require("./fastlane"));
42
+ const codeTools = __importStar(require("./code-tools"));
48
43
  /* eslint-enable @typescript-eslint/no-unused-vars */
49
- const clack_utils_1 = require("../utils/clack-utils");
44
+ const clack_1 = require("../utils/clack");
45
+ const check_installed_cli_1 = require("./check-installed-cli");
46
+ const configure_fastlane_1 = require("./configure-fastlane");
47
+ const lookup_xcode_project_1 = require("./lookup-xcode-project");
50
48
  async function runAppleWizard(options) {
51
49
  return (0, telemetry_1.withTelemetry)({
52
50
  enabled: options.telemetryEnabled,
@@ -56,58 +54,29 @@ async function runAppleWizard(options) {
56
54
  }
57
55
  exports.runAppleWizard = runAppleWizard;
58
56
  async function runAppleWizardWithTelementry(options) {
59
- (0, clack_utils_1.printWelcome)({
57
+ // Define options with defaults
58
+ const projectDir = options.projectDir ?? process.cwd();
59
+ // Step - Welcome Message
60
+ (0, clack_1.printWelcome)({
60
61
  wizardName: 'Sentry Apple Wizard',
61
62
  promoCode: options.promoCode,
62
63
  });
63
- await (0, clack_utils_1.confirmContinueIfNoOrDirtyGitRepo)();
64
- const hasCli = bash.hasSentryCLI();
65
- Sentry.setTag('has-cli', hasCli);
66
- if (!hasCli) {
67
- if (!(await (0, telemetry_1.traceStep)('Ask for SentryCLI', () => (0, clack_utils_1.askToInstallSentryCLI)()))) {
68
- prompts_1.default.log.warn("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/");
69
- Sentry.setTag('CLI-Installed', false);
70
- }
71
- else {
72
- await bash.installSentryCLI();
73
- Sentry.setTag('CLI-Installed', true);
74
- }
75
- }
76
- const projectDir = process.cwd();
77
- const xcodeProjFiles = searchXcodeProject(projectDir);
78
- if (!xcodeProjFiles || xcodeProjFiles.length === 0) {
79
- prompts_1.default.log.error('No Xcode project found. Please run this command from the root of your project.');
80
- await (0, clack_utils_1.abort)();
81
- return;
82
- }
83
- let xcodeProjFile;
84
- if (xcodeProjFiles.length === 1) {
85
- xcodeProjFile = xcodeProjFiles[0];
86
- Sentry.setTag('multiple-projects', false);
87
- }
88
- else {
89
- Sentry.setTag('multiple-projects', true);
90
- xcodeProjFile = (await (0, telemetry_1.traceStep)('Choose Xcode project', () => (0, clack_utils_1.askForItemSelection)(xcodeProjFiles, 'Which project do you want to add Sentry to?'))).value;
91
- }
92
- const pbxproj = path.join(projectDir, xcodeProjFile, 'project.pbxproj');
93
- if (!fs.existsSync(pbxproj)) {
94
- prompts_1.default.log.error(`No pbxproj found at ${xcodeProjFile}`);
95
- await (0, clack_utils_1.abort)();
96
- return;
97
- }
98
- const { project, apiKey } = await getSentryProjectAndApiKey(options);
99
- const xcProject = new xcode_manager_1.XcodeProject(pbxproj);
100
- const availableTargets = xcProject.getAllTargets();
101
- if (availableTargets.length == 0) {
102
- prompts_1.default.log.error(`No suitable target found in ${xcodeProjFile}`);
103
- Sentry.setTag('No-Target', true);
104
- await (0, clack_utils_1.abort)();
105
- return;
106
- }
107
- const target = availableTargets.length == 1
108
- ? availableTargets[0]
109
- : (await (0, telemetry_1.traceStep)('Choose target', () => (0, clack_utils_1.askForItemSelection)(availableTargets, 'Which target do you want to add Sentry to?'))).value;
110
- SentryUtils.createSentryCLIRC(projectDir, { auth_token: apiKey.token });
64
+ // Step - Git Status Check
65
+ await (0, clack_1.confirmContinueIfNoOrDirtyGitRepo)({
66
+ ignoreGitChanges: options.ignoreGitChanges,
67
+ cwd: projectDir,
68
+ });
69
+ // Step - Sentry CLI Check
70
+ await (0, check_installed_cli_1.checkInstalledCLI)();
71
+ // Step - Xcode Project Lookup
72
+ // This step should be run before the Sentry Project and API Key step
73
+ // because it can abort the wizard if no Xcode project is found.
74
+ const { xcProject, target } = await (0, lookup_xcode_project_1.lookupXcodeProject)({
75
+ projectDir,
76
+ });
77
+ // Step - Sentry Project and API Key
78
+ const { selectedProject, authToken } = await (0, clack_1.getOrAskForProjectData)(options, 'apple-ios');
79
+ SentryUtils.createSentryCLIRC(projectDir, { auth_token: authToken });
111
80
  prompts_1.default.log.info(`Created a ${chalk_1.default.cyan('.sentryclirc')} file in your project directory to provide an auth token for Sentry CLI.
112
81
 
113
82
  It was also added to your ${chalk_1.default.cyan('.gitignore')} file.
@@ -115,7 +84,7 @@ Set the ${chalk_1.default.cyan('SENTRY_AUTH_TOKEN')} environment variable in you
115
84
  let hasCocoa = cocoapod.usesCocoaPod(projectDir);
116
85
  Sentry.setTag('cocoapod-exists', hasCocoa);
117
86
  if (hasCocoa) {
118
- const pm = (await (0, telemetry_1.traceStep)('Choose a package manager', () => (0, clack_utils_1.askForItemSelection)(['Swift Package Manager', 'CocoaPods'], 'Which package manager would you like to use to add Sentry?'))).value;
87
+ const pm = (await (0, telemetry_1.traceStep)('Choose a package manager', () => (0, clack_1.askForItemSelection)(['Swift Package Manager', 'CocoaPods'], 'Which package manager would you like to use to add Sentry?'))).value;
119
88
  hasCocoa = pm === 'CocoaPods';
120
89
  if (hasCocoa) {
121
90
  const podAdded = await (0, telemetry_1.traceStep)('Add CocoaPods reference', () => cocoapod.addCocoaPods(projectDir));
@@ -127,74 +96,24 @@ Set the ${chalk_1.default.cyan('SENTRY_AUTH_TOKEN')} environment variable in you
127
96
  }
128
97
  Sentry.setTag('package-manager', hasCocoa ? 'cocoapods' : 'SPM');
129
98
  (0, telemetry_1.traceStep)('Update Xcode project', () => {
130
- xcProject.updateXcodeProject(project, target, !hasCocoa, true);
99
+ xcProject.updateXcodeProject(selectedProject, target, !hasCocoa, true);
131
100
  });
132
101
  const codeAdded = (0, telemetry_1.traceStep)('Add code snippet', () => {
133
102
  const files = xcProject.filesForTarget(target);
134
103
  if (files === undefined || files.length == 0)
135
104
  return false;
136
- return codeTools.addCodeSnippetToProject(projectDir, files, project.keys[0].dsn.public);
105
+ return codeTools.addCodeSnippetToProject(projectDir, files, selectedProject.keys[0].dsn.public);
137
106
  });
138
107
  Sentry.setTag('Snippet-Added', codeAdded);
139
108
  if (!codeAdded) {
140
109
  prompts_1.default.log.warn('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');
141
110
  }
142
- const hasFastlane = fastlane.fastFile(projectDir);
143
- Sentry.setTag('fastlane-exists', hasFastlane);
144
- if (hasFastlane) {
145
- const addLane = await prompts_1.default.confirm({
146
- message: 'Found a Fastfile in your project. Do you want to configure a lane to upload debug symbols to Sentry?',
147
- });
148
- Sentry.setTag('fastlane-desired', addLane);
149
- if (addLane) {
150
- const added = await (0, telemetry_1.traceStep)('Configure fastlane', () => fastlane.addSentryToFastlane(projectDir, project.organization.slug, project.slug));
151
- Sentry.setTag('fastlane-added', added);
152
- if (added) {
153
- prompts_1.default.log.step('A new step was added to your fastlane file. Now and you build your project with fastlane, debug symbols and source context will be uploaded to Sentry.');
154
- }
155
- else {
156
- prompts_1.default.log.warn('Could not edit your fastlane file to upload debug symbols to Sentry. Please follow the instructions at https://docs.sentry.io/platforms/apple/guides/ios/dsym/#fastlane');
157
- }
158
- }
159
- }
111
+ // Step - Fastlane Configuration
112
+ await (0, configure_fastlane_1.configureFastlane)({
113
+ projectDir,
114
+ orgSlug: selectedProject.organization.slug,
115
+ projectSlug: selectedProject.slug,
116
+ });
160
117
  prompts_1.default.log.success('Sentry was successfully added to your project! Run your project to send your first event to Sentry. Go to Sentry.io to see whether everything is working fine.');
161
118
  }
162
- //Prompt for Sentry project and API key
163
- async function getSentryProjectAndApiKey(options) {
164
- const { selectedProject, authToken } = await (0, clack_utils_1.getOrAskForProjectData)(options);
165
- return { project: selectedProject, apiKey: { token: authToken } };
166
- }
167
- function searchXcodeProject(at) {
168
- const projs = findFilesWithExtension(at, '.xcodeproj');
169
- if (projs.length > 0) {
170
- return projs;
171
- }
172
- const workspace = findFilesWithExtension(at, '.xcworkspace');
173
- if (workspace.length == 0) {
174
- return [];
175
- }
176
- const xsworkspacedata = path.join(at, workspace[0], 'contents.xcworkspacedata');
177
- if (!fs.existsSync(xsworkspacedata)) {
178
- return [];
179
- }
180
- const groupRegex = /location *= *"group:([^"]+)"/gim;
181
- const content = fs.readFileSync(xsworkspacedata, 'utf8');
182
- let matches = groupRegex.exec(content);
183
- while (matches) {
184
- const group = matches[1];
185
- const groupPath = path.join(at, group);
186
- if (!group.endsWith('Pods.xcodeproj') &&
187
- group.endsWith('.xcodeproj') &&
188
- fs.existsSync(groupPath)) {
189
- projs.push(group);
190
- }
191
- matches = groupRegex.exec(content);
192
- }
193
- return projs;
194
- }
195
- //find files with the given extension
196
- function findFilesWithExtension(dir, extension) {
197
- const files = fs.readdirSync(dir);
198
- return files.filter((file) => file.endsWith(extension));
199
- }
200
119
  //# sourceMappingURL=apple-wizard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"apple-wizard.js","sourceRoot":"","sources":["../../../src/apple/apple-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { XcodeProject } from './xcode-manager';\nimport * as codeTools from './code-tools';\nimport * as bash from '../utils/bash';\nimport * as SentryUtils from '../utils/sentrycli-utils';\nimport { SentryProjectData, WizardOptions } from '../utils/types';\nimport * as Sentry from '@sentry/node';\nimport { traceStep, withTelemetry } from '../telemetry';\nimport * as cocoapod from './cocoapod';\nimport * as fastlane from './fastlane';\n\n/* eslint-enable @typescript-eslint/no-unused-vars */\n\nimport {\n askToInstallSentryCLI,\n printWelcome,\n abort,\n askForItemSelection,\n confirmContinueIfNoOrDirtyGitRepo,\n getOrAskForProjectData,\n} from '../utils/clack-utils';\n\nexport async function runAppleWizard(options: WizardOptions): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'ios',\n wizardOptions: options,\n },\n () => runAppleWizardWithTelementry(options),\n );\n}\n\nasync function runAppleWizardWithTelementry(\n options: WizardOptions,\n): Promise<void> {\n printWelcome({\n wizardName: 'Sentry Apple Wizard',\n promoCode: options.promoCode,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo();\n\n const hasCli = bash.hasSentryCLI();\n Sentry.setTag('has-cli', hasCli);\n if (!hasCli) {\n if (\n !(await traceStep('Ask for SentryCLI', () => askToInstallSentryCLI()))\n ) {\n clack.log.warn(\n \"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/\",\n );\n Sentry.setTag('CLI-Installed', false);\n } else {\n await bash.installSentryCLI();\n Sentry.setTag('CLI-Installed', true);\n }\n }\n\n const projectDir = process.cwd();\n const xcodeProjFiles = searchXcodeProject(projectDir);\n\n if (!xcodeProjFiles || xcodeProjFiles.length === 0) {\n clack.log.error(\n 'No Xcode project found. Please run this command from the root of your project.',\n );\n await abort();\n return;\n }\n\n let xcodeProjFile;\n\n if (xcodeProjFiles.length === 1) {\n xcodeProjFile = xcodeProjFiles[0];\n Sentry.setTag('multiple-projects', false);\n } else {\n Sentry.setTag('multiple-projects', true);\n xcodeProjFile = (\n await traceStep('Choose Xcode project', () =>\n askForItemSelection(\n xcodeProjFiles,\n 'Which project do you want to add Sentry to?',\n ),\n )\n ).value;\n }\n\n const pbxproj = path.join(projectDir, xcodeProjFile, 'project.pbxproj');\n\n if (!fs.existsSync(pbxproj)) {\n clack.log.error(`No pbxproj found at ${xcodeProjFile}`);\n await abort();\n return;\n }\n\n const { project, apiKey } = await getSentryProjectAndApiKey(options);\n\n const xcProject = new XcodeProject(pbxproj);\n\n const availableTargets = xcProject.getAllTargets();\n\n if (availableTargets.length == 0) {\n clack.log.error(`No suitable target found in ${xcodeProjFile}`);\n Sentry.setTag('No-Target', true);\n await abort();\n return;\n }\n\n const target =\n availableTargets.length == 1\n ? availableTargets[0]\n : (\n await traceStep('Choose target', () =>\n askForItemSelection(\n availableTargets,\n 'Which target do you want to add Sentry to?',\n ),\n )\n ).value;\n\n SentryUtils.createSentryCLIRC(projectDir, { auth_token: apiKey.token });\n clack.log.info(\n `Created a ${chalk.cyan(\n '.sentryclirc',\n )} file in your project directory to provide an auth token for Sentry CLI.\n \nIt was also added to your ${chalk.cyan('.gitignore')} file.\nSet the ${chalk.cyan(\n 'SENTRY_AUTH_TOKEN',\n )} environment variable in your CI environment. See https://docs.sentry.io/cli/configuration/#auth-token for more information.`,\n );\n\n let hasCocoa = cocoapod.usesCocoaPod(projectDir);\n Sentry.setTag('cocoapod-exists', hasCocoa);\n\n if (hasCocoa) {\n const pm = (\n await traceStep('Choose a package manager', () =>\n askForItemSelection(\n ['Swift Package Manager', 'CocoaPods'],\n 'Which package manager would you like to use to add Sentry?',\n ),\n )\n ).value;\n\n hasCocoa = pm === 'CocoaPods';\n if (hasCocoa) {\n const podAdded = await traceStep('Add CocoaPods reference', () =>\n cocoapod.addCocoaPods(projectDir),\n );\n Sentry.setTag('cocoapod-added', podAdded);\n if (!podAdded) {\n clack.log.warn(\n \"Could not add Sentry pod to your Podfile. You'll have to add it manually.\\nPlease follow the instructions at https://docs.sentry.io/platforms/apple/guides/ios/#install\",\n );\n }\n }\n }\n\n Sentry.setTag('package-manager', hasCocoa ? 'cocoapods' : 'SPM');\n traceStep('Update Xcode project', () => {\n xcProject.updateXcodeProject(project, target, !hasCocoa, true);\n });\n\n const codeAdded = traceStep('Add code snippet', () => {\n const files = xcProject.filesForTarget(target);\n if (files === undefined || files.length == 0) return false;\n\n return codeTools.addCodeSnippetToProject(\n projectDir,\n files,\n project.keys[0].dsn.public,\n );\n });\n\n Sentry.setTag('Snippet-Added', codeAdded);\n\n if (!codeAdded) {\n clack.log.warn(\n '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',\n );\n }\n\n const hasFastlane = fastlane.fastFile(projectDir);\n Sentry.setTag('fastlane-exists', hasFastlane);\n if (hasFastlane) {\n const addLane = await clack.confirm({\n message:\n 'Found a Fastfile in your project. Do you want to configure a lane to upload debug symbols to Sentry?',\n });\n Sentry.setTag('fastlane-desired', addLane);\n if (addLane) {\n const added = await traceStep('Configure fastlane', () =>\n fastlane.addSentryToFastlane(\n projectDir,\n project.organization.slug,\n project.slug,\n ),\n );\n Sentry.setTag('fastlane-added', added);\n if (added) {\n clack.log.step(\n 'A new step was added to your fastlane file. Now and you build your project with fastlane, debug symbols and source context will be uploaded to Sentry.',\n );\n } else {\n clack.log.warn(\n 'Could not edit your fastlane file to upload debug symbols to Sentry. Please follow the instructions at https://docs.sentry.io/platforms/apple/guides/ios/dsym/#fastlane',\n );\n }\n }\n }\n\n clack.log.success(\n 'Sentry was successfully added to your project! Run your project to send your first event to Sentry. Go to Sentry.io to see whether everything is working fine.',\n );\n}\n\n//Prompt for Sentry project and API key\nasync function getSentryProjectAndApiKey(\n options: WizardOptions,\n): Promise<{ project: SentryProjectData; apiKey: { token: string } }> {\n const { selectedProject, authToken } = await getOrAskForProjectData(options);\n return { project: selectedProject, apiKey: { token: authToken } };\n}\n\nfunction searchXcodeProject(at: string): string[] {\n const projs = findFilesWithExtension(at, '.xcodeproj');\n if (projs.length > 0) {\n return projs;\n }\n\n const workspace = findFilesWithExtension(at, '.xcworkspace');\n if (workspace.length == 0) {\n return [];\n }\n\n const xsworkspacedata = path.join(\n at,\n workspace[0],\n 'contents.xcworkspacedata',\n );\n if (!fs.existsSync(xsworkspacedata)) {\n return [];\n }\n const groupRegex = /location *= *\"group:([^\"]+)\"/gim;\n const content = fs.readFileSync(xsworkspacedata, 'utf8');\n let matches = groupRegex.exec(content);\n\n while (matches) {\n const group = matches[1];\n const groupPath = path.join(at, group);\n if (\n !group.endsWith('Pods.xcodeproj') &&\n group.endsWith('.xcodeproj') &&\n fs.existsSync(groupPath)\n ) {\n projs.push(group);\n }\n matches = groupRegex.exec(content);\n }\n return projs;\n}\n\n//find files with the given extension\nfunction findFilesWithExtension(dir: string, extension: string): string[] {\n const files = fs.readdirSync(dir);\n return files.filter((file) => file.endsWith(extension));\n}\n"]}
1
+ {"version":3,"file":"apple-wizard.js","sourceRoot":"","sources":["../../../src/apple/apple-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport chalk from 'chalk';\nimport { traceStep, withTelemetry } from '../telemetry';\nimport * as SentryUtils from '../utils/sentrycli-utils';\nimport * as cocoapod from './cocoapod';\nimport * as codeTools from './code-tools';\n\n/* eslint-enable @typescript-eslint/no-unused-vars */\n\nimport {\n askForItemSelection,\n confirmContinueIfNoOrDirtyGitRepo,\n getOrAskForProjectData,\n printWelcome,\n} from '../utils/clack';\nimport { checkInstalledCLI } from './check-installed-cli';\nimport { configureFastlane } from './configure-fastlane';\nimport { lookupXcodeProject } from './lookup-xcode-project';\nimport { AppleWizardOptions } from './options';\n\nexport async function runAppleWizard(\n options: AppleWizardOptions,\n): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'ios',\n wizardOptions: options,\n },\n () => runAppleWizardWithTelementry(options),\n );\n}\n\nasync function runAppleWizardWithTelementry(\n options: AppleWizardOptions,\n): Promise<void> {\n // Define options with defaults\n const projectDir = options.projectDir ?? process.cwd();\n\n // Step - Welcome Message\n printWelcome({\n wizardName: 'Sentry Apple Wizard',\n promoCode: options.promoCode,\n });\n\n // Step - Git Status Check\n await confirmContinueIfNoOrDirtyGitRepo({\n ignoreGitChanges: options.ignoreGitChanges,\n cwd: projectDir,\n });\n\n // Step - Sentry CLI Check\n await checkInstalledCLI();\n\n // Step - Xcode Project Lookup\n // This step should be run before the Sentry Project and API Key step\n // because it can abort the wizard if no Xcode project is found.\n const { xcProject, target } = await lookupXcodeProject({\n projectDir,\n });\n\n // Step - Sentry Project and API Key\n const { selectedProject, authToken } = await getOrAskForProjectData(\n options,\n 'apple-ios',\n );\n SentryUtils.createSentryCLIRC(projectDir, { auth_token: authToken });\n clack.log.info(\n `Created a ${chalk.cyan(\n '.sentryclirc',\n )} file in your project directory to provide an auth token for Sentry CLI.\n \nIt was also added to your ${chalk.cyan('.gitignore')} file.\nSet the ${chalk.cyan(\n 'SENTRY_AUTH_TOKEN',\n )} environment variable in your CI environment. See https://docs.sentry.io/cli/configuration/#auth-token for more information.`,\n );\n\n let hasCocoa = cocoapod.usesCocoaPod(projectDir);\n Sentry.setTag('cocoapod-exists', hasCocoa);\n\n if (hasCocoa) {\n const pm = (\n await traceStep('Choose a package manager', () =>\n askForItemSelection(\n ['Swift Package Manager', 'CocoaPods'],\n 'Which package manager would you like to use to add Sentry?',\n ),\n )\n ).value;\n\n hasCocoa = pm === 'CocoaPods';\n if (hasCocoa) {\n const podAdded = await traceStep('Add CocoaPods reference', () =>\n cocoapod.addCocoaPods(projectDir),\n );\n Sentry.setTag('cocoapod-added', podAdded);\n if (!podAdded) {\n clack.log.warn(\n \"Could not add Sentry pod to your Podfile. You'll have to add it manually.\\nPlease follow the instructions at https://docs.sentry.io/platforms/apple/guides/ios/#install\",\n );\n }\n }\n }\n\n Sentry.setTag('package-manager', hasCocoa ? 'cocoapods' : 'SPM');\n traceStep('Update Xcode project', () => {\n xcProject.updateXcodeProject(selectedProject, target, !hasCocoa, true);\n });\n\n const codeAdded = traceStep('Add code snippet', () => {\n const files = xcProject.filesForTarget(target);\n if (files === undefined || files.length == 0) return false;\n\n return codeTools.addCodeSnippetToProject(\n projectDir,\n files,\n selectedProject.keys[0].dsn.public,\n );\n });\n\n Sentry.setTag('Snippet-Added', codeAdded);\n\n if (!codeAdded) {\n clack.log.warn(\n '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',\n );\n }\n\n // Step - Fastlane Configuration\n await configureFastlane({\n projectDir,\n orgSlug: selectedProject.organization.slug,\n projectSlug: selectedProject.slug,\n });\n\n clack.log.success(\n 'Sentry was successfully added to your project! Run your project to send your first event to Sentry. Go to Sentry.io to see whether everything is working fine.',\n );\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function checkInstalledCLI(): Promise<void>;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.checkInstalledCLI = void 0;
30
+ // @ts-expect-error - clack is ESM and TS complains about that. It works though
31
+ const prompts_1 = __importDefault(require("@clack/prompts"));
32
+ const Sentry = __importStar(require("@sentry/node"));
33
+ const telemetry_1 = require("../telemetry");
34
+ const bash = __importStar(require("../utils/bash"));
35
+ const clack_1 = require("../utils/clack");
36
+ const debug_1 = require("../utils/debug");
37
+ async function checkInstalledCLI() {
38
+ (0, debug_1.debug)(`Checking if sentry-cli is installed`);
39
+ const hasCli = bash.hasSentryCLI();
40
+ Sentry.setTag('has-cli', hasCli);
41
+ if (hasCli) {
42
+ // If the CLI is installed, we don't need to ask the user to install it and can exit early.
43
+ (0, debug_1.debug)(`sentry-cli is installed`);
44
+ return;
45
+ }
46
+ (0, debug_1.debug)(`sentry-cli is not installed, asking user to install it`);
47
+ const shouldInstallCLI = await (0, telemetry_1.traceStep)('Ask for SentryCLI', () => (0, clack_1.askToInstallSentryCLI)());
48
+ if (shouldInstallCLI) {
49
+ (0, debug_1.debug)(`User agreed to install sentry-cli`);
50
+ await bash.installSentryCLI();
51
+ Sentry.setTag('CLI-Installed', true);
52
+ }
53
+ else {
54
+ (0, debug_1.debug)(`User declined to install sentry-cli`);
55
+ prompts_1.default.log.warn("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/");
56
+ Sentry.setTag('CLI-Installed', false);
57
+ }
58
+ }
59
+ exports.checkInstalledCLI = checkInstalledCLI;
60
+ //# sourceMappingURL=check-installed-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-installed-cli.js","sourceRoot":"","sources":["../../../src/apple/check-installed-cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+EAA+E;AAC/E,6DAAmC;AACnC,qDAAuC;AACvC,4CAAyC;AACzC,oDAAsC;AACtC,0CAAuD;AACvD,0CAAuC;AAEhC,KAAK,UAAU,iBAAiB;IACrC,IAAA,aAAK,EAAC,qCAAqC,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;IACnC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,MAAM,EAAE;QACV,2FAA2F;QAC3F,IAAA,aAAK,EAAC,yBAAyB,CAAC,CAAC;QACjC,OAAO;KACR;IAED,IAAA,aAAK,EAAC,wDAAwD,CAAC,CAAC;IAChE,MAAM,gBAAgB,GAAG,MAAM,IAAA,qBAAS,EAAC,mBAAmB,EAAE,GAAG,EAAE,CACjE,IAAA,6BAAqB,GAAE,CACxB,CAAC;IACF,IAAI,gBAAgB,EAAE;QACpB,IAAA,aAAK,EAAC,mCAAmC,CAAC,CAAC;QAC3C,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;KACtC;SAAM;QACL,IAAA,aAAK,EAAC,qCAAqC,CAAC,CAAC;QAC7C,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,gKAAgK,CACjK,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;KACvC;AACH,CAAC;AAzBD,8CAyBC","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport { traceStep } from '../telemetry';\nimport * as bash from '../utils/bash';\nimport { askToInstallSentryCLI } from '../utils/clack';\nimport { debug } from '../utils/debug';\n\nexport async function checkInstalledCLI() {\n debug(`Checking if sentry-cli is installed`);\n const hasCli = bash.hasSentryCLI();\n Sentry.setTag('has-cli', hasCli);\n if (hasCli) {\n // If the CLI is installed, we don't need to ask the user to install it and can exit early.\n debug(`sentry-cli is installed`);\n return;\n }\n\n debug(`sentry-cli is not installed, asking user to install it`);\n const shouldInstallCLI = await traceStep('Ask for SentryCLI', () =>\n askToInstallSentryCLI(),\n );\n if (shouldInstallCLI) {\n debug(`User agreed to install sentry-cli`);\n await bash.installSentryCLI();\n Sentry.setTag('CLI-Installed', true);\n } else {\n debug(`User declined to install sentry-cli`);\n clack.log.warn(\n \"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/\",\n );\n Sentry.setTag('CLI-Installed', false);\n }\n}\n"]}
@@ -31,7 +31,7 @@ const fs = __importStar(require("fs"));
31
31
  const path = __importStar(require("path"));
32
32
  const bash = __importStar(require("../utils/bash"));
33
33
  const Sentry = __importStar(require("@sentry/node"));
34
- // @ts-ignore - clack is ESM and TS complains about that. It works though
34
+ // @ts-expect-error - clack is ESM and TS complains about that. It works though
35
35
  const clack = __importStar(require("@clack/prompts"));
36
36
  const chalk_1 = __importDefault(require("chalk"));
37
37
  function usesCocoaPod(projPath) {
@@ -1 +1 @@
1
- {"version":3,"file":"cocoapod.js","sourceRoot":"","sources":["../../../src/apple/cocoapod.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAC7B,oDAAsC;AACtC,qDAAuC;AACvC,yEAAyE;AACzE,sDAAwC;AACxC,kDAA0B;AAE1B,SAAgB,YAAY,CAAC,QAAgB;IAC3C,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AACvD,CAAC;AAFD,oCAEC;AAEM,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE/C,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAEpD,IACE,wDAAwD,CAAC,IAAI,CAAC,UAAU,CAAC,EACzE;QACA,0BAA0B;QAC1B,OAAO,IAAI,CAAC;KACb;IAED,IAAI,QAAQ,GAAG,+BAA+B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChE,IAAI,CAAC,QAAQ,EAAE;QACb,0EAA0E;QAC1E,MAAM,cAAc,GAAG,iCAAiC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1E,IAAI,CAAC,cAAc,EAAE;YACnB,OAAO,KAAK,CAAC;SACd;QACD,QAAQ,GAAG,cAAc,CAAC;KAC3B;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACxD,MAAM,cAAc,GAClB,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC;QAChC,IAAI;QACJ,QAAQ,CAAC,CAAC,CAAC;QACX,gBAAgB;QAChB,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAChC,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;IAElD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IAE3D,MAAM,UAAU,EAAE,CAAC;IAEnB,OAAO,IAAI,CAAC;AACd,CAAC;AApCD,oCAoCC;AAEM,KAAK,UAAU,UAAU,CAAC,GAAG,GAAG,GAAG;IACxC,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IACvC,cAAc,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAE9E,IAAI;QACF,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,qBAAqB,CAAC,CAAC;QACnD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,0BAA0B,CAAC,CAAC;QACxD,cAAc,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;KACvC;IAAC,OAAO,CAAC,EAAE;QACV,cAAc,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QACvC,KAAK,CAAC,GAAG,CAAC,KAAK,CACb,GAAG,eAAK,CAAC,GAAG,CACV,2DAA2D,CAE5D,OAAO,CAAC,OAAO,eAAK,CAAC,GAAG,CACvB,8HAA8H,CAC/H,EAAE,CACJ,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,4BAA4B,CAAC,CAAC;KACvD;AACH,CAAC;AAtBD,gCAsBC","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport * as bash from '../utils/bash';\nimport * as Sentry from '@sentry/node';\n// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\n\nexport function usesCocoaPod(projPath: string): boolean {\n return fs.existsSync(path.join(projPath, 'Podfile'));\n}\n\nexport async function addCocoaPods(projPath: string): Promise<boolean> {\n const podfile = path.join(projPath, 'Podfile');\n\n const podContent = fs.readFileSync(podfile, 'utf8');\n\n if (\n /^\\s*pod\\s+(['\"]Sentry['\"]|['\"]SentrySwiftUI['\"])\\s*$/im.test(podContent)\n ) {\n // Already have Sentry pod\n return true;\n }\n\n let podMatch = /^( *)pod\\s+['\"](\\w+)['\"] *$/im.exec(podContent);\n if (!podMatch) {\n // No Podfile is empty, will try to add Sentry pod after \"use_frameworks!\"\n const frameworkMatch = /^( *)use_frameworks![^\\n]* *$/im.exec(podContent);\n if (!frameworkMatch) {\n return false;\n }\n podMatch = frameworkMatch;\n }\n\n const insertIndex = podMatch.index + podMatch[0].length;\n const newFileContent =\n podContent.slice(0, insertIndex) +\n '\\n' +\n podMatch[1] +\n \"pod 'Sentry'\\n\" +\n podContent.slice(insertIndex);\n fs.writeFileSync(podfile, newFileContent, 'utf8');\n\n clack.log.step('Sentry pod added to the project podFile.');\n\n await podInstall();\n\n return true;\n}\n\nexport async function podInstall(dir = '.') {\n const installSpinner = clack.spinner();\n installSpinner.start(\"Running 'pod install'. This may take a few minutes...\");\n\n try {\n await bash.execute(`cd ${dir} && pod repo update`);\n await bash.execute(`cd ${dir} && pod install --silent`);\n installSpinner.stop('Pods installed.');\n Sentry.setTag('pods-installed', true);\n } catch (e) {\n installSpinner.stop('Failed to install pods.');\n Sentry.setTag('pods-installed', false);\n clack.log.error(\n `${chalk.red(\n 'Encountered the following error during pods installation:',\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n )}\\n\\n${e}\\n\\n${chalk.dim(\n 'If you think this issue is caused by the Sentry wizard, let us know here:\\nhttps://github.com/getsentry/sentry-wizard/issues',\n )}`,\n );\n Sentry.captureException('Sentry pod install failed.');\n }\n}\n"]}
1
+ {"version":3,"file":"cocoapod.js","sourceRoot":"","sources":["../../../src/apple/cocoapod.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAC7B,oDAAsC;AACtC,qDAAuC;AACvC,+EAA+E;AAC/E,sDAAwC;AACxC,kDAA0B;AAE1B,SAAgB,YAAY,CAAC,QAAgB;IAC3C,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AACvD,CAAC;AAFD,oCAEC;AAEM,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE/C,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAEpD,IACE,wDAAwD,CAAC,IAAI,CAAC,UAAU,CAAC,EACzE;QACA,0BAA0B;QAC1B,OAAO,IAAI,CAAC;KACb;IAED,IAAI,QAAQ,GAAG,+BAA+B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChE,IAAI,CAAC,QAAQ,EAAE;QACb,0EAA0E;QAC1E,MAAM,cAAc,GAAG,iCAAiC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1E,IAAI,CAAC,cAAc,EAAE;YACnB,OAAO,KAAK,CAAC;SACd;QACD,QAAQ,GAAG,cAAc,CAAC;KAC3B;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACxD,MAAM,cAAc,GAClB,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC;QAChC,IAAI;QACJ,QAAQ,CAAC,CAAC,CAAC;QACX,gBAAgB;QAChB,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAChC,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;IAElD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IAE3D,MAAM,UAAU,EAAE,CAAC;IAEnB,OAAO,IAAI,CAAC;AACd,CAAC;AApCD,oCAoCC;AAEM,KAAK,UAAU,UAAU,CAAC,GAAG,GAAG,GAAG;IACxC,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IACvC,cAAc,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAE9E,IAAI;QACF,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,qBAAqB,CAAC,CAAC;QACnD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,0BAA0B,CAAC,CAAC;QACxD,cAAc,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;KACvC;IAAC,OAAO,CAAC,EAAE;QACV,cAAc,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QACvC,KAAK,CAAC,GAAG,CAAC,KAAK,CACb,GAAG,eAAK,CAAC,GAAG,CACV,2DAA2D,CAE5D,OAAO,CAAC,OAAO,eAAK,CAAC,GAAG,CACvB,8HAA8H,CAC/H,EAAE,CACJ,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,4BAA4B,CAAC,CAAC;KACvD;AACH,CAAC;AAtBD,gCAsBC","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport * as bash from '../utils/bash';\nimport * as Sentry from '@sentry/node';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\n\nexport function usesCocoaPod(projPath: string): boolean {\n return fs.existsSync(path.join(projPath, 'Podfile'));\n}\n\nexport async function addCocoaPods(projPath: string): Promise<boolean> {\n const podfile = path.join(projPath, 'Podfile');\n\n const podContent = fs.readFileSync(podfile, 'utf8');\n\n if (\n /^\\s*pod\\s+(['\"]Sentry['\"]|['\"]SentrySwiftUI['\"])\\s*$/im.test(podContent)\n ) {\n // Already have Sentry pod\n return true;\n }\n\n let podMatch = /^( *)pod\\s+['\"](\\w+)['\"] *$/im.exec(podContent);\n if (!podMatch) {\n // No Podfile is empty, will try to add Sentry pod after \"use_frameworks!\"\n const frameworkMatch = /^( *)use_frameworks![^\\n]* *$/im.exec(podContent);\n if (!frameworkMatch) {\n return false;\n }\n podMatch = frameworkMatch;\n }\n\n const insertIndex = podMatch.index + podMatch[0].length;\n const newFileContent =\n podContent.slice(0, insertIndex) +\n '\\n' +\n podMatch[1] +\n \"pod 'Sentry'\\n\" +\n podContent.slice(insertIndex);\n fs.writeFileSync(podfile, newFileContent, 'utf8');\n\n clack.log.step('Sentry pod added to the project podFile.');\n\n await podInstall();\n\n return true;\n}\n\nexport async function podInstall(dir = '.') {\n const installSpinner = clack.spinner();\n installSpinner.start(\"Running 'pod install'. This may take a few minutes...\");\n\n try {\n await bash.execute(`cd ${dir} && pod repo update`);\n await bash.execute(`cd ${dir} && pod install --silent`);\n installSpinner.stop('Pods installed.');\n Sentry.setTag('pods-installed', true);\n } catch (e) {\n installSpinner.stop('Failed to install pods.');\n Sentry.setTag('pods-installed', false);\n clack.log.error(\n `${chalk.red(\n 'Encountered the following error during pods installation:',\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n )}\\n\\n${e}\\n\\n${chalk.dim(\n 'If you think this issue is caused by the Sentry wizard, let us know here:\\nhttps://github.com/getsentry/sentry-wizard/issues',\n )}`,\n );\n Sentry.captureException('Sentry pod install failed.');\n }\n}\n"]}
@@ -28,7 +28,7 @@ const Sentry = __importStar(require("@sentry/node"));
28
28
  const fs = __importStar(require("fs"));
29
29
  const path = __importStar(require("path"));
30
30
  const templates = __importStar(require("./templates"));
31
- // @ts-ignore - clack is ESM and TS complains about that. It works though
31
+ // @ts-expect-error - clack is ESM and TS complains about that. It works though
32
32
  const clack = __importStar(require("@clack/prompts"));
33
33
  const swiftAppLaunchRegex = /(func\s+application\s*\(\s*_\s+application:\s*[^,]+,\s*didFinishLaunchingWithOptions[^,]+:\s*[^)]+\s*\)\s+->\s+Bool\s+{)|func\s+applicationDidFinishLaunching\s*\(\s*_\s+aNotification:\s+Notification\s*\)\s*{/im;
34
34
  const objcAppLaunchRegex = /-\s*\(\s*BOOL\s*\)\s*application:\s*\(\s*UIApplication\s*\*\s*\)\s*application\s+didFinishLaunchingWithOptions:\s*\(\s*NSDictionary\s*\*\s*\)\s*launchOptions\s*{/im;
@@ -1 +1 @@
1
- {"version":3,"file":"code-tools.js","sourceRoot":"","sources":["../../../src/apple/code-tools.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Sentry from '@sentry/node';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as templates from './templates';\n// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\n\nconst swiftAppLaunchRegex =\n /(func\\s+application\\s*\\(\\s*_\\s+application:\\s*[^,]+,\\s*didFinishLaunchingWithOptions[^,]+:\\s*[^)]+\\s*\\)\\s+->\\s+Bool\\s+{)|func\\s+applicationDidFinishLaunching\\s*\\(\\s*_\\s+aNotification:\\s+Notification\\s*\\)\\s*{/im;\nconst objcAppLaunchRegex =\n /-\\s*\\(\\s*BOOL\\s*\\)\\s*application:\\s*\\(\\s*UIApplication\\s*\\*\\s*\\)\\s*application\\s+didFinishLaunchingWithOptions:\\s*\\(\\s*NSDictionary\\s*\\*\\s*\\)\\s*launchOptions\\s*{/im;\nconst swiftUIRegex = /@main\\s+struct[^:]+:\\s*(SwiftUI\\.)?App\\s*{/im;\n\nfunction isAppDelegateFile(filePath: string): boolean {\n const appLaunchRegex = filePath.toLowerCase().endsWith('.swift')\n ? swiftAppLaunchRegex\n : objcAppLaunchRegex;\n\n const fileContent = fs.readFileSync(filePath, 'utf8');\n return appLaunchRegex.test(fileContent) || swiftUIRegex.test(fileContent);\n}\n\nfunction findAppDidFinishLaunchingWithOptions(\n dir: string,\n files: string[] | undefined = undefined,\n): string | null {\n if (!files) {\n files = fs.readdirSync(dir);\n files = files.map((f) => path.join(dir, f));\n }\n\n //iterate over subdirectories later,\n //the appdelegate usually is in the top level\n const dirs: string[] = [];\n\n for (const filePath of files) {\n if (\n filePath.endsWith('.swift') ||\n filePath.endsWith('.m') ||\n filePath.endsWith('.mm')\n ) {\n if (fs.existsSync(filePath) && isAppDelegateFile(filePath)) {\n return filePath;\n }\n } else if (\n !path.basename(filePath).startsWith('.') &&\n !filePath.endsWith('.xcodeproj') &&\n !filePath.endsWith('.xcassets') &&\n fs.existsSync(filePath) &&\n fs.lstatSync(filePath).isDirectory()\n ) {\n dirs.push(filePath);\n }\n }\n\n for (const dr of dirs) {\n const result = findAppDidFinishLaunchingWithOptions(dr);\n if (result) return result;\n }\n return null;\n}\n\nexport function addCodeSnippetToProject(\n projPath: string,\n files: string[],\n dsn: string,\n): boolean {\n const appDelegate = findAppDidFinishLaunchingWithOptions(projPath, files);\n if (!appDelegate) {\n return false;\n }\n\n const fileContent = fs.readFileSync(appDelegate, 'utf8');\n const isSwift = appDelegate.toLowerCase().endsWith('.swift');\n const appLaunchRegex = isSwift ? swiftAppLaunchRegex : objcAppLaunchRegex;\n const importStatement = isSwift ? 'import Sentry\\n' : '@import Sentry;\\n';\n const checkForSentryInit = isSwift ? 'SentrySDK.start' : '[SentrySDK start';\n let codeSnippet = isSwift\n ? templates.getSwiftSnippet(dsn)\n : templates.getObjcSnippet(dsn);\n\n Sentry.setTag('code-language', isSwift ? 'swift' : 'objc');\n Sentry.setTag(\n 'ui-engine',\n swiftUIRegex.test(fileContent) ? 'swiftui' : 'uikit',\n );\n\n if (fileContent.includes(checkForSentryInit)) {\n //already initialized\n clack.log.info(\n 'Sentry is already initialized in your AppDelegate. Skipping adding the code snippet.',\n );\n return true;\n }\n\n let match = appLaunchRegex.exec(fileContent);\n if (!match) {\n const swiftUIMatch = swiftUIRegex.exec(fileContent);\n if (!swiftUIMatch) {\n // This branch is not reached, because we already checked for SwiftUI in isAppDelegateFile\n return false;\n }\n //Is SwiftUI with no init\n match = swiftUIMatch;\n codeSnippet = ` init() {\\n${codeSnippet} }`;\n }\n\n const insertIndex = match.index + match[0].length;\n let newFileContent =\n fileContent.slice(0, insertIndex) +\n '\\n' +\n codeSnippet +\n fileContent.slice(insertIndex);\n\n if (newFileContent.indexOf(importStatement) < 0) {\n const firstImport = /^[ \\t]*import +\\w+.*$/m.exec(newFileContent);\n if (firstImport) {\n const importIndex = firstImport.index + firstImport[0].length;\n newFileContent =\n newFileContent.slice(0, importIndex) +\n '\\n' +\n importStatement +\n newFileContent.slice(importIndex);\n } else {\n newFileContent = importStatement + newFileContent;\n }\n }\n\n fs.writeFileSync(appDelegate, newFileContent, 'utf8');\n\n clack.log.step('Added Sentry initialization code snippet to ' + appDelegate);\n return true;\n}\n\n/**\n * Exported for testing purposes, but should not be used in other modules.\n */\nexport let exportForTesting: {\n isAppDelegateFile: typeof isAppDelegateFile;\n findAppDidFinishLaunchingWithOptions: typeof findAppDidFinishLaunchingWithOptions;\n};\nif (process.env.NODE_ENV === 'test') {\n exportForTesting = {\n isAppDelegateFile,\n findAppDidFinishLaunchingWithOptions,\n };\n}\n"]}
1
+ {"version":3,"file":"code-tools.js","sourceRoot":"","sources":["../../../src/apple/code-tools.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Sentry from '@sentry/node';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as templates from './templates';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\n\nconst swiftAppLaunchRegex =\n /(func\\s+application\\s*\\(\\s*_\\s+application:\\s*[^,]+,\\s*didFinishLaunchingWithOptions[^,]+:\\s*[^)]+\\s*\\)\\s+->\\s+Bool\\s+{)|func\\s+applicationDidFinishLaunching\\s*\\(\\s*_\\s+aNotification:\\s+Notification\\s*\\)\\s*{/im;\nconst objcAppLaunchRegex =\n /-\\s*\\(\\s*BOOL\\s*\\)\\s*application:\\s*\\(\\s*UIApplication\\s*\\*\\s*\\)\\s*application\\s+didFinishLaunchingWithOptions:\\s*\\(\\s*NSDictionary\\s*\\*\\s*\\)\\s*launchOptions\\s*{/im;\nconst swiftUIRegex = /@main\\s+struct[^:]+:\\s*(SwiftUI\\.)?App\\s*{/im;\n\nfunction isAppDelegateFile(filePath: string): boolean {\n const appLaunchRegex = filePath.toLowerCase().endsWith('.swift')\n ? swiftAppLaunchRegex\n : objcAppLaunchRegex;\n\n const fileContent = fs.readFileSync(filePath, 'utf8');\n return appLaunchRegex.test(fileContent) || swiftUIRegex.test(fileContent);\n}\n\nfunction findAppDidFinishLaunchingWithOptions(\n dir: string,\n files: string[] | undefined = undefined,\n): string | null {\n if (!files) {\n files = fs.readdirSync(dir);\n files = files.map((f) => path.join(dir, f));\n }\n\n //iterate over subdirectories later,\n //the appdelegate usually is in the top level\n const dirs: string[] = [];\n\n for (const filePath of files) {\n if (\n filePath.endsWith('.swift') ||\n filePath.endsWith('.m') ||\n filePath.endsWith('.mm')\n ) {\n if (fs.existsSync(filePath) && isAppDelegateFile(filePath)) {\n return filePath;\n }\n } else if (\n !path.basename(filePath).startsWith('.') &&\n !filePath.endsWith('.xcodeproj') &&\n !filePath.endsWith('.xcassets') &&\n fs.existsSync(filePath) &&\n fs.lstatSync(filePath).isDirectory()\n ) {\n dirs.push(filePath);\n }\n }\n\n for (const dr of dirs) {\n const result = findAppDidFinishLaunchingWithOptions(dr);\n if (result) return result;\n }\n return null;\n}\n\nexport function addCodeSnippetToProject(\n projPath: string,\n files: string[],\n dsn: string,\n): boolean {\n const appDelegate = findAppDidFinishLaunchingWithOptions(projPath, files);\n if (!appDelegate) {\n return false;\n }\n\n const fileContent = fs.readFileSync(appDelegate, 'utf8');\n const isSwift = appDelegate.toLowerCase().endsWith('.swift');\n const appLaunchRegex = isSwift ? swiftAppLaunchRegex : objcAppLaunchRegex;\n const importStatement = isSwift ? 'import Sentry\\n' : '@import Sentry;\\n';\n const checkForSentryInit = isSwift ? 'SentrySDK.start' : '[SentrySDK start';\n let codeSnippet = isSwift\n ? templates.getSwiftSnippet(dsn)\n : templates.getObjcSnippet(dsn);\n\n Sentry.setTag('code-language', isSwift ? 'swift' : 'objc');\n Sentry.setTag(\n 'ui-engine',\n swiftUIRegex.test(fileContent) ? 'swiftui' : 'uikit',\n );\n\n if (fileContent.includes(checkForSentryInit)) {\n //already initialized\n clack.log.info(\n 'Sentry is already initialized in your AppDelegate. Skipping adding the code snippet.',\n );\n return true;\n }\n\n let match = appLaunchRegex.exec(fileContent);\n if (!match) {\n const swiftUIMatch = swiftUIRegex.exec(fileContent);\n if (!swiftUIMatch) {\n // This branch is not reached, because we already checked for SwiftUI in isAppDelegateFile\n return false;\n }\n //Is SwiftUI with no init\n match = swiftUIMatch;\n codeSnippet = ` init() {\\n${codeSnippet} }`;\n }\n\n const insertIndex = match.index + match[0].length;\n let newFileContent =\n fileContent.slice(0, insertIndex) +\n '\\n' +\n codeSnippet +\n fileContent.slice(insertIndex);\n\n if (newFileContent.indexOf(importStatement) < 0) {\n const firstImport = /^[ \\t]*import +\\w+.*$/m.exec(newFileContent);\n if (firstImport) {\n const importIndex = firstImport.index + firstImport[0].length;\n newFileContent =\n newFileContent.slice(0, importIndex) +\n '\\n' +\n importStatement +\n newFileContent.slice(importIndex);\n } else {\n newFileContent = importStatement + newFileContent;\n }\n }\n\n fs.writeFileSync(appDelegate, newFileContent, 'utf8');\n\n clack.log.step('Added Sentry initialization code snippet to ' + appDelegate);\n return true;\n}\n\n/**\n * Exported for testing purposes, but should not be used in other modules.\n */\nexport let exportForTesting: {\n isAppDelegateFile: typeof isAppDelegateFile;\n findAppDidFinishLaunchingWithOptions: typeof findAppDidFinishLaunchingWithOptions;\n};\nif (process.env.NODE_ENV === 'test') {\n exportForTesting = {\n isAppDelegateFile,\n findAppDidFinishLaunchingWithOptions,\n };\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export declare function configureFastlane({ projectDir, orgSlug, projectSlug, }: {
2
+ projectDir: string;
3
+ orgSlug: string;
4
+ projectSlug: string;
5
+ }): Promise<void>;