@sentry/wizard 6.12.0 → 6.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/bin.js +16 -1
- package/dist/bin.js.map +1 -1
- package/dist/e2e-tests/tests/angular-17.test.js +3 -4
- package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
- package/dist/e2e-tests/tests/angular-19.test.js +3 -4
- package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
- package/dist/e2e-tests/tests/flutter.test.js +60 -0
- package/dist/e2e-tests/tests/flutter.test.js.map +1 -1
- package/dist/e2e-tests/tests/help-message.test.js +8 -3
- package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-3.test.js +12 -6
- package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-4.test.js +12 -6
- package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
- package/dist/e2e-tests/tests/pnpm-workspace.test.js +6 -3
- package/dist/e2e-tests/tests/pnpm-workspace.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js +4 -4
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-router.test.js +3 -6
- package/dist/e2e-tests/tests/react-router.test.js.map +1 -1
- package/dist/e2e-tests/tests/remix.test.js +2 -4
- package/dist/e2e-tests/tests/remix.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js +24 -8
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js +6 -3
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
- package/dist/lib/Constants.d.ts +1 -0
- package/dist/lib/Constants.js +5 -0
- package/dist/lib/Constants.js.map +1 -1
- package/dist/lib/Steps/Integrations/Electron.js +2 -2
- package/dist/lib/Steps/Integrations/Electron.js.map +1 -1
- package/dist/src/android/android-wizard.js +3 -0
- package/dist/src/android/android-wizard.js.map +1 -1
- package/dist/src/angular/codemods/main.d.ts +1 -1
- package/dist/src/angular/codemods/main.js +0 -1
- package/dist/src/angular/codemods/main.js.map +1 -1
- package/dist/src/apple/apple-wizard.js +2 -3
- package/dist/src/apple/apple-wizard.js.map +1 -1
- package/dist/src/apple/check-installed-cli.d.ts +1 -1
- package/dist/src/apple/check-installed-cli.js +13 -7
- package/dist/src/apple/check-installed-cli.js.map +1 -1
- package/dist/src/apple/configure-xcode-project.js +8 -1
- package/dist/src/apple/configure-xcode-project.js.map +1 -1
- package/dist/src/apple/lookup-xcode-project.d.ts +8 -5
- package/dist/src/apple/lookup-xcode-project.js +22 -17
- package/dist/src/apple/lookup-xcode-project.js.map +1 -1
- package/dist/src/apple/options.d.ts +5 -0
- package/dist/src/apple/options.js.map +1 -1
- package/dist/src/apple/sentry-swift-package.d.ts +4 -0
- package/dist/src/apple/sentry-swift-package.js +17 -0
- package/dist/src/apple/sentry-swift-package.js.map +1 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.d.ts +2 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.js +251 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.js.map +1 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.d.ts +13 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js +48 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js.map +1 -0
- package/dist/src/apple/snapshots/snapshot-test-file.d.ts +18 -0
- package/dist/src/apple/snapshots/snapshot-test-file.js +122 -0
- package/dist/src/apple/snapshots/snapshot-test-file.js.map +1 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.d.ts +6 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.js +147 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.js.map +1 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.d.ts +4 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.js +8 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.js.map +1 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.d.ts +23 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.js +136 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.js.map +1 -0
- package/dist/src/apple/xcode-manager.d.ts +59 -1
- package/dist/src/apple/xcode-manager.js +507 -106
- package/dist/src/apple/xcode-manager.js.map +1 -1
- package/dist/src/flutter/flutter-wizard.js +3 -0
- package/dist/src/flutter/flutter-wizard.js.map +1 -1
- package/dist/src/nextjs/templates.js +12 -6
- package/dist/src/nextjs/templates.js.map +1 -1
- package/dist/src/nuxt/templates.js +12 -6
- package/dist/src/nuxt/templates.js.map +1 -1
- package/dist/src/react-router/codemods/client.entry.d.ts +1 -1
- package/dist/src/react-router/codemods/client.entry.js +93 -52
- package/dist/src/react-router/codemods/client.entry.js.map +1 -1
- package/dist/src/react-router/codemods/server-entry.js +8 -7
- package/dist/src/react-router/codemods/server-entry.js.map +1 -1
- package/dist/src/react-router/react-router-wizard.js +13 -19
- package/dist/src/react-router/react-router-wizard.js.map +1 -1
- package/dist/src/react-router/sdk-setup.d.ts +2 -2
- package/dist/src/react-router/sdk-setup.js +16 -15
- package/dist/src/react-router/sdk-setup.js.map +1 -1
- package/dist/src/react-router/templates.d.ts +1 -3
- package/dist/src/react-router/templates.js +24 -92
- package/dist/src/react-router/templates.js.map +1 -1
- package/dist/src/remix/sdk-setup.js +1 -2
- package/dist/src/remix/sdk-setup.js.map +1 -1
- package/dist/src/run.d.ts +4 -1
- package/dist/src/run.js +13 -0
- package/dist/src/run.js.map +1 -1
- package/dist/src/sourcemaps/tools/remix.js +4 -4
- package/dist/src/sourcemaps/tools/remix.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup/setup.js +17 -4
- package/dist/src/sveltekit/sdk-setup/setup.js.map +1 -1
- package/dist/src/sveltekit/templates.js +12 -6
- package/dist/src/sveltekit/templates.js.map +1 -1
- package/dist/src/utils/clack/index.d.ts +2 -1
- package/dist/src/utils/clack/index.js +17 -6
- package/dist/src/utils/clack/index.js.map +1 -1
- package/dist/src/utils/files.d.ts +2 -0
- package/dist/src/utils/files.js +58 -0
- package/dist/src/utils/files.js.map +1 -0
- package/dist/src/utils/git.d.ts +3 -1
- package/dist/src/utils/git.js +2 -1
- package/dist/src/utils/git.js.map +1 -1
- package/dist/src/utils/line-endings.d.ts +1 -0
- package/dist/src/utils/line-endings.js +76 -0
- package/dist/src/utils/line-endings.js.map +1 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/test/angular/angular-wizard.test.js +0 -5
- package/dist/test/angular/angular-wizard.test.js.map +1 -1
- package/dist/test/apple/lookup-xcode-project.test.js +167 -0
- package/dist/test/apple/lookup-xcode-project.test.js.map +1 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.d.ts +1 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js +487 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js.map +1 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.d.ts +24 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.js +191 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.js.map +1 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.js +110 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js +146 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js +186 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js +192 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js.map +1 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.d.ts +1 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.js +77 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.js.map +1 -0
- package/dist/test/apple/xcode-manager.test.js +452 -43
- package/dist/test/apple/xcode-manager.test.js.map +1 -1
- package/dist/test/constants.test.d.ts +1 -0
- package/dist/test/constants.test.js +12 -0
- package/dist/test/constants.test.js.map +1 -0
- package/dist/test/nextjs/templates.test.js +66 -33
- package/dist/test/nextjs/templates.test.js.map +1 -1
- package/dist/test/nuxt/templates.test.js +66 -36
- package/dist/test/nuxt/templates.test.js.map +1 -1
- package/dist/test/react-router/codemods/client-entry.test.js +15 -11
- package/dist/test/react-router/codemods/client-entry.test.js.map +1 -1
- package/dist/test/react-router/codemods/server-entry.test.js +21 -8
- package/dist/test/react-router/codemods/server-entry.test.js.map +1 -1
- package/dist/test/react-router/sdk-setup.test.js +46 -10
- package/dist/test/react-router/sdk-setup.test.js.map +1 -1
- package/dist/test/react-router/templates.test.js +26 -64
- package/dist/test/react-router/templates.test.js.map +1 -1
- package/dist/test/remix/build-script.test.d.ts +1 -0
- package/dist/test/remix/build-script.test.js +124 -0
- package/dist/test/remix/build-script.test.js.map +1 -0
- package/dist/test/remix/client-entry.test.js +4 -10
- package/dist/test/remix/client-entry.test.js.map +1 -1
- package/dist/test/run.test.d.ts +1 -0
- package/dist/test/run.test.js +137 -0
- package/dist/test/run.test.js.map +1 -0
- package/dist/test/sveltekit/templates.test.js +78 -27
- package/dist/test/sveltekit/templates.test.js.map +1 -1
- package/dist/test/utils/clack/index.test.js +101 -0
- package/dist/test/utils/clack/index.test.js.map +1 -1
- package/dist/test/utils/git.test.js +10 -0
- package/dist/test/utils/git.test.js.map +1 -1
- package/dist/test/utils/line-endings.test.d.ts +1 -0
- package/dist/test/utils/line-endings.test.js +103 -0
- package/dist/test/utils/line-endings.test.js.map +1 -0
- package/package.json +2 -2
- package/dist/src/react-router/codemods/root.d.ts +0 -1
- package/dist/src/react-router/codemods/root.js +0 -170
- package/dist/src/react-router/codemods/root.js.map +0 -1
- package/dist/test/react-router/codemods/root.test.js +0 -182
- package/dist/test/react-router/codemods/root.test.js.map +0 -1
- /package/dist/test/{react-router/codemods/root.test.d.ts → apple/lookup-xcode-project.test.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup-xcode-project.js","sourceRoot":"","sources":["../../../src/apple/lookup-xcode-project.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+EAA+E;AAC/E,6DAAmC;AACnC,qDAAuC;AACvC,kDAA0B;AAC1B,uCAAyB;AACzB,2CAA6B;AAE7B,4CAAyC;AACzC,0CAA4D;AAC5D,0CAAuC;AACvC,iFAA0E;AAC1E,mDAA+C;AAExC,KAAK,UAAU,kBAAkB,CAAC,EACvC,UAAU,
|
|
1
|
+
{"version":3,"file":"lookup-xcode-project.js","sourceRoot":"","sources":["../../../src/apple/lookup-xcode-project.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+EAA+E;AAC/E,6DAAmC;AACnC,qDAAuC;AACvC,kDAA0B;AAC1B,uCAAyB;AACzB,2CAA6B;AAE7B,4CAAyC;AACzC,0CAA4D;AAC5D,0CAAuC;AACvC,iFAA0E;AAC1E,mDAA+C;AAExC,KAAK,UAAU,kBAAkB,CAAC,EACvC,UAAU,EACV,cAAc,GAAG,KAAK,GAIvB;IACC,IAAA,aAAK,EAAC,2CAA2C,eAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC3E,MAAM,cAAc,GAAG,IAAA,uDAAwB,EAAC,UAAU,CAAC,CAAC;IAC5D,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;QAC/B,iBAAK,CAAC,GAAG,CAAC,KAAK,CACb,gFAAgF,CACjF,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACxC,OAAO,MAAM,IAAA,aAAK,GAAE,CAAC;KACtB;IACD,IAAA,aAAK,EACH,SAAS,eAAK,CAAC,IAAI,CACjB,cAAc,CAAC,MAAM,CAAC,QAAQ,EAAE,CACjC,+BAA+B,CACjC,CAAC;IAEF,gEAAgE;IAChE,iEAAiE;IACjE,IAAI,aAAqB,CAAC;IAC1B,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;QAC/B,IAAA,aAAK,EAAC,2CAA2C,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;QAC1C,aAAa,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;KACnC;SAAM;QACL,IAAA,aAAK,EAAC,0DAA0D,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;QAEzC,IAAI,cAAc,EAAE;YAClB,iBAAK,CAAC,GAAG,CAAC,KAAK,CACb;gBACE,wDAAwD;gBACxD,uBAAuB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;gBACnD,8GAA8G;aAC/G,CAAC,IAAI,CAAC,GAAG,CAAC,CACZ,CAAC;YACF,OAAO,MAAM,IAAA,aAAK,GAAE,CAAC;SACtB;QAED,aAAa,GAAG,CACd,MAAM,IAAA,qBAAS,EAAC,sBAAsB,EAAE,GAAG,EAAE,CAC3C,IAAA,2BAAmB,EACjB,cAAc,EACd,6CAA6C,CAC9C,CACF,CACF,CAAC,KAAK,CAAC;KACT;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAC;IAC9E,IAAA,aAAK,EAAC,0CAA0C,eAAK,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IAC7E,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;QACjC,iBAAK,CAAC,GAAG,CAAC,KAAK,CAAC,uBAAuB,aAAa,EAAE,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;QACzC,OAAO,MAAM,IAAA,aAAK,GAAE,CAAC;KACtB;IAED,OAAO,IAAI,4BAAY,CAAC,aAAa,CAAC,CAAC;AACzC,CAAC;AA/DD,gDA+DC;AAEM,KAAK,UAAU,iBAAiB,CACrC,SAAuB,EACvB,EACE,WAAW,GAAG,SAAS,CAAC,aAAa,EAAE,EACvC,eAAe,GAAG,qCAAqC,IAAI,CAAC,QAAQ,CAClE,SAAS,CAAC,aAAa,CACxB,EAAE,EACH,aAAa,GAAG,4CAA4C,MAK1D,EAAE;IAEN,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;QAC5B,iBAAK,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACjC,OAAO,MAAM,IAAA,aAAK,GAAE,CAAC;KACtB;IACD,IAAA,aAAK,EACH,SAAS,eAAK,CAAC,IAAI,CACjB,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,CAC9B,2BAA2B,CAC7B,CAAC;IAEF,IAAI,MAAc,CAAC;IACnB,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;QAC5B,IAAA,aAAK,EAAC,oCAAoC,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QACzC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;KACzB;SAAM;QACL,IAAA,aAAK,EAAC,mDAAmD,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACxC,MAAM,GAAG,CACP,MAAM,IAAA,qBAAS,EAAC,eAAe,EAAE,GAAG,EAAE,CACpC,IAAA,2BAAmB,EAAC,WAAW,EAAE,aAAa,CAAC,CAChD,CACF,CAAC,KAAK,CAAC;KACT;IACD,IAAA,aAAK,EAAC,oBAAoB,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAEhD,OAAO,MAAM,CAAC;AAChB,CAAC;AA1CD,8CA0CC","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 chalk from 'chalk';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nimport { traceStep } from '../telemetry';\nimport { abort, askForItemSelection } from '../utils/clack';\nimport { debug } from '../utils/debug';\nimport { searchXcodeProjectAtPath } from './search-xcode-project-at-path';\nimport { XcodeProject } from './xcode-manager';\n\nexport async function lookupXcodeProject({\n projectDir,\n nonInteractive = false,\n}: {\n projectDir: string;\n nonInteractive?: boolean;\n}): Promise<XcodeProject> {\n debug(`Looking for Xcode project in directory: ${chalk.cyan(projectDir)}`);\n const xcodeProjFiles = searchXcodeProjectAtPath(projectDir);\n if (xcodeProjFiles.length === 0) {\n clack.log.error(\n 'No Xcode project found. Please run this command from the root of your project.',\n );\n Sentry.setTag('no-xcode-project', true);\n return await abort();\n }\n debug(\n `Found ${chalk.cyan(\n xcodeProjFiles.length.toString(),\n )} candidates for Xcode project`,\n );\n\n // In case there is only one Xcode project, we can use that one.\n // Otherwise, we need to ask the user which one they want to use.\n let xcodeProjFile: string;\n if (xcodeProjFiles.length === 1) {\n debug(`Found exactly one Xcode project, using it`);\n Sentry.setTag('multiple-projects', false);\n xcodeProjFile = xcodeProjFiles[0];\n } else {\n debug(`Found multiple Xcode projects, asking user to choose one`);\n Sentry.setTag('multiple-projects', true);\n\n if (nonInteractive) {\n clack.log.error(\n [\n 'Multiple Xcode projects found in non-interactive mode.',\n `Available projects: ${xcodeProjFiles.join(', ')}.`,\n 'Run from a directory with a single .xcodeproj or pass --xcode-project-dir with a narrower project directory.',\n ].join(' '),\n );\n return await abort();\n }\n\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 pathToPbxproj = path.join(projectDir, xcodeProjFile, 'project.pbxproj');\n debug(`Loading Xcode project pbxproj at path: ${chalk.cyan(pathToPbxproj)}`);\n if (!fs.existsSync(pathToPbxproj)) {\n clack.log.error(`No pbxproj found at ${xcodeProjFile}`);\n Sentry.setTag('pbxproj-not-found', true);\n return await abort();\n }\n\n return new XcodeProject(pathToPbxproj);\n}\n\nexport async function selectXcodeTarget(\n xcProject: XcodeProject,\n {\n targetNames = xcProject.getAllTargets(),\n noTargetMessage = `No suitable Xcode target found in ${path.basename(\n xcProject.xcodeprojPath,\n )}`,\n promptMessage = 'Which target do you want to add Sentry to?',\n }: {\n targetNames?: string[];\n noTargetMessage?: string;\n promptMessage?: string;\n } = {},\n): Promise<string> {\n if (targetNames.length === 0) {\n clack.log.error(noTargetMessage);\n Sentry.setTag('No-Target', true);\n return await abort();\n }\n debug(\n `Found ${chalk.cyan(\n targetNames.length.toString(),\n )} targets in Xcode project`,\n );\n\n let target: string;\n if (targetNames.length === 1) {\n debug(`Found exactly one target, using it`);\n Sentry.setTag('multiple-targets', false);\n target = targetNames[0];\n } else {\n debug(`Found multiple targets, asking user to choose one`);\n Sentry.setTag('multiple-targets', true);\n target = (\n await traceStep('Choose target', () =>\n askForItemSelection(targetNames, promptMessage),\n )\n ).value;\n }\n debug(`Selected target: ${chalk.cyan(target)}`);\n\n return target;\n}\n"]}
|
|
@@ -2,3 +2,8 @@ import { WizardOptions } from '../utils/types';
|
|
|
2
2
|
export interface AppleWizardOptions extends WizardOptions {
|
|
3
3
|
projectDir: string | undefined;
|
|
4
4
|
}
|
|
5
|
+
export interface AppleSnapshotsWizardOptions extends AppleWizardOptions {
|
|
6
|
+
appTarget?: string;
|
|
7
|
+
hostedTestTarget?: string;
|
|
8
|
+
nonInteractive: boolean;
|
|
9
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/apple/options.ts"],"names":[],"mappings":"","sourcesContent":["import { WizardOptions } from '../utils/types';\n\nexport interface AppleWizardOptions extends WizardOptions {\n projectDir: string | undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/apple/options.ts"],"names":[],"mappings":"","sourcesContent":["import { WizardOptions } from '../utils/types';\n\nexport interface AppleWizardOptions extends WizardOptions {\n projectDir: string | undefined;\n}\n\nexport interface AppleSnapshotsWizardOptions extends AppleWizardOptions {\n appTarget?: string;\n hostedTestTarget?: string;\n nonInteractive: boolean;\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SwiftPackageProductSpec, SwiftPackageSpec } from './xcode-manager';
|
|
2
|
+
export declare const SENTRY_SPM_ALREADY_LINKED_FRAMEWORK_COMMENT = "Sentry in Frameworks";
|
|
3
|
+
export declare const sentrySwiftPackageSpec: SwiftPackageSpec;
|
|
4
|
+
export declare const sentrySwiftPackageProductSpec: SwiftPackageProductSpec;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sentrySwiftPackageProductSpec = exports.sentrySwiftPackageSpec = exports.SENTRY_SPM_ALREADY_LINKED_FRAMEWORK_COMMENT = void 0;
|
|
4
|
+
exports.SENTRY_SPM_ALREADY_LINKED_FRAMEWORK_COMMENT = 'Sentry in Frameworks';
|
|
5
|
+
exports.sentrySwiftPackageSpec = {
|
|
6
|
+
repositoryURL: 'https://github.com/getsentry/sentry-cocoa/',
|
|
7
|
+
requirement: {
|
|
8
|
+
kind: 'upToNextMajorVersion',
|
|
9
|
+
minimumVersion: '9.0.0',
|
|
10
|
+
},
|
|
11
|
+
commentName: 'sentry-cocoa',
|
|
12
|
+
};
|
|
13
|
+
exports.sentrySwiftPackageProductSpec = {
|
|
14
|
+
package: exports.sentrySwiftPackageSpec,
|
|
15
|
+
productName: 'Sentry',
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=sentry-swift-package.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentry-swift-package.js","sourceRoot":"","sources":["../../../src/apple/sentry-swift-package.ts"],"names":[],"mappings":";;;AAKa,QAAA,2CAA2C,GACtD,sBAAsB,CAAC;AAEZ,QAAA,sBAAsB,GAAqB;IACtD,aAAa,EAAE,4CAA4C;IAC3D,WAAW,EAAE;QACX,IAAI,EAAE,sBAAsB;QAC5B,cAAc,EAAE,OAAO;KACxB;IACD,WAAW,EAAE,cAAc;CAC5B,CAAC;AAEW,QAAA,6BAA6B,GAA4B;IACpE,OAAO,EAAE,8BAAsB;IAC/B,WAAW,EAAE,QAAQ;CACtB,CAAC","sourcesContent":["import type {\n SwiftPackageProductSpec,\n SwiftPackageSpec,\n} from './xcode-manager';\n\nexport const SENTRY_SPM_ALREADY_LINKED_FRAMEWORK_COMMENT =\n 'Sentry in Frameworks';\n\nexport const sentrySwiftPackageSpec: SwiftPackageSpec = {\n repositoryURL: 'https://github.com/getsentry/sentry-cocoa/',\n requirement: {\n kind: 'upToNextMajorVersion',\n minimumVersion: '9.0.0',\n },\n commentName: 'sentry-cocoa',\n};\n\nexport const sentrySwiftPackageProductSpec: SwiftPackageProductSpec = {\n package: sentrySwiftPackageSpec,\n productName: 'Sentry',\n};\n"]}
|
|
@@ -0,0 +1,251 @@
|
|
|
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.runAppleSnapshotsWizard = void 0;
|
|
30
|
+
const fs = __importStar(require("node:fs"));
|
|
31
|
+
const path = __importStar(require("node:path"));
|
|
32
|
+
// @ts-expect-error - clack is ESM and TS complains about that. It works though
|
|
33
|
+
const prompts_1 = __importDefault(require("@clack/prompts"));
|
|
34
|
+
const telemetry_1 = require("../../telemetry");
|
|
35
|
+
const clack_1 = require("../../utils/clack");
|
|
36
|
+
const lookup_xcode_project_1 = require("../lookup-xcode-project");
|
|
37
|
+
const snapshots_cli_preflight_1 = require("./snapshots-cli-preflight");
|
|
38
|
+
const configure_snapshotpreviews_xcode_project_1 = require("./configure-snapshotpreviews-xcode-project");
|
|
39
|
+
const snapshot_test_file_1 = require("./snapshot-test-file");
|
|
40
|
+
const snapshot_verification_scheme_1 = require("./snapshot-verification-scheme");
|
|
41
|
+
const snapshotpreviews_package_1 = require("./snapshotpreviews-package");
|
|
42
|
+
const APPLE_SNAPSHOTS_SETUP_DID_NOT_COMPLETE = 'Apple Snapshots setup did not complete.';
|
|
43
|
+
async function runAppleSnapshotsWizard(options) {
|
|
44
|
+
return (0, telemetry_1.withTelemetry)({
|
|
45
|
+
enabled: options.telemetryEnabled,
|
|
46
|
+
integration: 'appleSnapshots',
|
|
47
|
+
wizardOptions: options,
|
|
48
|
+
}, () => runAppleSnapshotsWizardWithTelemetry(options));
|
|
49
|
+
}
|
|
50
|
+
exports.runAppleSnapshotsWizard = runAppleSnapshotsWizard;
|
|
51
|
+
async function runAppleSnapshotsWizardWithTelemetry(options) {
|
|
52
|
+
const projectDir = options.projectDir ?? process.cwd();
|
|
53
|
+
(0, clack_1.printWelcome)({
|
|
54
|
+
wizardName: 'Sentry Apple Snapshots Wizard',
|
|
55
|
+
promoCode: options.promoCode,
|
|
56
|
+
});
|
|
57
|
+
await (0, clack_1.confirmContinueIfNoOrDirtyGitRepo)({
|
|
58
|
+
ignoreGitChanges: options.ignoreGitChanges,
|
|
59
|
+
cwd: projectDir,
|
|
60
|
+
nonInteractive: options.nonInteractive,
|
|
61
|
+
});
|
|
62
|
+
prompts_1.default.log.info([
|
|
63
|
+
`Apple Snapshots setup will use ${snapshotpreviews_package_1.SNAPSHOTPREVIEWS_PACKAGE_URL}`,
|
|
64
|
+
`${snapshotpreviews_package_1.SNAPSHOTPREVIEWS_MINIMUM_VERSION}+ and link`,
|
|
65
|
+
`${snapshotpreviews_package_1.SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT} to the hosted XCTest`,
|
|
66
|
+
`target and ${snapshotpreviews_package_1.SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT} to the selected`,
|
|
67
|
+
'app target.',
|
|
68
|
+
].join(' '));
|
|
69
|
+
const xcProject = await (0, lookup_xcode_project_1.lookupXcodeProject)({
|
|
70
|
+
projectDir,
|
|
71
|
+
nonInteractive: options.nonInteractive,
|
|
72
|
+
});
|
|
73
|
+
const appTargetName = await resolveAppTargetName(xcProject, options);
|
|
74
|
+
if (!appTargetName) {
|
|
75
|
+
return await (0, clack_1.abort)(APPLE_SNAPSHOTS_SETUP_DID_NOT_COMPLETE);
|
|
76
|
+
}
|
|
77
|
+
const hostedTestTargetName = await resolveHostedTestTargetName(xcProject, appTargetName, options);
|
|
78
|
+
if (!hostedTestTargetName) {
|
|
79
|
+
return await (0, clack_1.abort)(APPLE_SNAPSHOTS_SETUP_DID_NOT_COMPLETE);
|
|
80
|
+
}
|
|
81
|
+
const previewTargetNames = [appTargetName];
|
|
82
|
+
prompts_1.default.log.info([
|
|
83
|
+
`${snapshotpreviews_package_1.SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT} will be linked to the selected`,
|
|
84
|
+
'app target when possible. Import SnapshotPreferences in Swift',
|
|
85
|
+
'preview files only if you want to use SnapshotPreviews modifiers.',
|
|
86
|
+
].join(' '));
|
|
87
|
+
if (fs.existsSync(path.join(projectDir, 'Package.swift'))) {
|
|
88
|
+
prompts_1.default.log.info([
|
|
89
|
+
'Detected Package.swift. This wizard does not edit SwiftPM manifests.',
|
|
90
|
+
`If SwiftPM preview targets use SnapshotPreferences modifiers, add`,
|
|
91
|
+
`the ${snapshotpreviews_package_1.SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT} product dependency to those`,
|
|
92
|
+
'targets in Package.swift.',
|
|
93
|
+
].join(' '));
|
|
94
|
+
}
|
|
95
|
+
const packageResult = (0, configure_snapshotpreviews_xcode_project_1.configureSnapshotPreviewsXcodeProject)({
|
|
96
|
+
xcodeProject: xcProject,
|
|
97
|
+
hostedTestTargetName,
|
|
98
|
+
previewTargetNames,
|
|
99
|
+
});
|
|
100
|
+
if (!packageResult.linked) {
|
|
101
|
+
prompts_1.default.log.error('SnapshotPreviews package products could not be linked to the selected targets. Please check the Xcode project target build phases and try again.');
|
|
102
|
+
await (0, clack_1.abort)(APPLE_SNAPSHOTS_SETUP_DID_NOT_COMPLETE);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (packageResult.failedSnapshotPreferencesTargetNames.length) {
|
|
106
|
+
prompts_1.default.log.warn([
|
|
107
|
+
`${snapshotpreviews_package_1.SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT} could not be linked to`,
|
|
108
|
+
packageResult.failedSnapshotPreferencesTargetNames.join(', '),
|
|
109
|
+
'because the target Frameworks build phase could not be updated.',
|
|
110
|
+
'Apple Snapshots setup will continue; link the product manually if',
|
|
111
|
+
'you want to use SnapshotPreviews modifiers in Swift previews.',
|
|
112
|
+
].join(' '));
|
|
113
|
+
}
|
|
114
|
+
const snapshotTestResult = (0, snapshot_test_file_1.ensureSnapshotTestFile)({
|
|
115
|
+
xcodeProject: xcProject,
|
|
116
|
+
hostedTestTargetName,
|
|
117
|
+
});
|
|
118
|
+
if (!snapshotTestResult.included) {
|
|
119
|
+
prompts_1.default.log.error('SnapshotPreviews test file could not be added to the selected XCTest target. Please check the target Sources build phase and try again.');
|
|
120
|
+
await (0, clack_1.abort)(APPLE_SNAPSHOTS_SETUP_DID_NOT_COMPLETE);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (snapshotTestResult.changed || packageResult.changed) {
|
|
124
|
+
xcProject.write();
|
|
125
|
+
prompts_1.default.log.success('Updated the Xcode project for SnapshotPreviews.');
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
prompts_1.default.log.info('SnapshotPreviews Xcode project setup is already present.');
|
|
129
|
+
}
|
|
130
|
+
await (0, snapshots_cli_preflight_1.checkInstalledCLISnapshots)({
|
|
131
|
+
projectDir,
|
|
132
|
+
nonInteractive: options.nonInteractive,
|
|
133
|
+
verificationGuidance: {
|
|
134
|
+
appId: xcProject.getBundleIdentifierForTarget(appTargetName),
|
|
135
|
+
hostedTestTargetName,
|
|
136
|
+
projectDir,
|
|
137
|
+
projectPath: xcProject.xcodeprojPath,
|
|
138
|
+
schemeName: (0, snapshot_verification_scheme_1.resolveSnapshotVerificationSchemeName)({
|
|
139
|
+
hostedTestTargetName,
|
|
140
|
+
xcodeprojPath: xcProject.xcodeprojPath,
|
|
141
|
+
}),
|
|
142
|
+
snapshotTestClassName: snapshotTestResult.className,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
prompts_1.default.outro('Apple Snapshots setup complete.');
|
|
146
|
+
}
|
|
147
|
+
async function resolveAppTargetName(xcodeProject, options) {
|
|
148
|
+
const appTargetNames = xcodeProject.getAllTargets();
|
|
149
|
+
if (options.appTarget) {
|
|
150
|
+
if (appTargetNames.includes(options.appTarget)) {
|
|
151
|
+
return options.appTarget;
|
|
152
|
+
}
|
|
153
|
+
prompts_1.default.log.error(`Xcode app target ${options.appTarget} was not found. Available app targets: ${formatList(appTargetNames)}.`);
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
if (appTargetNames.length === 0) {
|
|
157
|
+
prompts_1.default.log.error('No application target found.');
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
if (options.nonInteractive && appTargetNames.length !== 1) {
|
|
161
|
+
prompts_1.default.log.error([
|
|
162
|
+
'Could not automatically select an Xcode app target in non-interactive mode.',
|
|
163
|
+
`Available app targets: ${formatList(appTargetNames)}.`,
|
|
164
|
+
'Pass --app-target <target-name> to select the app target that SnapshotPreviews should use.',
|
|
165
|
+
].join(' '));
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
return await (0, lookup_xcode_project_1.selectXcodeTarget)(xcodeProject, {
|
|
169
|
+
targetNames: appTargetNames,
|
|
170
|
+
noTargetMessage: 'No application target found.',
|
|
171
|
+
promptMessage: 'Which app target should SnapshotPreviews use?',
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
async function resolveHostedTestTargetName(xcodeProject, appTargetName, options) {
|
|
175
|
+
const hostedTestTargetNames = xcodeProject.getHostedUnitTestTargetNames();
|
|
176
|
+
if (options.hostedTestTarget) {
|
|
177
|
+
if (hostedTestTargetNames.includes(options.hostedTestTarget)) {
|
|
178
|
+
return options.hostedTestTarget;
|
|
179
|
+
}
|
|
180
|
+
prompts_1.default.log.error([
|
|
181
|
+
`Hosted XCTest target ${options.hostedTestTarget} was not found or does not define TEST_HOST.`,
|
|
182
|
+
`Available hosted XCTest targets: ${formatList(hostedTestTargetNames)}.`,
|
|
183
|
+
].join(' '));
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
const inferredHostedTestTargetNames = xcodeProject.getHostedUnitTestTargetNamesForApplicationTarget(appTargetName);
|
|
187
|
+
if (inferredHostedTestTargetNames.length > 0) {
|
|
188
|
+
return await selectHostedTestTargetName({
|
|
189
|
+
appTargetName,
|
|
190
|
+
hostedTestTargetNames: inferredHostedTestTargetNames,
|
|
191
|
+
nonInteractive: options.nonInteractive,
|
|
192
|
+
promptMessage: 'Which test target should render SnapshotPreviews?',
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
if (hostedTestTargetNames.length === 0) {
|
|
196
|
+
prompts_1.default.log.error([
|
|
197
|
+
`No hosted XCTest target was found for ${appTargetName}.`,
|
|
198
|
+
manualAppleSnapshotsSetupInstructions({ appTargetName }),
|
|
199
|
+
].join('\n'));
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
prompts_1.default.log.warn([
|
|
203
|
+
`Could not automatically match a hosted XCTest target to ${appTargetName}.`,
|
|
204
|
+
'This can happen when TEST_HOST uses Xcode build-setting macros for the app bundle or executable name.',
|
|
205
|
+
].join(' '));
|
|
206
|
+
return await selectHostedTestTargetName({
|
|
207
|
+
appTargetName,
|
|
208
|
+
hostedTestTargetNames,
|
|
209
|
+
nonInteractive: options.nonInteractive,
|
|
210
|
+
promptMessage: 'Which hosted XCTest target should render SnapshotPreviews?',
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
async function selectHostedTestTargetName({ appTargetName, hostedTestTargetNames, nonInteractive, promptMessage, }) {
|
|
214
|
+
if (hostedTestTargetNames.length === 1) {
|
|
215
|
+
return hostedTestTargetNames[0];
|
|
216
|
+
}
|
|
217
|
+
if (nonInteractive) {
|
|
218
|
+
prompts_1.default.log.error([
|
|
219
|
+
`Could not automatically select the hosted XCTest target for ${appTargetName} in non-interactive mode.`,
|
|
220
|
+
`Available hosted XCTest targets: ${formatList(hostedTestTargetNames)}.`,
|
|
221
|
+
'Pass --hosted-test-target <target-name> to select the target explicitly.',
|
|
222
|
+
manualAppleSnapshotsSetupInstructions({
|
|
223
|
+
appTargetName,
|
|
224
|
+
hostedTestTargetName: hostedTestTargetNames[0],
|
|
225
|
+
}),
|
|
226
|
+
].join('\n'));
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
const selection = await (0, clack_1.abortIfCancelled)((0, clack_1.askForItemSelection)(hostedTestTargetNames, promptMessage));
|
|
230
|
+
return selection.value;
|
|
231
|
+
}
|
|
232
|
+
function manualAppleSnapshotsSetupInstructions({ appTargetName, hostedTestTargetName, }) {
|
|
233
|
+
const exampleHostedTestTargetName = hostedTestTargetName ?? 'AppTests';
|
|
234
|
+
const sourceFileInstruction = hostedTestTargetName
|
|
235
|
+
? '3. Add this XCTest source file to the hosted XCTest target:'
|
|
236
|
+
: `3. Add this XCTest source file to the hosted XCTest target. This example assumes the hosted XCTest target is named ${exampleHostedTestTargetName}:`;
|
|
237
|
+
return [
|
|
238
|
+
'Manual setup:',
|
|
239
|
+
`1. Add the ${snapshotpreviews_package_1.SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT} package product to the hosted XCTest target for ${appTargetName}.`,
|
|
240
|
+
`2. Add the ${snapshotpreviews_package_1.SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT} package product to ${appTargetName} if its Swift previews use SnapshotPreviews modifiers.`,
|
|
241
|
+
sourceFileInstruction,
|
|
242
|
+
'```swift',
|
|
243
|
+
(0, snapshot_test_file_1.snapshotTestTemplate)((0, snapshot_test_file_1.snapshotTestClassName)(exampleHostedTestTargetName)).trimEnd(),
|
|
244
|
+
'```',
|
|
245
|
+
'4. Run the hosted XCTest target with xcodebuild.',
|
|
246
|
+
].join('\n');
|
|
247
|
+
}
|
|
248
|
+
function formatList(values) {
|
|
249
|
+
return values.length > 0 ? values.join(', ') : 'none';
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=apple-snapshots-wizard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apple-snapshots-wizard.js","sourceRoot":"","sources":["../../../../src/apple/snapshots/apple-snapshots-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\n\nimport { withTelemetry } from '../../telemetry';\nimport {\n abort,\n abortIfCancelled,\n askForItemSelection,\n confirmContinueIfNoOrDirtyGitRepo,\n printWelcome,\n} from '../../utils/clack';\nimport { lookupXcodeProject, selectXcodeTarget } from '../lookup-xcode-project';\nimport type { AppleSnapshotsWizardOptions } from '../options';\nimport type { XcodeProject } from '../xcode-manager';\nimport { checkInstalledCLISnapshots } from './snapshots-cli-preflight';\nimport { configureSnapshotPreviewsXcodeProject } from './configure-snapshotpreviews-xcode-project';\nimport {\n ensureSnapshotTestFile,\n snapshotTestClassName,\n snapshotTestTemplate,\n} from './snapshot-test-file';\nimport { resolveSnapshotVerificationSchemeName } from './snapshot-verification-scheme';\nimport {\n SNAPSHOTPREVIEWS_MINIMUM_VERSION,\n SNAPSHOTPREVIEWS_PACKAGE_URL,\n SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT,\n SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT,\n} from './snapshotpreviews-package';\n\nconst APPLE_SNAPSHOTS_SETUP_DID_NOT_COMPLETE =\n 'Apple Snapshots setup did not complete.';\n\nexport async function runAppleSnapshotsWizard(\n options: AppleSnapshotsWizardOptions,\n): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'appleSnapshots',\n wizardOptions: options,\n },\n () => runAppleSnapshotsWizardWithTelemetry(options),\n );\n}\n\nasync function runAppleSnapshotsWizardWithTelemetry(\n options: AppleSnapshotsWizardOptions,\n): Promise<void> {\n const projectDir = options.projectDir ?? process.cwd();\n\n printWelcome({\n wizardName: 'Sentry Apple Snapshots Wizard',\n promoCode: options.promoCode,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo({\n ignoreGitChanges: options.ignoreGitChanges,\n cwd: projectDir,\n nonInteractive: options.nonInteractive,\n });\n\n clack.log.info(\n [\n `Apple Snapshots setup will use ${SNAPSHOTPREVIEWS_PACKAGE_URL}`,\n `${SNAPSHOTPREVIEWS_MINIMUM_VERSION}+ and link`,\n `${SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT} to the hosted XCTest`,\n `target and ${SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT} to the selected`,\n 'app target.',\n ].join(' '),\n );\n\n const xcProject = await lookupXcodeProject({\n projectDir,\n nonInteractive: options.nonInteractive,\n });\n\n const appTargetName = await resolveAppTargetName(xcProject, options);\n if (!appTargetName) {\n return await abort(APPLE_SNAPSHOTS_SETUP_DID_NOT_COMPLETE);\n }\n\n const hostedTestTargetName = await resolveHostedTestTargetName(\n xcProject,\n appTargetName,\n options,\n );\n if (!hostedTestTargetName) {\n return await abort(APPLE_SNAPSHOTS_SETUP_DID_NOT_COMPLETE);\n }\n\n const previewTargetNames = [appTargetName];\n\n clack.log.info(\n [\n `${SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT} will be linked to the selected`,\n 'app target when possible. Import SnapshotPreferences in Swift',\n 'preview files only if you want to use SnapshotPreviews modifiers.',\n ].join(' '),\n );\n\n if (fs.existsSync(path.join(projectDir, 'Package.swift'))) {\n clack.log.info(\n [\n 'Detected Package.swift. This wizard does not edit SwiftPM manifests.',\n `If SwiftPM preview targets use SnapshotPreferences modifiers, add`,\n `the ${SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT} product dependency to those`,\n 'targets in Package.swift.',\n ].join(' '),\n );\n }\n\n const packageResult = configureSnapshotPreviewsXcodeProject({\n xcodeProject: xcProject,\n hostedTestTargetName,\n previewTargetNames,\n });\n\n if (!packageResult.linked) {\n clack.log.error(\n 'SnapshotPreviews package products could not be linked to the selected targets. Please check the Xcode project target build phases and try again.',\n );\n await abort(APPLE_SNAPSHOTS_SETUP_DID_NOT_COMPLETE);\n return;\n }\n\n if (packageResult.failedSnapshotPreferencesTargetNames.length) {\n clack.log.warn(\n [\n `${SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT} could not be linked to`,\n packageResult.failedSnapshotPreferencesTargetNames.join(', '),\n 'because the target Frameworks build phase could not be updated.',\n 'Apple Snapshots setup will continue; link the product manually if',\n 'you want to use SnapshotPreviews modifiers in Swift previews.',\n ].join(' '),\n );\n }\n\n const snapshotTestResult = ensureSnapshotTestFile({\n xcodeProject: xcProject,\n hostedTestTargetName,\n });\n if (!snapshotTestResult.included) {\n clack.log.error(\n 'SnapshotPreviews test file could not be added to the selected XCTest target. Please check the target Sources build phase and try again.',\n );\n await abort(APPLE_SNAPSHOTS_SETUP_DID_NOT_COMPLETE);\n return;\n }\n\n if (snapshotTestResult.changed || packageResult.changed) {\n xcProject.write();\n clack.log.success('Updated the Xcode project for SnapshotPreviews.');\n } else {\n clack.log.info('SnapshotPreviews Xcode project setup is already present.');\n }\n\n await checkInstalledCLISnapshots({\n projectDir,\n nonInteractive: options.nonInteractive,\n verificationGuidance: {\n appId: xcProject.getBundleIdentifierForTarget(appTargetName),\n hostedTestTargetName,\n projectDir,\n projectPath: xcProject.xcodeprojPath,\n schemeName: resolveSnapshotVerificationSchemeName({\n hostedTestTargetName,\n xcodeprojPath: xcProject.xcodeprojPath,\n }),\n snapshotTestClassName: snapshotTestResult.className,\n },\n });\n\n clack.outro('Apple Snapshots setup complete.');\n}\n\nasync function resolveAppTargetName(\n xcodeProject: XcodeProject,\n options: AppleSnapshotsWizardOptions,\n): Promise<string | undefined> {\n const appTargetNames = xcodeProject.getAllTargets();\n if (options.appTarget) {\n if (appTargetNames.includes(options.appTarget)) {\n return options.appTarget;\n }\n\n clack.log.error(\n `Xcode app target ${\n options.appTarget\n } was not found. Available app targets: ${formatList(appTargetNames)}.`,\n );\n return undefined;\n }\n\n if (appTargetNames.length === 0) {\n clack.log.error('No application target found.');\n return undefined;\n }\n\n if (options.nonInteractive && appTargetNames.length !== 1) {\n clack.log.error(\n [\n 'Could not automatically select an Xcode app target in non-interactive mode.',\n `Available app targets: ${formatList(appTargetNames)}.`,\n 'Pass --app-target <target-name> to select the app target that SnapshotPreviews should use.',\n ].join(' '),\n );\n return undefined;\n }\n\n return await selectXcodeTarget(xcodeProject, {\n targetNames: appTargetNames,\n noTargetMessage: 'No application target found.',\n promptMessage: 'Which app target should SnapshotPreviews use?',\n });\n}\n\nasync function resolveHostedTestTargetName(\n xcodeProject: XcodeProject,\n appTargetName: string,\n options: AppleSnapshotsWizardOptions,\n): Promise<string | undefined> {\n const hostedTestTargetNames = xcodeProject.getHostedUnitTestTargetNames();\n if (options.hostedTestTarget) {\n if (hostedTestTargetNames.includes(options.hostedTestTarget)) {\n return options.hostedTestTarget;\n }\n\n clack.log.error(\n [\n `Hosted XCTest target ${options.hostedTestTarget} was not found or does not define TEST_HOST.`,\n `Available hosted XCTest targets: ${formatList(\n hostedTestTargetNames,\n )}.`,\n ].join(' '),\n );\n return undefined;\n }\n\n const inferredHostedTestTargetNames =\n xcodeProject.getHostedUnitTestTargetNamesForApplicationTarget(\n appTargetName,\n );\n if (inferredHostedTestTargetNames.length > 0) {\n return await selectHostedTestTargetName({\n appTargetName,\n hostedTestTargetNames: inferredHostedTestTargetNames,\n nonInteractive: options.nonInteractive,\n promptMessage: 'Which test target should render SnapshotPreviews?',\n });\n }\n\n if (hostedTestTargetNames.length === 0) {\n clack.log.error(\n [\n `No hosted XCTest target was found for ${appTargetName}.`,\n manualAppleSnapshotsSetupInstructions({ appTargetName }),\n ].join('\\n'),\n );\n return undefined;\n }\n\n clack.log.warn(\n [\n `Could not automatically match a hosted XCTest target to ${appTargetName}.`,\n 'This can happen when TEST_HOST uses Xcode build-setting macros for the app bundle or executable name.',\n ].join(' '),\n );\n\n return await selectHostedTestTargetName({\n appTargetName,\n hostedTestTargetNames,\n nonInteractive: options.nonInteractive,\n promptMessage: 'Which hosted XCTest target should render SnapshotPreviews?',\n });\n}\n\nasync function selectHostedTestTargetName({\n appTargetName,\n hostedTestTargetNames,\n nonInteractive,\n promptMessage,\n}: {\n appTargetName: string;\n hostedTestTargetNames: string[];\n nonInteractive: boolean;\n promptMessage: string;\n}): Promise<string | undefined> {\n if (hostedTestTargetNames.length === 1) {\n return hostedTestTargetNames[0];\n }\n\n if (nonInteractive) {\n clack.log.error(\n [\n `Could not automatically select the hosted XCTest target for ${appTargetName} in non-interactive mode.`,\n `Available hosted XCTest targets: ${formatList(\n hostedTestTargetNames,\n )}.`,\n 'Pass --hosted-test-target <target-name> to select the target explicitly.',\n manualAppleSnapshotsSetupInstructions({\n appTargetName,\n hostedTestTargetName: hostedTestTargetNames[0],\n }),\n ].join('\\n'),\n );\n return undefined;\n }\n\n const selection = await abortIfCancelled(\n askForItemSelection(hostedTestTargetNames, promptMessage),\n );\n return selection.value;\n}\n\nfunction manualAppleSnapshotsSetupInstructions({\n appTargetName,\n hostedTestTargetName,\n}: {\n appTargetName: string;\n hostedTestTargetName?: string;\n}): string {\n const exampleHostedTestTargetName = hostedTestTargetName ?? 'AppTests';\n const sourceFileInstruction = hostedTestTargetName\n ? '3. Add this XCTest source file to the hosted XCTest target:'\n : `3. Add this XCTest source file to the hosted XCTest target. This example assumes the hosted XCTest target is named ${exampleHostedTestTargetName}:`;\n\n return [\n 'Manual setup:',\n `1. Add the ${SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT} package product to the hosted XCTest target for ${appTargetName}.`,\n `2. Add the ${SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT} package product to ${appTargetName} if its Swift previews use SnapshotPreviews modifiers.`,\n sourceFileInstruction,\n '```swift',\n snapshotTestTemplate(\n snapshotTestClassName(exampleHostedTestTargetName),\n ).trimEnd(),\n '```',\n '4. Run the hosted XCTest target with xcodebuild.',\n ].join('\\n');\n}\n\nfunction formatList(values: string[]): string {\n return values.length > 0 ? values.join(', ') : 'none';\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SwiftPackageProductSpec, SwiftPackageSpec, XcodeProject } from '../xcode-manager';
|
|
2
|
+
export declare const snapshotPreviewsPackageSpec: SwiftPackageSpec;
|
|
3
|
+
export declare const snapshottingTestsProductSpec: SwiftPackageProductSpec;
|
|
4
|
+
export declare const snapshotPreferencesProductSpec: SwiftPackageProductSpec;
|
|
5
|
+
export declare function configureSnapshotPreviewsXcodeProject({ xcodeProject, hostedTestTargetName, previewTargetNames, }: {
|
|
6
|
+
xcodeProject: XcodeProject;
|
|
7
|
+
hostedTestTargetName: string;
|
|
8
|
+
previewTargetNames?: string[];
|
|
9
|
+
}): {
|
|
10
|
+
changed: boolean;
|
|
11
|
+
failedSnapshotPreferencesTargetNames: string[];
|
|
12
|
+
linked: boolean;
|
|
13
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureSnapshotPreviewsXcodeProject = exports.snapshotPreferencesProductSpec = exports.snapshottingTestsProductSpec = exports.snapshotPreviewsPackageSpec = void 0;
|
|
4
|
+
const snapshotpreviews_package_1 = require("./snapshotpreviews-package");
|
|
5
|
+
exports.snapshotPreviewsPackageSpec = {
|
|
6
|
+
repositoryURL: snapshotpreviews_package_1.SNAPSHOTPREVIEWS_PACKAGE_URL,
|
|
7
|
+
requirement: {
|
|
8
|
+
kind: 'upToNextMajorVersion',
|
|
9
|
+
minimumVersion: snapshotpreviews_package_1.SNAPSHOTPREVIEWS_MINIMUM_VERSION,
|
|
10
|
+
},
|
|
11
|
+
commentName: 'SnapshotPreviews',
|
|
12
|
+
};
|
|
13
|
+
exports.snapshottingTestsProductSpec = {
|
|
14
|
+
package: exports.snapshotPreviewsPackageSpec,
|
|
15
|
+
productName: snapshotpreviews_package_1.SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT,
|
|
16
|
+
};
|
|
17
|
+
exports.snapshotPreferencesProductSpec = {
|
|
18
|
+
package: exports.snapshotPreviewsPackageSpec,
|
|
19
|
+
productName: snapshotpreviews_package_1.SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT,
|
|
20
|
+
};
|
|
21
|
+
function configureSnapshotPreviewsXcodeProject({ xcodeProject, hostedTestTargetName, previewTargetNames = [], }) {
|
|
22
|
+
if (!xcodeProject.getUnitTestTargetNames().includes(hostedTestTargetName)) {
|
|
23
|
+
return {
|
|
24
|
+
changed: false,
|
|
25
|
+
failedSnapshotPreferencesTargetNames: [],
|
|
26
|
+
linked: false,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const snapshottingTestsResult = xcodeProject.ensureSwiftPackageProductLinked(hostedTestTargetName, exports.snapshottingTestsProductSpec);
|
|
30
|
+
const snapshotPreferencesResults = previewTargetNames.map((targetName) => ({
|
|
31
|
+
result: xcodeProject.ensureSwiftPackageProductLinked(targetName, exports.snapshotPreferencesProductSpec),
|
|
32
|
+
targetName,
|
|
33
|
+
}));
|
|
34
|
+
const linkResults = [
|
|
35
|
+
snapshottingTestsResult,
|
|
36
|
+
...snapshotPreferencesResults.map(({ result }) => result),
|
|
37
|
+
];
|
|
38
|
+
const failedSnapshotPreferencesTargetNames = snapshotPreferencesResults
|
|
39
|
+
.filter(({ result }) => !result.linked)
|
|
40
|
+
.map(({ targetName }) => targetName);
|
|
41
|
+
return {
|
|
42
|
+
changed: linkResults.some((result) => result.changed),
|
|
43
|
+
failedSnapshotPreferencesTargetNames,
|
|
44
|
+
linked: snapshottingTestsResult.linked,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
exports.configureSnapshotPreviewsXcodeProject = configureSnapshotPreviewsXcodeProject;
|
|
48
|
+
//# sourceMappingURL=configure-snapshotpreviews-xcode-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure-snapshotpreviews-xcode-project.js","sourceRoot":"","sources":["../../../../src/apple/snapshots/configure-snapshotpreviews-xcode-project.ts"],"names":[],"mappings":";;;AAKA,yEAKoC;AAEvB,QAAA,2BAA2B,GAAqB;IAC3D,aAAa,EAAE,uDAA4B;IAC3C,WAAW,EAAE;QACX,IAAI,EAAE,sBAAsB;QAC5B,cAAc,EAAE,2DAAgC;KACjD;IACD,WAAW,EAAE,kBAAkB;CAChC,CAAC;AAEW,QAAA,4BAA4B,GAA4B;IACnE,OAAO,EAAE,mCAA2B;IACpC,WAAW,EAAE,kEAAuC;CACrD,CAAC;AAEW,QAAA,8BAA8B,GAA4B;IACrE,OAAO,EAAE,mCAA2B;IACpC,WAAW,EAAE,+DAAoC;CAClD,CAAC;AAEF,SAAgB,qCAAqC,CAAC,EACpD,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,GAAG,EAAE,GAKxB;IAKC,IAAI,CAAC,YAAY,CAAC,sBAAsB,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE;QACzE,OAAO;YACL,OAAO,EAAE,KAAK;YACd,oCAAoC,EAAE,EAAE;YACxC,MAAM,EAAE,KAAK;SACd,CAAC;KACH;IAED,MAAM,uBAAuB,GAAG,YAAY,CAAC,+BAA+B,CAC1E,oBAAoB,EACpB,oCAA4B,CAC7B,CAAC;IACF,MAAM,0BAA0B,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACzE,MAAM,EAAE,YAAY,CAAC,+BAA+B,CAClD,UAAU,EACV,sCAA8B,CAC/B;QACD,UAAU;KACX,CAAC,CAAC,CAAC;IACJ,MAAM,WAAW,GAAG;QAClB,uBAAuB;QACvB,GAAG,0BAA0B,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC;KAC1D,CAAC;IACF,MAAM,oCAAoC,GAAG,0BAA0B;SACpE,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;SACtC,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC;IAEvC,OAAO;QACL,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC;QACrD,oCAAoC;QACpC,MAAM,EAAE,uBAAuB,CAAC,MAAM;KACvC,CAAC;AACJ,CAAC;AA7CD,sFA6CC","sourcesContent":["import type {\n SwiftPackageProductSpec,\n SwiftPackageSpec,\n XcodeProject,\n} from '../xcode-manager';\nimport {\n SNAPSHOTPREVIEWS_MINIMUM_VERSION,\n SNAPSHOTPREVIEWS_PACKAGE_URL,\n SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT,\n SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT,\n} from './snapshotpreviews-package';\n\nexport const snapshotPreviewsPackageSpec: SwiftPackageSpec = {\n repositoryURL: SNAPSHOTPREVIEWS_PACKAGE_URL,\n requirement: {\n kind: 'upToNextMajorVersion',\n minimumVersion: SNAPSHOTPREVIEWS_MINIMUM_VERSION,\n },\n commentName: 'SnapshotPreviews',\n};\n\nexport const snapshottingTestsProductSpec: SwiftPackageProductSpec = {\n package: snapshotPreviewsPackageSpec,\n productName: SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT,\n};\n\nexport const snapshotPreferencesProductSpec: SwiftPackageProductSpec = {\n package: snapshotPreviewsPackageSpec,\n productName: SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT,\n};\n\nexport function configureSnapshotPreviewsXcodeProject({\n xcodeProject,\n hostedTestTargetName,\n previewTargetNames = [],\n}: {\n xcodeProject: XcodeProject;\n hostedTestTargetName: string;\n previewTargetNames?: string[];\n}): {\n changed: boolean;\n failedSnapshotPreferencesTargetNames: string[];\n linked: boolean;\n} {\n if (!xcodeProject.getUnitTestTargetNames().includes(hostedTestTargetName)) {\n return {\n changed: false,\n failedSnapshotPreferencesTargetNames: [],\n linked: false,\n };\n }\n\n const snapshottingTestsResult = xcodeProject.ensureSwiftPackageProductLinked(\n hostedTestTargetName,\n snapshottingTestsProductSpec,\n );\n const snapshotPreferencesResults = previewTargetNames.map((targetName) => ({\n result: xcodeProject.ensureSwiftPackageProductLinked(\n targetName,\n snapshotPreferencesProductSpec,\n ),\n targetName,\n }));\n const linkResults = [\n snapshottingTestsResult,\n ...snapshotPreferencesResults.map(({ result }) => result),\n ];\n const failedSnapshotPreferencesTargetNames = snapshotPreferencesResults\n .filter(({ result }) => !result.linked)\n .map(({ targetName }) => targetName);\n\n return {\n changed: linkResults.some((result) => result.changed),\n failedSnapshotPreferencesTargetNames,\n linked: snapshottingTestsResult.linked,\n };\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { XcodeProject } from '../xcode-manager';
|
|
2
|
+
type EnsureSnapshotTestFileResult = {
|
|
3
|
+
changed: false;
|
|
4
|
+
included: false;
|
|
5
|
+
} | {
|
|
6
|
+
changed: boolean;
|
|
7
|
+
className: string;
|
|
8
|
+
filePath: string;
|
|
9
|
+
included: true;
|
|
10
|
+
};
|
|
11
|
+
export declare function ensureSnapshotTestFile({ xcodeProject, hostedTestTargetName, }: {
|
|
12
|
+
xcodeProject: XcodeProject;
|
|
13
|
+
hostedTestTargetName: string;
|
|
14
|
+
}): EnsureSnapshotTestFileResult;
|
|
15
|
+
export declare function snapshotTestClassName(hostedTestTargetName: string): string;
|
|
16
|
+
export declare function snapshotTestTemplate(className: string): string;
|
|
17
|
+
export declare function swiftSafeTypeName(value: string): string;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.swiftSafeTypeName = exports.snapshotTestTemplate = exports.snapshotTestClassName = exports.ensureSnapshotTestFile = void 0;
|
|
27
|
+
const fs = __importStar(require("node:fs"));
|
|
28
|
+
const path = __importStar(require("node:path"));
|
|
29
|
+
const SNAPSHOT_TEST_IMPORT = 'import SnapshottingTests';
|
|
30
|
+
function ensureSnapshotTestFile({ xcodeProject, hostedTestTargetName, }) {
|
|
31
|
+
const existingSnapshotTestFile = findExistingSnapshotTestFile(xcodeProject, hostedTestTargetName);
|
|
32
|
+
if (existingSnapshotTestFile) {
|
|
33
|
+
return {
|
|
34
|
+
changed: false,
|
|
35
|
+
className: existingSnapshotTestFile.className,
|
|
36
|
+
filePath: existingSnapshotTestFile.filePath,
|
|
37
|
+
included: true,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const className = snapshotTestClassName(hostedTestTargetName);
|
|
41
|
+
const filePath = path.join(getSnapshotTestDirectory(xcodeProject, hostedTestTargetName), `${className}.swift`);
|
|
42
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
43
|
+
const fileCreated = !fs.existsSync(filePath);
|
|
44
|
+
if (fileCreated) {
|
|
45
|
+
fs.writeFileSync(filePath, snapshotTestTemplate(className), 'utf8');
|
|
46
|
+
}
|
|
47
|
+
const membership = xcodeProject.addSwiftSourceFileToTarget({
|
|
48
|
+
targetName: hostedTestTargetName,
|
|
49
|
+
filePath,
|
|
50
|
+
});
|
|
51
|
+
if (!membership.included) {
|
|
52
|
+
if (fileCreated) {
|
|
53
|
+
fs.unlinkSync(filePath);
|
|
54
|
+
}
|
|
55
|
+
return { changed: false, included: false };
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
changed: fileCreated || membership.changed,
|
|
59
|
+
className,
|
|
60
|
+
filePath,
|
|
61
|
+
included: true,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
exports.ensureSnapshotTestFile = ensureSnapshotTestFile;
|
|
65
|
+
function snapshotTestClassName(hostedTestTargetName) {
|
|
66
|
+
return `${swiftSafeTypeName(hostedTestTargetName)}SnapshotTest`;
|
|
67
|
+
}
|
|
68
|
+
exports.snapshotTestClassName = snapshotTestClassName;
|
|
69
|
+
function snapshotTestTemplate(className) {
|
|
70
|
+
return `${SNAPSHOT_TEST_IMPORT}
|
|
71
|
+
|
|
72
|
+
final class ${className}: SnapshotTest {
|
|
73
|
+
override class func snapshotPreviews() -> [String]? { nil }
|
|
74
|
+
override class func excludedSnapshotPreviews() -> [String]? { nil }
|
|
75
|
+
override class func snapshotPreviewModules() -> [String]? { nil }
|
|
76
|
+
override class func excludedSnapshotPreviewModules() -> [String]? { nil }
|
|
77
|
+
}
|
|
78
|
+
`;
|
|
79
|
+
}
|
|
80
|
+
exports.snapshotTestTemplate = snapshotTestTemplate;
|
|
81
|
+
function swiftSafeTypeName(value) {
|
|
82
|
+
const words = value.split(/[^A-Za-z0-9]+/).filter((word) => word.length > 0);
|
|
83
|
+
const typeName = words
|
|
84
|
+
.map((word) => `${word[0].toUpperCase()}${word.slice(1)}`)
|
|
85
|
+
.join('');
|
|
86
|
+
if (!typeName) {
|
|
87
|
+
return 'Snapshots';
|
|
88
|
+
}
|
|
89
|
+
return /^[0-9]/.test(typeName) ? `_${typeName}` : typeName;
|
|
90
|
+
}
|
|
91
|
+
exports.swiftSafeTypeName = swiftSafeTypeName;
|
|
92
|
+
function findExistingSnapshotTestFile(xcodeProject, hostedTestTargetName) {
|
|
93
|
+
const sourceFiles = xcodeProject.getSourceFilesForTarget(hostedTestTargetName) ?? [];
|
|
94
|
+
for (const filePath of sourceFiles) {
|
|
95
|
+
if (!filePath.endsWith('.swift') || !fs.existsSync(filePath)) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const contents = fs.readFileSync(filePath, 'utf8');
|
|
99
|
+
const className = getSnapshotTestClassName(contents);
|
|
100
|
+
if (contents.includes(SNAPSHOT_TEST_IMPORT) && className) {
|
|
101
|
+
return { className, filePath };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
function getSnapshotTestClassName(contents) {
|
|
107
|
+
return contents.match(/\bclass\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*SnapshotTest\b/)?.[1];
|
|
108
|
+
}
|
|
109
|
+
function getSnapshotTestDirectory(xcodeProject, hostedTestTargetName) {
|
|
110
|
+
const synchronizedRootGroupPath = xcodeProject.getSynchronizedRootGroupPathsForTarget(hostedTestTargetName)[0];
|
|
111
|
+
if (synchronizedRootGroupPath) {
|
|
112
|
+
return synchronizedRootGroupPath;
|
|
113
|
+
}
|
|
114
|
+
const existingSwiftFile = xcodeProject
|
|
115
|
+
.getSourceFilesForTarget(hostedTestTargetName)
|
|
116
|
+
?.find((filePath) => filePath.endsWith('.swift'));
|
|
117
|
+
if (existingSwiftFile) {
|
|
118
|
+
return path.dirname(existingSwiftFile);
|
|
119
|
+
}
|
|
120
|
+
return path.join(xcodeProject.baseDir, hostedTestTargetName);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=snapshot-test-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-test-file.js","sourceRoot":"","sources":["../../../../src/apple/snapshots/snapshot-test-file.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { XcodeProject } from '../xcode-manager';\n\nconst SNAPSHOT_TEST_IMPORT = 'import SnapshottingTests';\n\ntype EnsureSnapshotTestFileResult =\n | { changed: false; included: false }\n | {\n changed: boolean;\n className: string;\n filePath: string;\n included: true;\n };\n\nexport function ensureSnapshotTestFile({\n xcodeProject,\n hostedTestTargetName,\n}: {\n xcodeProject: XcodeProject;\n hostedTestTargetName: string;\n}): EnsureSnapshotTestFileResult {\n const existingSnapshotTestFile = findExistingSnapshotTestFile(\n xcodeProject,\n hostedTestTargetName,\n );\n if (existingSnapshotTestFile) {\n return {\n changed: false,\n className: existingSnapshotTestFile.className,\n filePath: existingSnapshotTestFile.filePath,\n included: true,\n };\n }\n\n const className = snapshotTestClassName(hostedTestTargetName);\n const filePath = path.join(\n getSnapshotTestDirectory(xcodeProject, hostedTestTargetName),\n `${className}.swift`,\n );\n\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n const fileCreated = !fs.existsSync(filePath);\n if (fileCreated) {\n fs.writeFileSync(filePath, snapshotTestTemplate(className), 'utf8');\n }\n\n const membership = xcodeProject.addSwiftSourceFileToTarget({\n targetName: hostedTestTargetName,\n filePath,\n });\n\n if (!membership.included) {\n if (fileCreated) {\n fs.unlinkSync(filePath);\n }\n\n return { changed: false, included: false };\n }\n\n return {\n changed: fileCreated || membership.changed,\n className,\n filePath,\n included: true,\n };\n}\n\nexport function snapshotTestClassName(hostedTestTargetName: string): string {\n return `${swiftSafeTypeName(hostedTestTargetName)}SnapshotTest`;\n}\n\nexport function snapshotTestTemplate(className: string): string {\n return `${SNAPSHOT_TEST_IMPORT}\n\nfinal class ${className}: SnapshotTest {\n override class func snapshotPreviews() -> [String]? { nil }\n override class func excludedSnapshotPreviews() -> [String]? { nil }\n override class func snapshotPreviewModules() -> [String]? { nil }\n override class func excludedSnapshotPreviewModules() -> [String]? { nil }\n}\n`;\n}\n\nexport function swiftSafeTypeName(value: string): string {\n const words = value.split(/[^A-Za-z0-9]+/).filter((word) => word.length > 0);\n const typeName = words\n .map((word) => `${word[0].toUpperCase()}${word.slice(1)}`)\n .join('');\n\n if (!typeName) {\n return 'Snapshots';\n }\n\n return /^[0-9]/.test(typeName) ? `_${typeName}` : typeName;\n}\n\nfunction findExistingSnapshotTestFile(\n xcodeProject: XcodeProject,\n hostedTestTargetName: string,\n): { className: string; filePath: string } | undefined {\n const sourceFiles =\n xcodeProject.getSourceFilesForTarget(hostedTestTargetName) ?? [];\n for (const filePath of sourceFiles) {\n if (!filePath.endsWith('.swift') || !fs.existsSync(filePath)) {\n continue;\n }\n\n const contents = fs.readFileSync(filePath, 'utf8');\n const className = getSnapshotTestClassName(contents);\n if (contents.includes(SNAPSHOT_TEST_IMPORT) && className) {\n return { className, filePath };\n }\n }\n\n return undefined;\n}\n\nfunction getSnapshotTestClassName(contents: string): string | undefined {\n return contents.match(\n /\\bclass\\s+([A-Za-z_][A-Za-z0-9_]*)\\s*:\\s*SnapshotTest\\b/,\n )?.[1];\n}\n\nfunction getSnapshotTestDirectory(\n xcodeProject: XcodeProject,\n hostedTestTargetName: string,\n): string {\n const synchronizedRootGroupPath =\n xcodeProject.getSynchronizedRootGroupPathsForTarget(\n hostedTestTargetName,\n )[0];\n if (synchronizedRootGroupPath) {\n return synchronizedRootGroupPath;\n }\n\n const existingSwiftFile = xcodeProject\n .getSourceFilesForTarget(hostedTestTargetName)\n ?.find((filePath) => filePath.endsWith('.swift'));\n if (existingSwiftFile) {\n return path.dirname(existingSwiftFile);\n }\n\n return path.join(xcodeProject.baseDir, hostedTestTargetName);\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type SnapshotVerificationSchemeOptions = {
|
|
2
|
+
hostedTestTargetName: string;
|
|
3
|
+
xcodeprojPath: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function resolveSnapshotVerificationSchemeName({ hostedTestTargetName, xcodeprojPath, }: SnapshotVerificationSchemeOptions): string | undefined;
|
|
6
|
+
export {};
|