eng/scripts/service-adoption.ps1 (155 lines of code) (raw):

#!/usr/bin/env pwsh #cSpell:disable <# .SYNOPSIS This script analyzes a Git repository to find all commits that add a new 'tspconfig.yaml' file within a specified date range. .DESCRIPTION The script takes a start date, an end date, and an optional array of branch names as parameters. It then iterates over each branch and each month in the date range. For each month, it uses the `git log` command to find all commits that added a new 'tspconfig.yaml' file on the specified branches. Afer eliminating duplicate commits between branches, the script counts the number of such commits for each month and outputs the counts in a table format. It also distinguishes between data plane and management plane commits based on the existence of 'resource-manager' or 'Management' in the file paths in the commit. Furthermore, it distinguishes between greenfield (new services) and brownfield (existing services) based on the existence of a 'stable' folder in the service path. .PARAMETER startDate The start date for the analysis. Must be a string in the format 'yyyy-MM-dd'. .PARAMETER endDate The end date for the analysis. Must be a string in the format 'yyyy-MM-dd'. .PARAMETER branchName The names of the Git branches to analyze. Optional, defaults to 'main'. The script is typically run against 'main' and 'RPSaaSMaster' branches. .PARAMETER DebugMode A flag that enables debug mode, which outputs additional information for each commit. Optional, defaults to false. .EXAMPLE .\service-adoption.ps1 -startDate '2023-08-01' -endDate '2024-03-29' -branchName 'main', 'RPSaaSMaster' This example runs the script with a start date of August 1, 2023, an end date of March 29, 2024, and analyzes the 'main' and 'RPSaaSMaster' branches. #> # Define script parameters param ( # Start and end dates for the analysis (mandatory) [Parameter(Mandatory=$true)] [string]$startDate, [Parameter(Mandatory=$true)] [string]$endDate, # Names of the Git branches to analyze (optional, defaults to 'main') [Parameter(Mandatory=$false)] [string[]]$branchName = 'main', # Debug mode flag (optional, defaults to false) [Parameter(Mandatory=$false)] [bool]$DebugMode = $false ) # Convert the date strings to DateTime objects $start = Get-Date $startDate $end = Get-Date $endDate # Define the relative path to the Git repository $repoPath = Join-Path -Path $PSScriptRoot -ChildPath "azure-rest-api-specs-pr" # Initialize an empty array to hold all commits $allCommits = @() # Initialize an empty hashtable to hold the output objects $output = @{} # Initialize an empty hashtable to hold the processed file paths $processedPaths = @{} # Loop over each month in the date range for ($date = $start; $date -le $end; $date = $date.AddMonths(1)) { # Loop over each branch foreach ($branch in $branchName) { # Loop over each month in the date range for ($date = $start; $date -le $end; $date = $date.AddMonths(1)) { # Initialize counters for data plane and management plane commits $dataPlaneCommits = 0 $managementPlaneCommits = 0 $greenfieldCommits = 0 $brownfieldCommits = 0 # Initialize an empty array to hold the commits for this month $monthlyCommits = @() # Define the date range for this month $since = $date.ToString("yyyy-MM-dd") $until = $date.AddMonths(1).ToString("yyyy-MM-dd") # Change to the Git repository directory Set-Location -Path $repoPath # Get the name of the current branch $currentBranch = git rev-parse --abbrev-ref HEAD # Check if the current branch matches $branch if ($currentBranch -ne $branch) { # If not, switch to $branch git checkout $branch } # Find commits that add new 'tspconfig.yaml' files during this month on the specified branch $commitHashesAndDates = git log $branch --since=$since --until=$until --pretty=format:"%H %ad" --diff-filter=A -- '*tspconfig.yaml' # Process each commit separately foreach ($commitHashAndDate in $commitHashesAndDates -split "`n") { # Split the commit hash and date $commitHash, $commitDate = $commitHashAndDate -split " ", 2 # Get the file paths for this commit $filePaths = git show --pretty="" --name-only $commitHash # Check if the commit includes changes to 'tspconfig.yaml' if ($filePaths -match "tspconfig.yaml") { $tspconfigPaths = $filePaths | Where-Object { $_ -match "tspconfig.yaml" } # Skip duplicate file paths if ($processedPaths.ContainsKey($tspconfigPaths)) { continue } # Add the file path to the hashtable $processedPaths[$tspconfigPaths] = $true # Get the service name from the file path $service = ($tspconfigPaths -split '/')[1] # Print the value of $tspconfigPaths if ($DebugMode) { Write-Output "Paths: $tspconfigPaths" Write-Output "Checking status for service $service..." } $stable = Get-ChildItem -Path "$repoPath/specification/$service" -Recurse -Directory | Where-Object { $_.Name -like "stable" } # Check if the service has a 'stable' folder. If not, it's greenfield if ($null -eq $stable) { # Write-Output "Greenfield service commit" $greenfieldCommits++ } else { # Write-Output "Brownfield service commit" $brownfieldCommits++ } # Check if the file path matches the data plane or management plane criteria if ($filePaths -notmatch 'resource-manager' -and $filePaths -notmatch '\.Management') { # This is a data plane commit $dataPlaneCommits++ } else { # This is a management plane commit $managementPlaneCommits++ } # Add the commit to the array of all commits and the array of monthly commits $allCommits += $commitHash $monthlyCommits += $commitHash } } # Count the unique commits $discreteCount = $monthlyCommits | Sort-Object -Unique | Measure-Object | % { $_.Count } # Update the hashtable $monthKey = $date.ToString("yyyy-MM") if ($output.ContainsKey($monthKey)) { # Update the existing object $output[$monthKey].Discrete += $discreteCount # cumulativeCount is updated separately further down below $output[$monthKey].Data += $dataPlaneCommits $output[$monthKey].Mgmt += $managementPlaneCommits $output[$monthKey].Greenfield += $greenfieldCommits $output[$monthKey].Brownfield += $brownfieldCommits } else { # Create a new object and add it to the hashtable $output[$monthKey] = New-Object PSObject -Property @{ Month = $monthKey Discrete = $discreteCount Cumulative = 0 Data = $dataPlaneCommits Mgmt = $managementPlaneCommits Greenfield = $greenfieldCommits Brownfield = $brownfieldCommits } } } } } # Change back to the script directory Set-Location -Path $PSScriptRoot # Calculate the cumulative counts $cumulativeCount = 0 $output.Values | Sort-Object Month | ForEach-Object { $cumulativeCount += $_.Discrete $_.Cumulative = $cumulativeCount } # Output the counts in a table format $output.Values | Sort-Object Month | Format-Table -Property Month, Discrete, Cumulative, Data, Mgmt, Greenfield, Brownfield -AutoSize # Export the counts to a CSV file with the properties in the same order. CSV file can be loaded in Excel to generate charts. $output.Values | Sort-Object Month | Select-Object Month, Discrete, Cumulative, Data, Mgmt, Greenfield, Brownfield | Export-Csv -Path ./output.csv -NoTypeInformation