eng/GenerateSdkForNetCodeGenerationMatrix.ps1 (98 lines of code) (raw):
[CmdLetBinding()]
param (
[Parameter()]
[string]$SdkForNetPath,
[Parameter()]
[int]$GroupCount,
[Parameter()]
[string]$OutputFolder
)
# Divide the items into groups of approximately equal size.
function Split-Items([array]$Items) {
# given $Items.Length = 22 and $GroupCount = 5
# then $itemsPerGroup = 4
# and $largeGroupCount = 2
# and $group.Length = 5, 5, 4, 4, 4
$itemsPerGroup = [math]::Floor($Items.Length / $GroupCount)
$largeGroupCount = $Items.Length % $itemsPerGroup
$groups = [object[]]::new($GroupCount)
$i = 0
for($g = 0;$g -lt $GroupCount;$g++) {
$groupLength = if($g -lt $largeGroupCount) { $itemsPerGroup + 1 } else { $itemsPerGroup }
$group = [object[]]::new($groupLength)
$groups[$g] = $group
for($gi = 0;$gi -lt $groupLength;$gi++) {
$group[$gi] = $Items[$i++]
}
}
return ,$groups
}
# Write each project group into a props file and return the array of generated project file paths
function New-PropsFiles($ProjectGroups, $PropsFilePrefix) {
if (!$ProjectGroups -or !$ProjectGroups[0]) {
Throw "There should be some project files in the group. Please check the given project list."
}
$numOfGroups = $ProjectGroups.Count
for ($i = 0; $i -lt $numOfGroups; $i++) {
$projects = $ProjectGroups[$i]
$propsFileName = "$PropsFilePrefix$i.props"
$propsFilePath = Join-Path $OutputFolder $propsFileName
$itemGroupNode = [Xml.Linq.XElement]'<ItemGroup />'
foreach($project in $projects) {
$newElemAttr = [Xml.Linq.XAttribute]::new('Include', $project.Path)
$newElem = [Xml.Linq.XElement]::new('ProjectReference', $newElemAttr)
$itemGroupNode.Add($newElem)
}
$projectNode = [Xml.Linq.XElement]::new('Project', $itemGroupNode)
$projectNode.ToString() | Out-File $propsFilePath
Write-Host "$propsFileName`:`n$($projectNode.ToString())`n"
Write-Output @{
"FileName"=$propsFileName;
"Projects"=$projects
}
}
}
function Get-ProjectsWithAutorest() {
$projectsFilePath = "$SdkForNetPath/artifacts/projects.txt"
Remove-Item $projectsFilePath -Force -ErrorAction SilentlyContinue
Push-Location $SdkForNetPath
dotnet build "$SdkForNetPath/eng/service.proj" `
/t:GetCodeGenProjects `
/p:IncludeTests=false `
/p:IncludePerf=false `
/p:IncludeStress=false `
/p:OutputProjectFilePath=$projectsFilePath | Out-Host
Pop-Location
$projects = Get-Content $projectsFilePath
| Where-Object { $_ }
| ForEach-Object {
@{
"Path"= $_;
"ServiceArea"= $_ -match 'sdk[\\/](.*?)[\\/]' ? $Matches[1] : '??'
}
}
return $projects
}
function New-Matrix([array]$PropsFiles) {
$matrix = [ordered]@{}
for($i=0;$i -lt $PropsFiles.Length;$i++) {
$fileName = $PropsFiles[$i].FileName
$projects = $PropsFiles[$i].Projects
$firstPrefix = $projects[0].ServiceArea.Substring(0, 2)
$lastPrefix = $projects[-1].ServiceArea.Substring(0, 2)
$key = "$firstPrefix`_$lastPrefix`_$i"
$matrix[$key] = @{ 'JobKey' = $key; 'ProjectListOverrideFile' = $fileName }
}
return $matrix
}
function Write-JsonVariable($VariableName, $Value) {
$compressed = ConvertTo-Json $Value -Depth 100 -Compress
Write-Output "##vso[task.setVariable variable=$VariableName;isOutput=true]$compressed"
}
New-Item -Path $OutputFolder -ItemType "directory" -Force | Out-Null
$projects = Get-ProjectsWithAutorest | Sort-Object -Property Path
$projectGroups = Split-Items -Items $projects
$propsFiles = New-PropsFiles -ProjectGroups $projectGroups -PropsFilePrefix 'projects_'
$matrix = New-Matrix -PropsFiles $propsFiles
Write-JsonVariable "matrix" $matrix
Write-Host "Matrix:`n$(ConvertTo-Json $matrix -Depth 100)"