PSDependScripts/Git.ps1
<# .SYNOPSIS Clone a git repository .DESCRIPTION Clone a git repository Note: We require git.exe in your path Relevant Dependency metadata: DependencyName (Key): Git URL You can override this with the 'Name'. If you specify only an Account/Repository, we assume GitHub is the source Name: Optional override for the Git URL, same rules as DependencyName (key) Version: Used with git checkout. Specify a branch name, commit hash, or tags/<tag name>, for example. Defaults to master Target: Path to clone this repository. e.g C:\Temp would result in C:\Temp\RepoName. Defaults to nothing (current path/repo name) AddToPath: Prepend the Target to ENV:PATH and ENV:PSModulePath .PARAMETER Force If specified and target does not exist, create directory tree up to the target folder .PARAMETER PSDependAction Test, Install, or Import the module. Defaults to Install Test: Return true or false on whether the dependency is in place (Note: Currently only checks if path exists) Install: Install the dependency Import: Import the dependency 'Target'. Override with ImportPath .PARAMETER ImportPath If specified with PSDependAction Import, we import this path, instead of Target, the default .EXAMPLE @{ 'buildhelpers' = @{ Name = 'https://github.com/RamblingCookieMonster/BuildHelpers.git' Version = 'd32a9495c39046c851ceccfb7b1a85b17d5be051' Target = 'C:\git' } } # Full syntax # DependencyName (key) uses (unique) name 'buildhelpers' # Override DependencyName as URL the name https://github.com/RamblingCookieMonster/BuildHelpers.git # Specify a commit to checkout (version) # Clone in C:\git .EXAMPLE @{ 'ramblingcookiemonster/PSDeploy' = 'master' 'ramblingcookiemonster/BuildHelpers' = 'd32a9495c39046c851ceccfb7b1a85b17d5be051' } # Simple syntax # First example shows cloning PSDeploy from ramblingcookiemonster's GitHub account # Second example shows clonging PSDeploy from ramblingcookiemonster's GitHub account and checking out a specific commit # Both are cloned to the current path (e.g. .\<repo name>) # This syntax assumes GitHub as a source. The right hand side is the version (branch, commit, tags/<tag name>, etc. #> [cmdletbinding()] param( [PSTypeName('PSDepend.Dependency')] [psobject[]]$Dependency, [switch]$Force, [ValidateSet('Test', 'Install')] [string[]]$PSDependAction = @('Install'), [string]$ImportPath ) # Extract data from Dependency $DependencyName = $Dependency.DependencyName $Name = $Dependency.Name if(-not $Name) { $Name = $DependencyName } #Name is in account/repo format, default to GitHub as source #This likely needs work, and will need to change if GitHub changes valid characters for usernames if($Name -match "^[a-zA-Z0-9]+/[a-zA-Z0-9_-]+$") { $Name = "https://github.com/$Name.git" } $GitName = $Name.trimend('/').split('/')[-1] -replace "\.git$", '' $Target = $Dependency.Target if(-not $Target) { $Target = $PWD.Path } $RepoPath = Join-Path $Target $GitName $GottaInstall = $True if(-not (Test-Path $Target) -and $PSDependAction -contains 'Install') { Write-Verbose "Creating folder [$Target] for git dependency [$Name]" $null = mkdir $Target -Force } if(-not (Test-Path $RepoPath)) { # Nothing found, return test output if( $PSDependAction -contains 'Test' -and $PSDependAction.count -eq 1) { return $False } } else # Target exists { $GottaTest = $True } if(-not (Get-Command git.exe -ErrorAction SilentlyContinue)) { Write-Error "Git dependency type requires git.exe. Ensure this is in your path, or explicitly specified in $ModuleRoot\PSDepend.Config's GitPath. Skipping [$DependencyName]" } $Version = $Dependency.Version if(-not $Version) { $Version = 'master' } if($GottaTest) { Push-Location Set-Location $RepoPath $Branch = Invoke-ExternalCommand git -Arguments (echo rev-parse --abbrev-ref HEAD) -Passthru $Commit = Invoke-ExternalCommand git -Arguments (echo rev-parse HEAD) -Passthru Pop-Location if($Version -eq $Branch -or $Version -eq $Commit) { Write-Verbose "[$RepoPath] exists and is already at version [$Version]" if($PSDependAction -contains 'Test' -and $PSDependAction.count -eq 1) { return $true } $GottaInstall = $False } elseif($PSDependAction -contains 'Test' -and $PSDependAction.count -eq 1) { Write-Verbose "[$RepoPath] exists and is at branch [$Branch], commit [$Commit].`nWe don't currently support moving to the requested version [$Version]" return $false } else { Write-Verbose "[$RepoPath] exists and is at branch [$Branch], commit [$Commit].`nWe don't currently support moving to the requested version [$Version]" $GottaInstall = $False } } if($PSDependAction -notcontains 'Install') { return } if($GottaInstall) { Push-Location Set-Location $Target Write-Verbose -Message "Cloning dependency [$Name] with git from [$($Target)]" Invoke-ExternalCommand git 'clone', $Name #TODO: Should we do a fetch, once existing repo is found? Set-Location $RepoPath Write-Verbose -Message "Checking out [$Version] of [$Name] from [$RepoPath]" Invoke-ExternalCommand git 'checkout', $Version Pop-Location } if($Dependency.AddToPath) { Write-Verbose "Setting PSModulePath to`n$($Target, $env:PSModulePath -join ';' | Out-String)" Add-ToItemCollection -Reference Env:\PSModulePath -Item $Target Write-Verbose "Setting PATH to`n$($RepoPath, $env:PATH -join ';' | Out-String)" Add-ToItemCollection -Reference Env:\Path -Item $Target } $ToImport = $Target if($ImportPath) { $ToImport = $ImportPath } Import-PSDependModule $ToImport |