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,
})
}
}