Last active
February 8, 2023 08:42
-
-
Save level120/e0401bea4005d3a748d4dc9fd2bdf694 to your computer and use it in GitHub Desktop.
Change log generator - powershell version
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Based on https://medium.com/@Jeef/creating-a-git-submodule-change-log-for-ci-db60c90f821c | |
| # Input Parameter | |
| param([String] $script:BeginCommitOrTag, [String] $script:EndCommitOrTag, [String] $script:Branch) | |
| function Get-RootPath { | |
| <# | |
| .SYNOPSIS | |
| 입력 파라미터의 Path 기준으로 *.sln 파일이 있는 위치까지 상향 탐색합니다. | |
| .OUTPUTS | |
| [String] *.sln 파일이 있는 Path(없으면 빈 문자열) 반환 | |
| #> | |
| param ( | |
| [String] $BasePath | |
| ) | |
| if ((Get-ChildItem -Path $BasePath -Filter *.sln).count -gt 0) { | |
| return $BasePath | |
| } | |
| $ParentPath = (Get-Item $BasePath).Parent.FullName | |
| if ([string]::IsNullOrWhiteSpace($ParentPath)) { | |
| return '' | |
| } | |
| return Get-RootPath -BasePath $ParentPath | |
| } | |
| function Get-TimestampBy { | |
| <# | |
| .SYNOPSIS | |
| 현재 작업 디렉토리를 기준으로 입력 파라미터의 결과에서 시간 값만 반환합니다(git show). | |
| .OUTPUTS | |
| [String] "yyyy-MM-dd HH:mm:ss" 형태의 시간 문자열 | |
| #> | |
| param ( | |
| [String] $CommitOrTag | |
| ) | |
| if ([string]::IsNullOrWhiteSpace($CommitOrTag)) { | |
| return '' | |
| } | |
| return (git show -s --format=%ci $CommitOrTag) | ForEach-Object { | |
| if ($_ -match "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} *") { | |
| $_.split('+')[0].Trim() | |
| } | |
| } | |
| } | |
| function Get-SubModules { | |
| <# | |
| .SYNOPSIS | |
| 현재 작업 디렉토리를 기준으로 .gitmodules에 등록된 SubModule을 반환합니다. | |
| .OUTPUTS | |
| SubModule Name | |
| #> | |
| return (git config --file=.gitmodules -l) | ForEach-Object { | |
| $local:submodule_infos = $_.split('=')[0].split('.') | |
| if ($submodule_infos.length -gt 3) { | |
| $submodule_infos[1..($submodule_infos.length - 2)] -join '.' | |
| } | |
| else { | |
| $submodule_infos[1] | |
| } | |
| } | Sort-Object -Unique | |
| } | |
| function Get-Printable { | |
| <# | |
| .SYNOPSIS | |
| 현재 작업 디렉토리를 기준으로 변경점이 있는지 확인하여 그 결과를 반환합니다. | |
| .OUTPUTS | |
| [Bool] 타입의 결과 | |
| #> | |
| git fetch -q -p --all | Out-Null | |
| if ([string]::IsNullOrWhiteSpace($End)) { | |
| return (git log --pretty=`"%s`" --after `"$Begin`").Count -gt 0 | |
| } | |
| else { | |
| return (git log --pretty=`"%s`" --after `"$Begin`" --before=`"$End`").Count -gt 0 | |
| } | |
| } | |
| function Write-LogRecursively { | |
| <# | |
| .SYNOPSIS | |
| SubModule의 Log를 출력합니다. | |
| #> | |
| param ( | |
| [String] $SubmoduleName | |
| ) | |
| $local:SubmodulePath = (git config --file=.gitmodules --get submodule.$SubmoduleName.path) | |
| $local:SubmoduleBranch = (git config --file=.gitmodules --get submodule.$SubmoduleName.branch) | |
| # When branch not found | |
| if ([string]::IsNullOrWhiteSpace($SubmoduleBranch)) { | |
| $SubmoduleBranch = "HEAD" | |
| } | |
| $local:Location = $pwd.Path | |
| Set-Location $SubmodulePath | |
| if (Get-Printable) { | |
| Write-BranchInfo -RepoName $SubmoduleName -BranchName $SubmoduleBranch | |
| Write-Log | |
| } | |
| Set-Location $Location | |
| } | |
| function Write-LogCurrently { | |
| <# | |
| .SYNOPSIS | |
| 현 위치(솔루션 프로젝트)의 Log를 출력합니다. | |
| #> | |
| param ( | |
| [String] $BranchName | |
| ) | |
| # When branch not found | |
| if ([string]::IsNullOrWhiteSpace($BranchName)) { | |
| $BranchName = "HEAD" | |
| } | |
| $local:ProjectName = (git config --get remote.origin.url).split('/')[-1] | |
| Write-BranchInfo -RepoName $ProjectName -BranchName $BranchName | |
| Write-Log | |
| } | |
| function Write-Log { | |
| <# | |
| .SYNOPSIS | |
| git log를 이용해 해당 Repo의 Log 출력합니다. | |
| #> | |
| # When use "Write-Host", newline character ignore | |
| if ([string]::IsNullOrWhiteSpace($End)) { | |
| Write-Output (git log --pretty=`"tformat:* `(%h`) %s `(%ae`)`" --after=`"$Begin`") | |
| } | |
| else { | |
| Write-Output (git log --pretty=`"tformat:* `(%h`) %s `(%ae`)`" --after=`"$Begin`" --before=`"$End`") | |
| } | |
| } | |
| function Write-BranchInfo { | |
| <# | |
| .SYNOPSIS | |
| 해당 위치의 Title 출력 부분, [ RepoName : Branch ] 형태로 출력합니다. | |
| #> | |
| param ( | |
| [String] $RepoName, | |
| [String] $BranchName | |
| ) | |
| Write-Host "" | |
| Write-Host "[ " -NoNewline | |
| Write-Host $RepoName -NoNewline -ForegroundColor Green | |
| Write-Host " : " -NoNewline | |
| Write-Host $BranchName -NoNewline -ForegroundColor Blue | |
| Write-Host " ]" | |
| } | |
| function Update-Initialize { | |
| <# | |
| .SYNOPSIS | |
| *.sln 파일이 있는 솔루션 폴더 기준 Initialize | |
| #> | |
| # Update recently | |
| if ([string]::IsNullOrWhiteSpace($Branch)) { | |
| git pull | out-null | |
| } | |
| else { | |
| git switch $Branch | out-null | |
| git pull | out-null | |
| } | |
| } | |
| # Set locale | |
| $env:LC_ALL='C.UTF-8' | |
| [System.Console]::InputEncoding = [System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8 | |
| ## Main | |
| # 시작 tag(또는 commit) 없으면 종료 | |
| if ([string]::IsNullOrWhiteSpace($BeginCommitOrTag)) { | |
| Write-Error -Message "Please set begin commit or tag" -Category InvalidArgument | |
| Write-Error -Message "$ $($MyInvocation.MyCommand.Name) BEGIN_COMMIT_OR_TAG [END_COMMIT_OR_TAG] [BRANCH_NAME]" -Category InvalidArgument | |
| exit | |
| } | |
| # Script Path로부터 Script의 Directory로 분리한 뒤 RootPath 탐색 | |
| [String] $local:BasePath = Get-RootPath -BasePath (Split-Path $MyInvocation.MyCommand.Path) | |
| # *.sln 파일이 있는 BasePath를 찾지 못한 경우 종료 | |
| if ([string]::IsNullOrWhiteSpace($BasePath)) { | |
| Write-Error -Message "Solution file not found." -Category InvalidData | |
| exit | |
| } | |
| # Solution 폴더로 이동 | |
| Set-Location $BasePath | |
| Write-Host "# Build Version: $(git describe)" -ForegroundColor DarkYellow | |
| [String] $script:Begin = Get-TimestampBy -CommitOrTag $BeginCommitOrTag | |
| [String] $script:End = Get-TimestampBy -CommitOrTag $EndCommitOrTag | |
| # 시작 tag(또는 commit)의 Timestamp를 찾을 수 없는 경우 종료 | |
| if ([string]::IsNullOrWhiteSpace($Begin)) { | |
| Write-Error -Message "Invalid begin tag or commit hash." -Category InvalidData | |
| exit | |
| } | |
| # Solution 폴더 기준 최신화(git pull) | |
| Update-Initialize | |
| # Log 탐색해서 출력 부 | |
| Write-LogCurrently -BranchName $Branch | |
| Get-SubModules | ForEach-Object { Write-LogRecursively -SubmoduleName $_ } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
powershell .\changelog_generator.ps1 FROM_TAG TO_TAG BRANCHexample1:
powershell .\changelog_generator.ps1 1.0example2:
powershell .\changelog_generator.ps1 1.0 1.1example3:
powershell .\changelog_generator.ps1 1.0 1.1 develop