Daha Fazla Git PowerShell Aracı Oluşturma
PowerShell kullanarak git boyutlandırma aracı oluşturmaya ilişkin son makalelerime büyük ilgi gördüm. Birçoğunuz anlattığım yolculuğun varış noktası kadar önemli olduğunu anlayacak kadar bilgiliydiniz. Bunu aklımda tutarak geçen yıl hakkında yazdığım PowerShell ve git ile ilgili başka bir projeyi tekrar gözden geçirmeye karar verdim. Git yapılandırmanızın nesne sürümünü yazmak için bir PowerShell işlevi oluşturdum. Bir komut dosyası olarak ortaya çıkan bu işlev, git config -global -list gibi bir komutun etrafındaki süslü bir sarmalayıcıdan başka bir şey değildir. Bunun dışında metinle uğraşmak yerine boru hattında nesnelerim var. Her neyse, son makaleden öğrendiğim bazı bilgilere ve kullandığım bazı tekniklere dayanarak kodu tekrar gözden geçirip güncellemeye karar verdim.
Özel Tür Ekleme
PowerShell işlevinin özü, bir git config komutunu çalıştırmak ve yapılandırılmış verileri bir nesneye ayrıştırmaktır. Önceki işlev, ardışık düzene genel bir özel nesne yazıyordu. Ancak yazı tipi adını nesneyle tanımlayabildiğim teknikten yararlanmaya karar verdim.
foreach ($line in $data) {
$split = $line.split("=")
#split the first element again to get the category and name
$sub = $split[0].split(".")
[PSCustomObject]@{
PSTypeName = 'gitConfig'
Scope = $scope
Category = $sub[0]
Name = $sub[1]
Setting = $split[1]
Username = $env:username
Computername = $env:COMPUTERNAME
}
} #foreach line
Git yapılandırmasındaki her satır 'gitConfig' türünde özel bir nesneye dönüştürülecektir. Bunu yaparken kullanıcı adı ve bilgisayar adı için ek parametreler eklemeye karar verdim. Amaç, komutu yerel olarak çalıştırmak olsa da, veriler serileştirilmişse veya bir dosyaya kaydedilmişse, bunun nereden geldiğini bilmek faydalı olabilir. Kendi PowerShell araçlarınızı oluştururken her zaman sonuçların nasıl kullanılabileceğini ve hatta nerede tüketilebileceğini düşünmeniz gerekir.
gitConfig Türünü genişletme
Artık kendi tür adına sahip özel bir nesnem var. Varsayılan olarak tüm özellikleri alacağım. Ama bunu gerçekten istemiyorum. Varsayılan olarak Kullanıcı Adı ve Bilgisayar Adı özelliklerini görmem gerekmiyor. Çözüm, geçen sefer yaptığım gibi, Update-TypeData'yı kullanarak varsayılan bir özellik seti tanımlamaktır.
Update-TypeData -TypeName 'gitConfig' -DefaultDisplayPropertySet 'Scope', 'Category', 'Name', 'Setting' -force
İhtiyacım olursa ek özellikler orada.
Özel nesnemi daha çok PowerShell'e benzeyecek şekilde oluşturduğumdan beri 'git-ness'inin bir kısmını kaybedebilir. Örneğin, özel nesnede Kategori ve Ayar gibi özellik adlarını kullanıyorum. Ancak git dünyasında, yapılandırma dosyasının bu bölümlerine muhtemelen Bölüm ve Değer adı verilir. Sonucu daha git dostu hale getirmek için yapabileceğim şeylerden biri Kategori ve Ayar için takma ad özellikleri oluşturmaktır.
Update-TypeData -TypeName 'gitConfig' -MemberType AliasProperty -MemberName 'Value' -Value 'Setting' -force
Update-TypeData -TypeName 'gitConfig' -MemberType AliasProperty -MemberName 'Section' -Value 'Category' -force
Varsayılan ekran bile takma adları kullanmaz; ancak kesinlikle kullanabilir; kullanıcı takma adların mevcut olduğunu biliyorsa bunları kullanabilir.
Git sürümünü göstermek için özel bir tür uzantısı da ekledim.
Update-TypeData -TypeName 'gitConfig' -MemberType ScriptProperty -MemberName gitVersion -value {git --version} -force
Get-Member bu özelliklerin tümünü görüntüler.
PowerShell Kodu
Komut dosyasının bu sürümünü GitHub'da yayınladım.
Get-GitConfig.ps1:
#requires -version 5.1
Function Get-GitConfig {
<#
.SYNOPSIS
Get git configuration settings
.DESCRIPTION
Git stores configurations settings in a simple text file format. Fortunately, this file is structured and predictable. This command will process git configuration information into PowerShell friendly output.
.PARAMETER Scope
Possible values are Global,Local or System
.PARAMETER Path
Enter the path to a .gitconfig file. You can use shell paths like ~\.gitconfig
.EXAMPLE
PS C:\> Get-GitConfig
Scope Category Name Setting
----- -------- ---- -------
global filter lfs git-lfs clean -- %f
global filter lfs git-lfs smudge -- %f
global filter lfs true
global user name Art Deco
global user email artd@company.com
global gui recentrepo C:/Scripts/Gen2Tools
global gui recentrepo C:/Scripts/PSVirtualBox
global gui recentrepo C:/Scripts/FormatFunctions
global core editor powershell_ise.exe
global core autocrlf true
global core excludesfile ~/.gitignore
global push default simple
global color ui true
global alias logd log --oneline --graph --decorate
global alias last log -1 HEAD
global alias pushdev !git checkout master && git merge dev && git push && git checkout dev
global alias st status
global alias fp !git fetch && git pull
global merge tool kdiff3
global mergetool kdiff3 'C:/Program Files/KDiff3/kdiff3.exe' $BASE $LOCAL $REMOTE -o $MERGED
Getting global configuration settings
.EXAMPLE
PS C:\> Get-GitConfig -scope system | where category -eq 'filter'
Scope Category Name Setting
----- -------- ---- -------
system filter lfs git-lfs clean -- %f
system filter lfs git-lfs smudge -- %f
system filter lfs git-lfs filter-process
system filter lfs true
Get system configuration and only git filters.
.EXAMPLE
PS S:\PSScriptTools> Get-GitConfig local
Scope Category Name Setting
----- -------- ---- -------
local core repositoryformatversion 0
local core filemode false
local core bare false
local core logallrefupdates true
local core symlinks false
local core ignorecase true
local remote origin https://github.com/jdhitsolutions/PSScriptTools.git
local remote origin +refs/heads/*:refs/remotes/origin/*
local branch master origin
local branch master refs/heads/master
Get the git configuration from a local repository.
.EXAMPLE
PS C:\> Get-GitConfig -path ~\.gitconfig | format-table -groupby category -property Name,Setting
Get settings from a configuration file and present in a grouped, formatted table.
.INPUTS
none
.OUTPUTS
[gitConfig]
.NOTES
The command assumes you have git installed. Otherwise, why would you be using this?
Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
Last updated: 1 February, 2019
.LINK
git
#>
[CmdletBinding(DefaultParameterSetName = "default")]
[OutputType("gitConfig")]
[Alias("ggc")]
Param (
[Parameter(Position = 0, ParameterSetName = "default")]
[ValidateSet("Global", "System", "Local")]
[string[]]$Scope = "Global",
[Parameter(ParameterSetName = "file")]
#the path to a .gitconfig file which must be specified if scope if File
[ValidateScript( {Test-Path $_})]
[Alias("config")]
[string]$Path
)
Begin {
Write-Verbose "Starting $($myinvocation.MyCommand)"
if ($path) {
#convert path value to a complete file system path
$Path = Convert-Path -Path $path
}
#internal helper function
function _process {
[cmdletbinding()]
Param(
[scriptblock]$scriptblock,
[string]$Scope
)
Write-Verbose "Invoking $($scriptblock.tostring())"
#invoke the scriptblock and save the text output
$data = Invoke-Command -scriptblock $scriptblock
#split each line of the config on the = sign
#and add to the hashtable
foreach ($line in $data) {
$split = $line.split("=")
#split the first element again to get the category and name
$sub = $split[0].split(".")
[PSCustomObject]@{
PSTypeName = 'gitConfig'
Scope = $scope
Category = $sub[0]
Name = $sub[1]
Setting = $split[1]
Username = $env:username
Computername = $env:COMPUTERNAME
}
} #foreach line
} # _process
} #begin
Process {
if ($PSCmdlet.ParameterSetName -eq 'file') {
Write-Verbose "Getting config from $path"
$get = [scriptblock]::Create("git config --file $path --list")
#call the helper function
_process -scriptblock $get -scope "File"
}
else {
foreach ($item in $Scope) {
Write-Verbose "Getting $item config"
#the git command is case sensitive so make the scope lower case
$item = $item.tolower()
#create a scriptblock to run git config
$get = [scriptblock]::Create("git config --$item --list")
#call the helper function
_process -scriptblock $get -Scope $item
} #foreach scope
} #else
} #process
End {
Write-Verbose "Ending $($myinvocation.MyCommand)"
} #end
} #end Get-GitConfig
#define a default set of properties to the custom gitConfig type
Update-TypeData -TypeName 'gitConfig' -DefaultDisplayPropertySet 'Scope', 'Category', 'Name', 'Setting' -force
#define some alias properties that might be more 'git-like'
Update-TypeData -TypeName 'gitConfig' -MemberType AliasProperty -MemberName 'Value' -Value 'Setting' -force
Update-TypeData -TypeName 'gitConfig' -MemberType AliasProperty -MemberName 'Section' -Value 'Category' -force
#add a custom property
Update-TypeData -TypeName 'gitConfig' -MemberType ScriptProperty -MemberName gitVersion -value {git --version} -forceParametre bildiriminin hemen öncesine bakarsanız, çıktı tipini özel tip adımla tanımladığımı görebilirsiniz. Bunu [gitConfig] gibi parantez içine alırsanız PowerShell kayıtlı bir tür arayıp şikayette bulunmaya çalışabilir. Bir dize kullanın. Zaten bunların hepsi belgeleme amaçlıdır. Ayrıca işlevin bir parçası olarak ggc takma adını da tanımlıyorum. Bu şekilde Set-Alias veya New-Alias'ı çalıştırmak için kod eklemem gerekmiyor.
Dikkat çekmek istediğim diğer husus ise dahili ve özel bir “yardımcı” fonksiyonunun kullanılmasıdır. Bu işlev, kullanıcıya gösterilmediğinden standart bir Fiil-İsim adı kullanmaz. Bu, parametre setine bağlı olarak çağrılabilen bir kod bloğudur. İstemediğim şey kod parçalarının iki kopyası. Bu sadece kodu biraz daha kullanışsız hale getirmekle kalmıyor, aynı zamanda kodu belirli yerlerde tutmam gerekiyor. Özel bir işlevle modülerleştirme süreci basitleştirir ve eğer bir Pester testi oluşturuyor olsaydım test edilmesi de daha kolay olurdu.
Git Config'i PowerShell Yoluyla Alma
PS1 dosyasına nokta kaynak sağladıktan sonra git yapılandırmamı çeşitli şekillerde görüntülememe olanak tanıyan yeni bir komutum var.
Aynı bilgilerin çoğunu görüntülemek için hala git komut satırı aracını kullanabileceğinizin farkındayım. Ancak bunu PowerShell'e dönüştürdüğümde, bunun etrafında şu şekilde ek araçlar oluşturabilirim:
#dot source the required function
. C:\scripts\Get-Gitconfig.ps1
$data = Get-GitConfig -Scope Global,System
$frags = @("<H1>Git Configuration</H1>")
$frags+= $data[0] | Select-object "Computername","Username"| ConvertTo-Html -Fragment
$data | Group-Object -Property Scope | ForEach-Object {
$frags += "<H2>$($_.name.toupper())</H2>"
$frags+= $_.group | Sort-Object Category |
Select-Object -Property Category,Name,Setting | ConvertTo-Html -Fragment
}
$head = @"
<Title> git Configuration</Title>
<style>
body { background-color:#FFFFFF;
font-family:Monospace;
font-size:10pt; }
td, th { border:0px solid black;
border-collapse:collapse;
white-space:pre;
font-size:12pt; }
th { color:white;
background-color:black; }
table, tr, td, th { padding: 0px; margin: 0px ;white-space:pre; }
tr:nth-child(odd) {background-color: lightgray}
table { margin-left:10px; }
h2 {
font-family:Tahoma;
}
</style>
"@
ConvertTo-Html -Body $frags -Head $head -PostContent "<h4>$($data[0].gitversion)</h4>"| Out-File mygit.html -Encoding ascii
Bu, git yapılandırmamın bir html raporunu oluşturacaktır. Git'i yüklediyseniz, onu da çalıştırabilmeniz gerekir.
Umarım bu yolculuğu bilgilendirici bulmuşumdur. Her ne kadar öğrenmenin en iyi yolu yaparak olsa da. Umarım kodumu alırsınız, bunları komut dosyası düzenleyicinizde açarsınız ve nasıl çalıştıklarını görürsünüz. Onlara bir şans ver. Ne olacağını görmek için onları değiştirin. İyi eğlenceler. Bu şekilde öğrenirsiniz.