UpdateSubmodules.ps1 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #!/usr/bin/env powershell
  2. <#
  3. .SYNOPSIS
  4. Updates git submodules and generates a commit message with the list of changes
  5. .PARAMETER GitCommitArgs
  6. Additional arguments to pass into git-commit
  7. .PARAMETER NoCommit
  8. Make changes without executing git-commit
  9. .PARAMETER Force
  10. Specified this to make a commit with any changes
  11. #>
  12. [cmdletbinding(SupportsShouldProcess = $true)]
  13. param(
  14. [string[]]$GitCommitArgs = @(),
  15. [switch]$NoCommit,
  16. [switch]$Force
  17. )
  18. $ErrorActionPreference = 'Stop'
  19. Set-StrictMode -Version 2
  20. $RepoRoot = Resolve-Path "$PSScriptRoot\.."
  21. Import-Module "$PSScriptRoot/common.psm1" -Scope Local -Force
  22. function Get-GitChanges([string]$Path) {
  23. Write-Verbose "git diff --cached --quiet $Path"
  24. & git diff --cached --quiet $Path | Out-Null
  25. if ($LastExitCode -ne 0) {
  26. return $true
  27. }
  28. Write-Verbose "git diff --quiet $Path"
  29. & git diff --quiet $Path | Out-Null
  30. return $LastExitCode -ne 0
  31. }
  32. try {
  33. Assert-Git
  34. if (Get-GitChanges "$RepoRoot/modules") {
  35. Write-Error "$RepoRoot/modules is in an unclean state. Reset submodules first by running ``git submodule update``"
  36. exit 1
  37. }
  38. Invoke-Block { & git submodule update --init }
  39. $submodules = @()
  40. Get-ChildItem "$RepoRoot/modules/*" -Directory | % {
  41. Push-Location $_
  42. try {
  43. $data = @{
  44. path = $_
  45. module = $_.Name
  46. commit = $(git rev-parse HEAD)
  47. newCommit = $null
  48. changed = $false
  49. }
  50. Write-Verbose "$($data.module) is at $($data.commit)"
  51. $submodules += $data
  52. }
  53. finally {
  54. Pop-Location
  55. }
  56. }
  57. Write-Verbose "git submodule update --remote"
  58. Invoke-Block { & git submodule update --remote }
  59. $changes = $submodules `
  60. | % {
  61. Push-Location $_.path
  62. try {
  63. $newCommit = $(git rev-parse HEAD)
  64. $_.newCommit = $newCommit
  65. if ($newCommit -ne $_.commit) {
  66. $_.changed = $true
  67. Write-Verbose "$($_.module) updated to $($_.newCommit)"
  68. }
  69. else {
  70. Write-Verbose "$($_.module) did not change"
  71. }
  72. return $_
  73. }
  74. finally {
  75. Pop-Location
  76. }
  77. } `
  78. | ? { $_.changed } `
  79. | % { "$($_.module) to $($_.newCommit.Substring(0, 8))" }
  80. $submodules `
  81. | ? { $_.changed } `
  82. | % {
  83. Invoke-Block { & git add $_.path }
  84. }
  85. if ($changes) {
  86. $shortMessage = "Updating submodule(s) $( $changes -join ' ,' )"
  87. # add this to the commit message to make it possible to filter commit triggers based on message
  88. $message = "$shortMessage`n`n[auto-updated: submodules]"
  89. if (-not $NoCommit -and ($Force -or ($PSCmdlet.ShouldContinue($shortMessage, 'Create a new commit with these changes?')))) {
  90. Invoke-Block { & git commit -m $message @GitCommitArgs }
  91. } else {
  92. # If composing this script with others, return the message that would have been used
  93. return @{
  94. message = $message
  95. }
  96. }
  97. }
  98. else {
  99. Write-Host -ForegroundColor Magenta 'No changes detected in git submodules'
  100. }
  101. }
  102. finally {
  103. Pop-Location
  104. }