import { WebSiteManagementModels } from '@azure/arm-appservice' ; import { RequestPrepareOptions } from '@azure/ms-rest-js' ; import * as extract from 'extract-zip' ; import * as querystring from 'querystring' ; import * as vscode from 'vscode' ; import { IActionContext , parseError } from 'vscode-azureextensionui' ; import { initProjectForVSCode } from '../commands/initProjectForVSCode/initProjectForVSCode' ; import { ProjectLanguage } from '../constants' ; import { ext } from '../extensionVariables' ; import { localize } from '../localize' ; import { SlotTreeItemBase } from "../tree/SlotTreeItemBase" ; import { getNameFromId } from '../utils/azure' ; import { requestUtils } from '../utils/requestUtils' ; import { getRequiredQueryParameter } from './handleUri' ; export async function setupProjectFolder ( uri , vsCodeFilePathUri , context ) { const parsedQuery = querystring . parse ( uri . query ) ; const resourceId = getRequiredQueryParameter ( parsedQuery , 'resourceId' ) ; const devContainerName = getRequiredQueryParameter ( parsedQuery , 'devcontainer' ) ; const language = getRequiredQueryParameter ( parsedQuery , 'language' ) ; const toBeDeletedFolderPathUri = vscode . Uri . joinPath ( vsCodeFilePathUri , 'temp' ) ; try { const functionAppName = getNameFromId ( resourceId ) ; const downloadFilePath = vscode . Uri . joinPath ( toBeDeletedFolderPathUri , `${ functionAppName }.zip` ) . fsPath ; await vscode . window . withProgress ( { location : vscode . ProgressLocation . Notification , title : localize ( 'settingUpFunctionAppLocalProjInfoMessage' , `Setting up project for function app '${ functionAppName }' with language '${ language }'.` ) } , async ( ) => { const slotTreeItem = await ext . tree . findTreeItem ( resourceId , { ... context , loadAll : true } ) ; if ( ! slotTreeItem ) { throw new Error ( localize ( 'failedToFindApp' , 'Failed to find function app with id "{0}"' , resourceId ) ) ; } const client = await slotTreeItem . site . createClient ( context ) ; const hostKeys = await client . listHostKeys ( ) ; const defaultHostName = slotTreeItem . site . defaultHostName ; if ( ! ! hostKeys && hostKeys . masterKey && defaultHostName ) { const requestOptions = { method : 'GET' , url : `https://${ defaultHostName }/admin/functions/download?includeCsproj=true&includeAppSettings=true` , headers : { 'x-functions-key' : hostKeys . masterKey } } ; await requestUtils . downloadFile ( context , requestOptions , downloadFilePath ) ; } else { throw new Error ( localize ( 'hostInformationNotFound' , 'Failed to get host information for the functionApp.' ) ) ; } const projectFilePathUri = vscode . Uri . joinPath ( vsCodeFilePathUri , `${ functionAppName }` ) ; const projectFilePath = projectFilePathUri . fsPath ; const devContainerFolderPathUri = vscode . Uri . joinPath ( projectFilePathUri , '.devcontainer' ) ; await extract ( downloadFilePath , { dir : projectFilePath } ) ; await requestUtils . downloadFile ( context , `https://raw.githubusercontent.com/microsoft/vscode-dev-containers/master/containers/${ devContainerName }/.devcontainer/devcontainer.json` , vscode . Uri . joinPath ( devContainerFolderPathUri , 'devcontainer.json' ) . fsPath ) ; await requestUtils . downloadFile ( context , `https://raw.githubusercontent.com/microsoft/vscode-dev-containers/master/containers/${ devContainerName }/.devcontainer/Dockerfile` , vscode . Uri . joinPath ( devContainerFolderPathUri , 'Dockerfile' ) . fsPath ) ; await initProjectForVSCode ( context , projectFilePath , getProjectLanguageForLanguage ( language ) ) ; await vscode . window . showInformationMessage ( localize ( 'restartingVsCodeInfoMessage' , 'Restarting VS Code with your function app project' ) ) ; await vscode . commands . executeCommand ( 'vscode.openFolder' , vscode . Uri . file ( projectFilePath ) , true ) ; } ) ; } catch ( err ) { throw new Error ( localize ( 'failedLocalProjSetupErrorMessage' , 'Failed to set up your local project: "{0}".' , parseError ( err ) . message ) ) ; } finally { await vscode . workspace . fs . delete ( vscode . Uri . file ( toBeDeletedFolderPathUri . fsPath ) , { recursive : true , useTrash : true } ) ; } } function getProjectLanguageForLanguage ( language ) { switch ( language ) { case 'powershell' : return ProjectLanguage . PowerShell ; case 'node' : return ProjectLanguage . JavaScript ; case 'python' : return ProjectLanguage . Python ; case 'dotnetcore2.1' : case 'dotnetcore3.1' : return ProjectLanguage . CSharpScript ; default : throw new Error ( `Language not supported: ${ language }` ) ; } }