eng/common/testproxy/onboarding/common-asset-functions.ps1 (222 lines of code) (raw):

class Assets { [string]$AssetsRepo = $DefaultAssetsRepo [string]$AssetsRepoPrefixPath = "" [string]$TagPrefix = "" [string]$Tag = "" Assets( [string]$AssetsRepoPrefixPath, [string]$TagPrefix ) { $this.TagPrefix = $TagPrefix $this.AssetsRepoPrefixPath = $AssetsRepoPrefixPath } } class Version { [int]$Year [int]$Month [int]$Day [int]$Revision Version( [string]$VersionString ) { if ($VersionString -match "(?<year>20\d{2})(?<month>\d{2})(?<day>\d{2}).(?<revision>\d+)") { $this.Year = [int]$Matches["year"] $this.Month = [int]$Matches["month"] $this.Day = [int]$Matches["day"] $this.Revision = [int]$Matches["revision"] } else { # This should be a Write-Error however powershell apparently cannot utilize that # in the constructor in certain cases Write-Warning "Version String '$($VersionString)' is invalid and cannot be parsed" exit 1 } } [bool] IsGreaterEqual([string]$OtherVersionString) { [Version]$OtherVersion = [Version]::new($OtherVersionString) if ($this.Year -lt $OtherVersion.Year) { return $false } elseif ($this.Year -eq $OtherVersion.Year) { if ($this.Month -lt $OtherVersion.Month) { return $false } elseif ($this.Month -eq $OtherVersion.Month) { if ($this.Day -lt $OtherVersion.Day) { return $false } elseif ($this.Day -eq $OtherVersion.Day) { if ($this.Revision -lt $OtherVersion.Revision) { return $false } } } } return $true } } Function Resolve-Proxy { $testProxyExe = "test-proxy" # this script requires the presence of the test-proxy on the PATH $proxyToolPresent = Test-Exe-In-Path -ExeToLookFor "test-proxy" -ExitOnError $false $proxyStandalonePresent = Test-Exe-In-Path -ExeToLookFor "Azure.Sdk.Tools.TestProxy" -ExitOnError $false if (-not $proxyToolPresent -and -not $proxyStandalonePresent) { Write-Error "This script requires the presence of a test-proxy executable to complete its operations. Exiting." exit 1 } if (-not $proxyToolPresent) { $testProxyExe = "Azure.Sdk.Tools.TestProxy" } return $testProxyExe } Function Test-Exe-In-Path { Param([string] $ExeToLookFor, [bool]$ExitOnError = $true) if ($null -eq (Get-Command $ExeToLookFor -ErrorAction SilentlyContinue)) { if ($ExitOnError) { Write-Error "Unable to find $ExeToLookFor in your PATH" exit 1 } else { return $false } } return $true } Function Test-TestProxyVersion { param( [string] $TestProxyExe ) Write-Host "$TestProxyExe --version" [string] $output = & "$TestProxyExe" --version [Version]$CurrentProxyVersion = [Version]::new($output) if (!$CurrentProxyVersion.IsGreaterEqual($MinTestProxyVersion)) { Write-Error "$TestProxyExe version, $output, is less than the minimum version $MinTestProxyVersion" Write-Error "Please refer to https://github.com/Azure/azure-sdk-tools/blob/main/tools/test-proxy/Azure.Sdk.Tools.TestProxy/README.md#installation to upgrade your $TestProxyExe" exit 1 } } Function Get-Repo-Language { $GitRepoOnDiskErr = "This script can only be called from within an azure-sdk-for-<lang> repository on disk." # Git remote -v is going to give us output similar to the following # origin git@github.com:Azure/azure-sdk-for-java.git (fetch) # origin git@github.com:Azure/azure-sdk-for-java.git (push) # upstream git@github.com:Azure/azure-sdk-for-java (fetch) # upstream git@github.com:Azure/azure-sdk-for-java (push) # We're really only trying to get the language from the git remote Write-Host "git remote -v" [array] $remotes = & git remote -v foreach ($line in $remotes) { Write-Host "$line" } # Git remote -v returned "fatal: not a git repository (or any of the parent directories): .git" # and the list of remotes will be null if (-not $remotes) { Write-Error $GitRepoOnDiskErr exit 1 } # The regular expression needed to be updated to handle the following types of input: # origin git@github.com:Azure/azure-sdk-for-python.git (fetch) # origin git@github.com:Azure/azure-sdk-for-python-pr.git (fetch) # fork git@github.com:UserName/azure-sdk-for-python (fetch) # azure-sdk https://github.com/azure-sdk/azure-sdk-for-net.git (fetch) # origin https://github.com/Azure/azure-sdk-for-python/ (fetch) # ForEach-Object splits the string on whitespace so each of the above strings is actually # 3 different strings. The first and last pieces won't match anything, the middle string # will match what is below. If the regular expression needs to be updated the following # link below will go to a regex playground # https://regex101.com/r/auOnAr/1 $lang = $remotes[0] | ForEach-Object { if ($_ -match "azure-sdk-for-(?<lang>[^\-\.\/ ]+)") { #Return the named language match return $Matches["lang"] } } if ([String]::IsNullOrWhitespace($lang)) { Write-Error $GitRepoOnDiskErr exit 1 } Write-Host "Current language=$lang" return $lang } Function Get-Repo-Root($StartDir=$null) { [string] $currentDir = Get-Location if ($StartDir){ $currentDir = $StartDir } # -1 to strip off the trialing directory separator return $currentDir.Substring(0, $currentDir.LastIndexOf("sdk") - 1) } Function New-Assets-Json-File { param( [Parameter(Mandatory = $true)] [string] $Language ) $AssetsRepoPrefixPath = $Language [string] $currentDir = Get-Location $sdkDir = "$([IO.Path]::DirectorySeparatorChar)sdk$([IO.Path]::DirectorySeparatorChar)" # if we're not in a <reporoot>/sdk/<ServiceDirectory> or deeper then this script isn't # being run in the right place if (-not $currentDir.contains($sdkDir)) { Write-Error "This script needs to be run at an sdk/<ServiceDirectory> or deeper." exit 1 } $TagPrefix = $currentDir.Substring($currentDir.LastIndexOf("sdk") + 4) $TagPrefix = $TagPrefix.Replace("\", "/") $TagPrefix = "$($AssetsRepoPrefixPath)/$($TagPrefix)" [Assets]$Assets = [Assets]::new($AssetsRepoPrefixPath, $TagPrefix) $AssetsJson = $Assets | ConvertTo-Json $AssetsFileName = Join-Path -Path $currentDir -ChildPath "assets.json" Write-Host "Writing file $AssetsFileName with the following contents" Write-Host $AssetsJson $Assets | ConvertTo-Json | Out-File $AssetsFileName return $AssetsFileName } # Invoke the proxy command and echo the output. Function Invoke-ProxyCommand { param( [string] $TestProxyExe, [string] $CommandString, [string] $TargetDirectory ) $updatedDirectory = $TargetDirectory.Replace("`\", "/") Write-Host "$TestProxyExe $CommandString" [array] $output = & "$TestProxyExe" $CommandString.Split(" ") --storage-location="$updatedDirectory" # echo the command output foreach ($line in $output) { Write-Host "$line" } } # Get the shorthash directory under PROXY_ASSETS_FOLDER Function Get-AssetsRoot { param( [string] $AssetsJsonFile, [string] $TestProxyExe ) $repoRoot = Get-Repo-Root $relPath = [IO.Path]::GetRelativePath($repoRoot, $AssetsJsonFile).Replace("`\", "/") $assetsJsonDirectory = Split-Path $relPath [array] $output = & "$TestProxyExe" config locate -a "$relPath" --storage-location="$repoRoot" $assetsDirectory = $output[-1] return Join-Path $assetsDirectory $assetsJsonDirectory } Function Move-AssetsFromLangRepo { param( [string] $AssetsRoot ) $filter = $LangRecordingDirs[$language] Write-Host "Language recording directory name=$filter" Write-Host "Get-ChildItem -Recurse -Filter ""*.json"" | Where-Object { if ($filter.Contains(""*"")) { $_.DirectoryName -match $filter } else { $_.DirectoryName.Split([IO.Path]::DirectorySeparatorChar) -contains ""$filter"" }" $filesToMove = Get-ChildItem -Recurse -Filter "*.json" | Where-Object { if ($filter.Contains("*")) { $_.DirectoryName -match $filter } else { $_.DirectoryName.Split([IO.Path]::DirectorySeparatorChar) -contains "$filter" } } [string] $currentDir = Get-Location foreach ($fromFile in $filesToMove) { $relPath = [IO.Path]::GetRelativePath($currentDir, $fromFile) $toFile = Join-Path -Path $AssetsRoot -ChildPath $relPath # Write-Host "Moving from=$fromFile" # Write-Host " to=$toFile" $toPath = Split-Path -Path $toFile Write-Host $toFile if (!(Test-Path $toPath)) { New-Item -Path $toPath -ItemType Directory -Force | Out-Null } Move-Item -LiteralPath $fromFile -Destination $toFile -Force } }