diff --git a/eng/codegen_to_sdk_config.json b/eng/codegen_to_sdk_config.json new file mode 100644 index 000000000000..f0d47d11d622 --- /dev/null +++ b/eng/codegen_to_sdk_config.json @@ -0,0 +1,31 @@ +{ + "init": { + "initScript": { + "path": "./eng/scripts/automation/init.sh", + "logPrefix": "[DotNet]", + "stderr":{ + "storeAllLog": true + } + } + }, + "generateAndBuild": { + "generateAndBuildScript": { + "path": "./eng/scripts/automation/Invoke-GenerateAndBuild.ps1", + "script": "pwsh", + "logPrefix": "[DotNet-Generate]", + "stderr":{ + "storeLogByFilter": "[error|Error|Exception]" + } + } + }, + "mockTest": { + "mockTestScript": { + "path": "./eng/scripts/automation/Invoke-MockTest.ps1", + "script": "pwsh", + "logPrefix": "[GO-MockTest]", + "stderr":{ + "storeLogByFilter": "[error|Error|Exception]" + } + } + } +} \ No newline at end of file diff --git a/eng/scripts/automation/GenerateAndBuildLib.ps1 b/eng/scripts/automation/GenerateAndBuildLib.ps1 index aee815bd3c76..07e036c80802 100644 --- a/eng/scripts/automation/GenerateAndBuildLib.ps1 +++ b/eng/scripts/automation/GenerateAndBuildLib.ps1 @@ -122,6 +122,68 @@ function New-DataPlanePackageFolder() { return $projectFolder } +function New-MgmtPackageFolder() { + param( + [string]$service = "", + [string]$packageName = "", + [string]$sdkPath = "", + [string]$commitid = "", + [string]$readme = "", + [string]$AUTOREST_CONFIG_FILE = "autorest.md", + [string]$outputJsonFile = "newPacakgeOutput.json" + ) + + $projectFolder="$sdkPath/sdk/$packageName/Azure.ResourceManager.*" + if (Test-Path -Path $projectFolder) { + Write-Host "Path exists!" + $folderinfo = Get-ChildItem -Path $projectFolder + $foldername = $folderinfo.Name + $projectFolder = "$sdkPath/sdk/$packageName/$foldername" + } else { + Write-Host "Path doesn't exist. create template." + dotnet new -i $sdkPath/eng/templates/Azure.ResourceManager.Template + $projectFolder="$sdkPath/sdk/$packageName/Azure.ResourceManager.$packageName" + Write-Host "Create project folder $projectFolder" + New-Item -Path $projectFolder -ItemType Directory + # Set-Location $projectFolder + Push-Location $projectFolder + dotnet new azuremgmt --provider $packageName --includeCI true --force + Pop-Location + } + + # update the readme url if needed. + if ($commitid -ne "") { + Write-Host "Updating autorest.md file." + $swaggerInfo = Get-SwaggerInfo -dir "$projectFolder/src" + $org = $swaggerInfo[0] + $rp = $swaggerInfo[1] + $permalinks = "https://github.com/$org/azure-rest-api-specs/blob/$commitid/specification/$rp/resource-manager/readme.md" + $requirefile = "require: $permalinks" + $rquirefileRex = "require *:.*.md" + $file="$projectFolder/src/$AUTOREST_CONFIG_FILE" + (Get-Content $file) -replace $rquirefileRex, "$requirefile" | Set-Content $file + } elseif ($readme -ne "") { + Write-Host "Updating required file $readme in autorest.md file." + $requirefile = "require: $readme" + $rquirefileRex = "require *:.*.md" + $file="$projectFolder/src/$AUTOREST_CONFIG_FILE" + (Get-Content $file) -replace $rquirefileRex, "$requirefile" | Set-Content $file + + $readmefilestr = Get-Content $file + Write-Output "autorest.md:$readmefilestr" + } + + $path=$projectFolder + $path=$path.Replace($sdkPath + "/", "") + $outputJson = [PSCustomObject]@{ + projectFolder = $projectFolder + path = $path + } + + $outputJson | ConvertTo-Json -depth 100 | Out-File $outputJsonFile + + return $projectFolder +} function Invoke-Generate() { param( [string]$sdkfolder= "" @@ -129,4 +191,20 @@ function Invoke-Generate() { $sdkfolder = $sdkfolder -replace "\\", "/" Set-Location $sdkfolder/src dotnet build /t:GenerateCode +} +function Get-ResourceProviderFromReadme($readmeFile) { + $readmeFileRegex = "(?.*)/resource-manager/readme.md" + try + { + if ($readmeFile -match $readmeFileRegex) + { + return $matches["specName"] + } + } + catch + { + Write-Error "Error parsing readme info" + Write-Error $_ + } + Write-Host "Cannot find resource provider info" } \ No newline at end of file diff --git a/eng/scripts/automation/Invoke-GenerateAndBuild.ps1 b/eng/scripts/automation/Invoke-GenerateAndBuild.ps1 new file mode 100644 index 000000000000..d06100904018 --- /dev/null +++ b/eng/scripts/automation/Invoke-GenerateAndBuild.ps1 @@ -0,0 +1,51 @@ +#Requires -Version 7.0 +param ( + [string]$inputJsonFile="generateInput.json", + [string]$outputJsonFile="output.json" +) + +. (Join-Path $PSScriptRoot GenerateAndBuildLib.ps1) + +$inputJson = Get-Content $inputJsonFile | Out-String | ConvertFrom-Json +$swaggerDir = $inputJson.specFolder +$swaggerDir = $swaggerDir -replace "\\", "/" +$readmeFile = $inputJson.relatedReadmeMdFile +$readmeFile = $readmeFile -replace "\\", "/" +$commitid = $inputJson.headSha +$serviceType = $inputJson.serviceType + +Write-Host "swaggerDir:$swaggerDir, readmeFile:$readmeFile" + +$packageName = Get-ResourceProviderFromReadme $readmeFile +$sdkPath = (Join-Path $PSScriptRoot .. .. ..) +$sdkPath = Resolve-Path $sdkPath +$sdkPath = $sdkPath -replace "\\", "/" + +$newpackageoutput = "newPackageOutput.json" +if ( $serviceType -eq "resource-manager" ) { + Write-Host "Generate resource-manager SDK client library." + New-MgmtPackageFolder -service $service -packageName $packageName -sdkPath $sdkPath -commitid $commitid -readme $swaggerDir/$readmeFile -outputJsonFile $newpackageoutput +} else { + Write-Host "Generate data-plane SDK client library." + Write-Host "Data-plane SDK Generation is not implemented currently." + exit 1 +} +if ( $? -ne $True) { + Write-Error "Failed to create sdk project folder. exit code: $?" + exit 1 +} +$newpackageoutputJson = Get-Content $newpackageoutput | Out-String | ConvertFrom-Json +$projectFolder = $newpackageoutputJson.projectFolder +$path = $newpackageoutputJson.path +Write-Host "projectFolder:$projectFolder" +Remove-Item $newpackageoutput + +Invoke-Generate -sdkfolder $projectFolder +if ( $? -ne $True) { + Write-Error "Failed to generate sdk. exit code: $?" + exit 1 +} +$outputJson = [PSCustomObject]@{ + packages = @([pscustomobject]@{packageName="$packageName"; result='succeeded'; path=@("$path");packageFolder="$path"}) +} +$outputJson | ConvertTo-Json -depth 100 | Out-File $outputJsonFile \ No newline at end of file diff --git a/eng/scripts/automation/Invoke-MockTest.ps1 b/eng/scripts/automation/Invoke-MockTest.ps1 new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/eng/scripts/automation/MgmtMockTestLib.ps1 b/eng/scripts/automation/MgmtMockTestLib.ps1 new file mode 100644 index 000000000000..a379691bae22 --- /dev/null +++ b/eng/scripts/automation/MgmtMockTestLib.ps1 @@ -0,0 +1,7 @@ +function Invoke-MgmtTestgen() { + param( + [string]$sdkDirectory = "", + [string]$outputFolder = "" + ) + +} \ No newline at end of file diff --git a/eng/scripts/automation/generate-and-build.sh b/eng/scripts/automation/generate-and-build.sh new file mode 100644 index 000000000000..f09d09222d33 --- /dev/null +++ b/eng/scripts/automation/generate-and-build.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +if [ -z $1 ]; then + echo "Please input inputfile" + echo "Usage: generate-and-build.sh " + exit 1 +fi + +if [ -z $2 ]; then + echo "Please input outputfile" + echo "Usage: generate-and-build.sh " + exit 1 +fi + +pwsh eng/automation/Invoke-GenerateAndBuild.ps1 -inputJsonFile $1 -outputJsonFile $2 + +if [ "$?" != "0" ]; then + echo "Failed to generate code." + exit 1 +fi + +cat $2 \ No newline at end of file diff --git a/eng/scripts/automation/init.ps1 b/eng/scripts/automation/init.ps1 new file mode 100644 index 000000000000..3f94c2b5c2a1 --- /dev/null +++ b/eng/scripts/automation/init.ps1 @@ -0,0 +1,49 @@ +[string] $RepoRoot = "${PSScriptRoot}/../../.." +[string] $dotnetInstallScriptVersion = "v1" + +function GetDotNetInstallScript() { + $installScript = Join-Path $RepoRoot 'dotnet-install.sh' + if (!(Test-Path $installScript)) { + New-Item -Path $RepoRoot -Force -ItemType 'Directory' | Out-Null + $maxRetries = 5 + $retries = 1 + + $uri = "https://dot.net/$dotnetInstallScriptVersion/dotnet-install.sh" + while ($true) { + try { + Write-Host "GET $uri" + Invoke-WebRequest $uri -OutFile $installScript + break + } + catch { + Write-Host "Failed to download '$uri'" + Write-Error $_.Exception.Message -ErrorAction Continue + } + if (++$retries -le $maxRetries) { + $delayInSeconds = [math]::Pow(2, $retries) - 1 # Exponential backoff + Write-Host "Retrying. Waiting for $delayInSeconds seconds before next attempt ($retries of $maxRetries)." + Start-Sleep -Seconds $delayInSeconds + } + else { + throw "Unable to download file in $maxRetries attempts." + } + } + } + + return $installScript +} + +$GlobalJson = Get-Content -Raw -Path (Join-Path $RepoRoot 'global.json') | ConvertFrom-Json +$dotnetSdkVersion = $GlobalJson.sdk.version + +$installScript = GetDotNetInstallScript + +$dotnet = Join-Path $RepoRoot ".dotnet" +& bash $installScript --install-dir $dotnet --version $dotnetSdkVersion + +if (Test-Path $installScript) { + Remove-Item $installScript +} +$env:DOTNET_ROOT = '$dotnet' +$env:Path = '$env:DOTNET_ROOT;$env:Path' +dotnet --list-sdks \ No newline at end of file diff --git a/eng/scripts/automation/init.sh b/eng/scripts/automation/init.sh new file mode 100644 index 000000000000..d3442bd95c24 --- /dev/null +++ b/eng/scripts/automation/init.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +if [ -z $1 ]; then + echo "Please input outputfile" + echo "Usage: init.sh " + exit 1 +fi +echo $1 + +pwsh eng/scripts/automation/init.ps1 + +DIRECTORY=$(cd `dirname $0` && pwd) +WORKFOLDER="$(realpath $DIRECTORY/../../../)" +echo $WORKFOLDER +export DOTNET_ROOT=$WORKFOLDER/.dotnet +export PATH=$DOTNET_ROOT:$PATH +which dotnet +dotnet --list-sdks +echo $1 +cat > $1 << EOF +{ + "envs": { + "PATH": "$DOTNET_ROOT:$PATH", + "DOTNET_ROOT": "$DOTNET_ROOT" + } +} +EOF + +cat $1 \ No newline at end of file