1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
# For details see https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/TypeSpec-Project-Scripts.md
[CmdletBinding()]
param (
[Parameter(Position = 0)]
[ValidateNotNullOrEmpty()]
[string] $TypeSpecProjectDirectory, # A directory of `tspconfig.yaml` or a remoteUrl of `tspconfig.yaml`
[Parameter(Position = 1)]
[string] $CommitHash,
[Parameter(Position = 2)]
[string] $RepoUrl,
[switch] $SkipSyncAndGenerate
)
. $PSScriptRoot/common.ps1
. $PSScriptRoot/Helpers/PSModule-Helpers.ps1
Install-ModuleIfNotInstalled "powershell-yaml" "0.4.7" | Import-Module
function CreateUpdate-TspLocation([System.Object]$tspConfig, [string]$TypeSpecProjectDirectory, [string]$CommitHash, [string]$repo, [string]$repoRoot, [ref]$isNewSdkProject) {
$additionalDirs = @()
if ($tspConfig["parameters"]["dependencies"] -and $tspConfig["parameters"]["dependencies"]["additionalDirectories"]) {
$additionalDirs = $tspConfig["parameters"]["dependencies"]["additionalDirectories"];
}
# Create service-dir if not exist
$serviceDir = Get-ServiceDir $tspConfig $repoRoot
if (!(Test-Path -Path $serviceDir)) {
New-Item -Path $serviceDir -ItemType Directory | Out-Null
Write-Host "created service folder $serviceDir"
}
# Create package-dir if not exist
$packageDir = Get-PackageDir $tspConfig
$packageDir = Join-Path $serviceDir $packageDir
if (!(Test-Path -Path $packageDir)) {
New-Item -Path $packageDir -ItemType Directory | Out-Null
Write-Host "created package folder $packageDir"
$isNewSdkProject.Value = $true
}
# Load tsp-location.yaml if exist
$tspLocationYamlPath = Join-Path $packageDir "tsp-location.yaml"
$tspLocationYaml = @{}
if (Test-Path -Path $tspLocationYamlPath) {
$tspLocationYaml = Get-Content -Path $tspLocationYamlPath -Raw | ConvertFrom-Yaml
}
else {
Write-Host "creating tsp-location.yaml in $packageDir"
}
# Update tsp-location.yaml
$tspLocationYaml["commit"] = $CommitHash
Write-Host "updated tsp-location.yaml commit to $CommitHash"
$tspLocationYaml["repo"] = $repo
Write-Host "updated tsp-location.yaml repo to $repo"
$tspLocationYaml["directory"] = $TypeSpecProjectDirectory
Write-Host "updated tsp-location.yaml directory to $TypeSpecProjectDirectory"
$tspLocationYaml["additionalDirectories"] = $additionalDirs
Write-Host "updated tsp-location.yaml additionalDirectories to $additionalDirs"
$tspLocationYaml |ConvertTo-Yaml | Out-File $tspLocationYamlPath
Write-Host "finished updating tsp-location.yaml in $packageDir"
return $packageDir
}
function Get-ServiceDir([System.Object]$tspConfig, [string]$repoRoot) {
$serviceDir = ""
if ($tspConfig["parameters"] -and $tspConfig["parameters"]["service-dir"]) {
$serviceDir = $tspConfig["parameters"]["service-dir"]["default"];
}
else {
Write-Error "Missing service-dir in parameters section of tspconfig.yaml. Please refer to https://github.com/Azure/azure-rest-api-specs/blob/main/specification/contosowidgetmanager/Contoso.WidgetManager/tspconfig.yaml for the right schema."
exit 1
}
# Create service-dir if not exist
$serviceDir = Join-Path $repoRoot $serviceDir
return $serviceDir
}
function Get-PackageDir([System.Object]$tspConfig) {
$emitterName = ""
if (Test-Path "Function:$GetEmitterNameFn") {
$emitterName = &$GetEmitterNameFn
}
else {
Write-Error "Missing $GetEmitterNameFn function in {$Language} SDK repo script."
exit 1
}
$packageDir = ""
if ($tspConfig["options"] -and $tspConfig["options"]["$emitterName"] -and $tspConfig["options"]["$emitterName"]["package-dir"]) {
$packageDir = $tspConfig["options"]["$emitterName"]["package-dir"]
}
else {
Write-Error "Missing package-dir in $emitterName options of tspconfig.yaml. Please refer to https://github.com/Azure/azure-rest-api-specs/blob/main/specification/contosowidgetmanager/Contoso.WidgetManager/tspconfig.yaml for the right schema."
exit 1
}
return $packageDir
}
function Get-TspLocationFolder([System.Object]$tspConfig, [string]$repoRoot) {
$serviceDir = Get-ServiceDir $tspConfig $repoRoot
$packageDir = Get-PackageDir $tspConfig
$packageDir = Join-Path $serviceDir $packageDir
return $packageDir
}
$sdkRepoRootPath = (Join-Path $PSScriptRoot .. .. ..)
$sdkRepoRootPath = Resolve-Path $sdkRepoRootPath
$sdkRepoRootPath = $sdkRepoRootPath -replace "\\", "/"
$tspConfigPath = Join-Path $sdkRepoRootPath 'tspconfig.yaml'
$tmpTspConfigPath = $tspConfigPath
$repo = ""
$specRepoRoot = ""
$generateFromLocalTypeSpec = $false
$isNewSdkProject = $false
# remote url scenario
# example url of tspconfig.yaml: https://github.com/Azure/azure-rest-api-specs-pr/blob/724ccc4d7ef7655c0b4d5c5ac4a5513f19bbef35/specification/containerservice/Fleet.Management/tspconfig.yaml
if ($TypeSpecProjectDirectory -match '^https://github.com/(?<repo>[^/]*/azure-rest-api-specs(-pr)?)/blob/(?<commit>[0-9a-f]{40})/(?<path>.*)/tspconfig.yaml$') {
try {
$TypeSpecProjectDirectory = $TypeSpecProjectDirectory -replace "https://github.com/(.*)/(tree|blob)", "https://raw.githubusercontent.com/`$1"
Invoke-WebRequest $TypeSpecProjectDirectory -OutFile $tspConfigPath -MaximumRetryCount 3
}
catch {
Write-Host "Failed to download '$TypeSpecProjectDirectory'"
Write-Error $_.Exception.Message
return
}
$repo = $Matches["repo"]
$TypeSpecProjectDirectory = $Matches["path"]
$CommitHash = $Matches["commit"]
# TODO support the branch name in url then get the commithash from branch name
} else {
# local path scenario
$tspConfigPath = Join-Path $TypeSpecProjectDirectory "tspconfig.yaml"
if (!(Test-Path $tspConfigPath)) {
Write-Error "Failed to find tspconfig.yaml in '$TypeSpecProjectDirectory'"
exit 1
}
$TypeSpecProjectDirectory = $TypeSpecProjectDirectory.Replace("\", "/")
if ($TypeSpecProjectDirectory -match "(?<repoRoot>^.*)/(?<path>specification/.*)$") {
$TypeSpecProjectDirectory = $Matches["path"]
$specRepoRoot = $Matches["repoRoot"]
} else {
Write-Error "$TypeSpecProjectDirectory doesn't have 'specification' in path."
exit 1
}
if (!$CommitHash -or !$RepoUrl) {
Write-Warning "Parameter of Commithash or RepoUrl are not provided along with the local path of tspconfig.yaml, trying to re-generate sdk code based on the local type specs."
$generateFromLocalTypeSpec = $true
}
if ($RepoUrl) {
if ($RepoUrl -match "^(https://github.com/|git@github.com:)(?<repo>[^/]*/azure-rest-api-specs(-pr)?).*") {
$repo = $Matches["repo"]
}
else {
Write-Error "Parameter 'RepoUrl' has incorrect value:$RepoUrl. It should be similar like 'https://github.com/Azure/azure-rest-api-specs'"
exit 1
}
}
}
$tspConfigYaml = Get-Content $tspConfigPath -Raw | ConvertFrom-Yaml
# delete the tmporary tspconfig.yaml downloaded from github
if (Test-Path $tmpTspConfigPath) {
Remove-Item $tspConfigPath
}
$sdkProjectFolder = ""
if ($generateFromLocalTypeSpec) {
Write-Host "Generating sdk code based on local type specs at specRepoRoot: $specRepoRoot."
$sdkProjectFolder = Get-TspLocationFolder $tspConfigYaml $sdkRepoRootPath
$tspLocationYamlPath = Join-Path $sdkProjectFolder "tsp-location.yaml"
if (!(Test-Path -Path $tspLocationYamlPath)) {
# try to create tsp-location.yaml using HEAD commit of the local spec repo
Write-Warning "Failed to find tsp-location.yaml in '$sdkProjectFolder'. Trying to create tsp-location.yaml using HEAD commit of the local spec repo then proceed the sdk generation based upon local typespecs at $specRepoRoot. Alternatively, please make sure to provide CommitHash and RepoUrl parameters when running this script."
# set default repo to Azure/azure-rest-api-specs
$repo = "Azure/azure-rest-api-specs"
try {
Push-Location $specRepoRoot
$CommitHash = $(git rev-parse HEAD)
$gitOriginUrl = (git remote get-url origin)
if ($gitOriginUrl -and $gitOriginUrl -match '(.*)?github.com:(?<repo>[^/]*/azure-rest-api-specs(-pr)?)(.git)?') {
$repo = $Matches["repo"]
Write-Host "Found git origin repo: $repo"
}
else {
Write-Warning "Failed to find git origin repo of the local spec repo at specRepoRoot: $specRepoRoot. Using default repo: $repo"
}
}
catch {
Write-Error "Failed to get HEAD commit or remote origin of the local spec repo at specRepoRoot: $specRepoRoot."
exit 1
}
finally {
Pop-Location
}
$sdkProjectFolder = CreateUpdate-TspLocation $tspConfigYaml $TypeSpecProjectDirectory $CommitHash $repo $sdkRepoRootPath -isNewSdkProject ([ref]$isNewSdkProject)
}
} else {
# call CreateUpdate-TspLocation function
$sdkProjectFolder = CreateUpdate-TspLocation $tspConfigYaml $TypeSpecProjectDirectory $CommitHash $repo $sdkRepoRootPath -isNewSdkProject ([ref]$isNewSdkProject)
}
# checking skip switch, only skip when it's not a new sdk project as project scaffolding is supported by emitter
if ($SkipSyncAndGenerate -and !$isNewSdkProject) {
Write-Host "Skip calling TypeSpec-Project-Sync.ps1 and TypeSpec-Project-Generate.ps1."
} else {
# call TypeSpec-Project-Sync.ps1
$syncScript = Join-Path $PSScriptRoot TypeSpec-Project-Sync.ps1
Write-Host "Calling TypeSpec-Project-Sync.ps1"
& $syncScript $sdkProjectFolder $specRepoRoot | Out-Null
if ($LASTEXITCODE) {
Write-Error "Failed to sync sdk project from $specRepoRoot to $sdkProjectFolder"
exit $LASTEXITCODE
}
# call TypeSpec-Project-Generate.ps1
Write-Host "Calling TypeSpec-Project-Generate.ps1"
$generateScript = Join-Path $PSScriptRoot TypeSpec-Project-Generate.ps1
& $generateScript $sdkProjectFolder | Out-Null
if ($LASTEXITCODE) {
Write-Error "Failed to generate sdk project at $sdkProjectFolder"
exit $LASTEXITCODE
}
}
return $sdkProjectFolder
|