export async function createNewSamApplication()

in packages/core/src/lambda/commands/createNewSamApp.ts [129:355]


export async function createNewSamApplication(
    extContext: ExtContext,
    samCliContext: SamCliContext = getSamCliContext(),
    activationReloadState: ActivationReloadState = new ActivationReloadState()
): Promise<void> {
    const awsContext: AwsContext = extContext.awsContext
    const regionProvider: RegionProvider = extContext.regionProvider
    let createResult: Result = 'Succeeded'
    let reason: string | undefined
    let lambdaPackageType: 'Zip' | 'Image' | undefined
    let createRuntime: Runtime | undefined
    let samVersion: string | undefined

    let initArguments: SamCliInitArgs | undefined

    try {
        await validateSamCli(samCliContext.validator)

        const credentials = await awsContext.getCredentials()
        samVersion = await getSamCliVersion(samCliContext)
        const schemaRegions = regionProvider
            .getRegions()
            .filter((r) => regionProvider.isServiceInRegion('schemas', r.id))
        const defaultRegion = awsContext.getCredentialDefaultRegion()

        const config = await new CreateNewSamAppWizard({
            credentials,
            schemaRegions,
            defaultRegion,
            samCliVersion: samVersion,
        }).run()

        if (!config) {
            createResult = 'Cancelled'
            reason = 'userCancelled'

            return
        }

        createRuntime = config.runtimeAndPackage.runtime as Runtime

        initArguments = {
            name: config.name,
            location: config.location.fsPath,
            dependencyManager: config.dependencyManager,
            architecture: config.architecture,
        }

        let request: SchemaCodeDownloadRequestDetails
        let schemaCodeDownloader: SchemaCodeDownloader
        let schemaTemplateParameters: SchemaTemplateParameters
        let client: SchemaClient
        if (config.template === eventBridgeStarterAppTemplate) {
            client = new DefaultSchemaClient(config.region!)
            schemaTemplateParameters = await buildSchemaTemplateParameters(
                config.schemaName!,
                config.registryName!,
                client
            )

            initArguments.extraContent = schemaTemplateParameters.templateExtraContent
        }

        if (config.runtimeAndPackage.packageType === 'Image') {
            lambdaPackageType = 'Image'
            initArguments.baseImage = `amazon/${createRuntime}-base`
        } else {
            lambdaPackageType = 'Zip'
            initArguments.runtime = createRuntime
            // in theory, templates could be provided with image-based lambdas, but that is currently not supported by SAM
            initArguments.template = config.template
        }

        await runSamCliInit(initArguments, samCliContext)

        const templateUri = await getProjectUri(config, samInitTemplateFiles)
        if (!templateUri) {
            reason = 'fileNotFound'

            return
        }

        const readmeUri = vscode.Uri.file(path.join(path.dirname(templateUri.fsPath), samInitReadmeFile))

        // Needs to be done or else gopls won't start
        if (goRuntimes.includes(createRuntime)) {
            try {
                await ChildProcess.run('go', ['mod', 'tidy'], {
                    spawnOptions: { cwd: path.join(path.dirname(templateUri.fsPath), 'hello-world') },
                })
            } catch (err) {
                getLogger().warn(
                    localize(
                        'AWS.message.warning.gotidyfailed',
                        'Failed to initialize package directory with "go mod tidy". Launch config will not be automatically created.'
                    )
                )
            }
        }

        if (config.template === eventBridgeStarterAppTemplate) {
            const destinationDirectory = path.join(config.location.fsPath, config.name, 'hello_world_function')
            request = {
                registryName: config.registryName!,
                schemaName: config.schemaName!,
                language: getApiValueForSchemasDownload(createRuntime),
                schemaVersion: schemaTemplateParameters!.SchemaVersion,
                destinationDirectory: vscode.Uri.file(destinationDirectory),
            }
            schemaCodeDownloader = createSchemaCodeDownloaderObject(client!, globals.outputChannel)
            getLogger().info(
                localize(
                    'AWS.message.info.schemas.downloadCodeBindings.start',
                    'Downloading code for schema {0}...',
                    config.schemaName!
                )
            )

            await schemaCodeDownloader!.downloadCode(request!)

            void vscode.window.showInformationMessage(
                localize(
                    'AWS.message.info.schemas.downloadCodeBindings.finished',
                    'Downloaded code for schema {0}!',
                    request!.schemaName
                )
            )
        }

        // In case adding the workspace folder triggers a VS Code restart, persist relevant state to be used after reload
        activationReloadState.setSamInitState({
            template: templateUri.fsPath,
            readme: readmeUri.fsPath,
            runtime: createRuntime,
            isImage: config.runtimeAndPackage.packageType === 'Image',
            architecture: initArguments?.architecture,
        })

        await addFolderToWorkspace(
            {
                uri: config.location,
                name: path.basename(config.location.fsPath),
            },
            true
        )

        // Race condition where SAM app is created but template doesn't register in time.
        // Poll for 5 seconds, otherwise direct user to codelens.
        const isTemplateRegistered = await waitUntil(
            async () => (await globals.templateRegistry).getItem(templateUri),
            {
                timeout: 5000,
                interval: 500,
                truthy: false,
            }
        )

        let tryOpenReadme: boolean = false

        if (isTemplateRegistered) {
            const newLaunchConfigs = await addInitialLaunchConfiguration(
                extContext,
                vscode.workspace.getWorkspaceFolder(templateUri)!,
                templateUri,
                createRuntime
            )
            tryOpenReadme = await writeToolkitReadme(readmeUri.fsPath, newLaunchConfigs)
            if (newLaunchConfigs && newLaunchConfigs.length > 0) {
                void showCompletionNotification(
                    config.name,
                    `"${newLaunchConfigs.map((config) => config.name).join('", "')}"`
                )
            }
            reason = 'complete'
        } else {
            createResult = 'Failed'
            reason = 'fileNotFound'

            const helpText = localize('AWS.generic.message.getHelp', 'Get Help...')
            void vscode.window
                .showWarningMessage(
                    localize(
                        'AWS.samcli.initWizard.launchConfigFail',
                        'Created SAM application "{0}" but failed to generate launch configurations. You can generate these via {1} in the template or handler file.',
                        config.name,
                        getIdeProperties().codelens
                    ),
                    helpText
                )
                .then(async (buttonText) => {
                    if (buttonText === helpText) {
                        void openUrl(getLaunchConfigDocUrl())
                    }
                })
        }

        activationReloadState.clearSamInitState()

        if (tryOpenReadme) {
            await vscode.commands.executeCommand('markdown.showPreviewToSide', readmeUri)
        } else {
            await vscode.workspace.openTextDocument(templateUri)
        }
    } catch (err) {
        createResult = getTelemetryResult(err)
        reason = getTelemetryReason(err)

        globals.outputChannel.show(true)
        getLogger().error(
            localize('AWS.samcli.initWizard.general.error', 'Error creating new SAM Application. {0}', checklogs())
        )

        getLogger().error('Error creating new SAM Application: %O', err as Error)

        // An error occured, so do not try to continue during the next extension activation
        activationReloadState.clearSamInitState()
    } finally {
        telemetry.sam_init.emit({
            lambdaPackageType: lambdaPackageType,
            lambdaArchitecture: initArguments?.architecture,
            result: createResult,
            reason: reason,
            runtime: createRuntime,
            version: samVersion,
        })
    }
}