GitBones.psm1
class GitBonesTemplate { [string] hidden $BonesURL = 'https://gitlab.com/GitBones/gitbones/raw/master/templates/templates.json' ## Name of the GitBones Template [string] $Name ## The HTTPS URL of the GitBones Template [string] $URL ## Short description of the repository [string] $Description ## The group that is managing the repository of the URL [string] $Maintainer ## The original Author of the repository [string] $Author ## The identified Git Host Server (e.g. GitLab, GitHub, Bitbucket) ## if repository is built off of specific Git Host service [string] $GitHost ## The specific CI tool being used for the repository [string] $CI ## The general topic of the template [string] $Topic ## The specific programming language or code-base of the repository [string] $Language ## Informs if the repository has submodules in it [bool] $Submodules GitBonesTemplate ( [string]$Name, [string]$URL, [string]$Description, [string]$Maintainer, [string]$Author, [string]$GitHost, [string]$CI, [string]$Topic, [string]$Language, [bool]$Submodules ) { $this.Name =$Name $this.URL = $URL $this.Description = $Description $this.Maintainer = $Maintainer $this.Author = $Author $this.GitHost = $GitHost $this.CI = $CI $this.Topic = $Topic $this.Language = $Language $this.Submodules = $Submodules } GitBonesTemplate([string]$Name) { $Response = invoke-restmethod -uri $this.BonesURL -Method Get $Result = $Response.Projects | Where-Object -Property Name -LIKE $Name $this.Name = $Result[0].Name $this.URL = $Result[0].URL $this.Description = $Result[0].Description $this.Maintainer = $Result[0].Maintainer $this.Author = $Result[0].Author $this.GitHost = $Result[0].GitHost $this.CI = $Result[0].CI $this.Topic = $Result[0].Topic $this.Language = $Result[0].Language $this.Submodules = $Result[0].Submodules } [void]CreateRepository([string]$NewGitRepoUri) { [string]$TemplateToClone = $this.URL Write-Host "Starting GitBones build for template $TemplateToClone" $RepositoryName = $($NewGitRepoUri.Split('/')[-1]) -replace ".git", "" if(test-path ./$RepositoryName -ErrorAction SilentlyContinue){ Write-Error "Directory $RepositoryName already exists. Please ensure directory named $RepositoryName is not in the present working directory." -ErrorAction Stop }# end if Write-Host "Creating git project directory $RepositoryName in present working directory" $ParentDirectory = (Get-Item -Path ".\").FullName try{ New-Item -ItemType Directory -Name $RepositoryName -ErrorAction Stop Write-Host "git project directory $RepositoryName created..." Write-Host "Starting copy of $TemplateToClone into $RepositoryName directory..." git clone $TemplateToClone ./$RepositoryName --quiet ## verify that no errors occurred during clone if(!($?)){ Write-Error "git clone process failed for $TemplateToClone." -ErrorAction Stop }# end if ## verify that the clone created the directory and sanitize it if(test-path ./$RepositoryName/.git -ErrorAction SilentlyContinue){ Write-Host "$TemplateToClone successfully copied" Write-Host "Sanitizing GitBones template..." Remove-Item -Path ./$RepositoryName/.git -Recurse -Force } else { ## there was some error with cloning and throw terminating error Write-Error "$TemplateToClone failed to copy" -ErrorAction Stop } Write-Host "Initializing new git project..." Set-Location $RepositoryName -ErrorAction Stop git init --quiet ## check to ensure git init worked if(!($?)){ Write-Error "Git init failure" -ErrorAction Stop }# end if Write-Host "Setting repository $RepositoryName remote origin to $NewGitRepoUri" git remote add origin $NewGitRepoUri if(!($?)){ Write-Error "Failed adding remote origin for git project" -ErrorAction Stop }# end if Set-Location $ParentDirectory Write-Host "GitBones successful created template $TemplateToClone for $RepositoryName." -ForegroundColor Green } catch { ## Failure to clone project, roll back all changes Set-Location $ParentDirectory ## if directory for project was created, delete it rolling back if(test-path ./$RepositoryName -ErrorAction SilentlyContinue){ Remove-Item -Path ./$RepositoryName -Recurse -Force } Write-Error "$_" -ErrorAction Stop }# end try-catch }# end method }# end class GitBonesTemplate function Invoke-GitInstall { PARAM() BEGIN { [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; }# end BEGIN PROCESS { if(-NOT(Test-GitApp)){ ## heavily pulled from https://github.com/tomlarse/Install-Git/blob/master/Install-Git/Install-Git.ps1 ## only run if on a Windows OS if (Test-WindowsOS){ $gitExePath = "$env:ProgramFiles\Git\bin\git.exe" foreach ($asset in (Invoke-RestMethod https://api.github.com/repos/git-for-windows/git/releases/latest).assets) { if ($asset.name -match 'Git-\d*\.\d*\.\d*.\d*-64-bit\.exe') { $dlurl = $asset.browser_download_url } }# end foreach if (!(Test-Path $gitExePath -ErrorAction SilentlyContinue)) { Remove-Item -Force $env:TEMP\git-stable.exe -ErrorAction SilentlyContinue }# end if try{ Invoke-WebRequest -Uri $dlurl -OutFile $env:TEMP\git-stable.exe -ErrorAction Stop } catch{ Write-Error "Failed to download git.exe" -ErrorAction Stop }# end try-catch try { Start-Process -Wait $env:TEMP\git-stable.exe -ArgumentList /silent -ErrorAction Stop Write-Host "Installation complete!" -ForegroundColor Green } catch{ Write-Error "Failed to install git.exe" -ErrorAction Stop }# end try-catch } else{ Write-Host "This script is currently only supported on the Windows operating system." Write-Host "If running Linux, use packagement solution to install." Write-Host "If running MacOS, use brew and using Xcode command line tools run 'git --version' and you should be prompted to install." } } else { Write-Host "Git correctly installed" } }# end PROCESS END {}# end END }# end Invoke-GitInstall Export-ModuleMember -Function Invoke-GitInstall function Get-GitBonesTemplate { <# .Synopsis Retrieves all supported GitBones Templates .DESCRIPTION Retrieves a full or filtered list of GitBones Templates. The templates provded by GitBones are searchable by GitBones Template URI, Name, Topic, Author, or Language. The Git-GitBonesTemplate can use the simplified alias of BonesList to quickly query available templates. Use this function to discover GitBones templates to build your projects with quickstarts and skeleton directories available. .EXAMPLE Get-GitBonesTemplate -GitBonesUri 'https://gitlab.com/git-templates/default.git' .EXAMPLE BonesList -Bones 'https://gitlab.com/git-templates/default.git' .EXAMPLE Get-GitBonesTemplate -Topic 'CloudFormation' .EXAMPLE BonesList -Topic 'CloudFormation' .EXAMPLE Get-GitBonesTemplate -Author 'AWS' .EXAMPLE BonesList -Author 'AWS' .EXAMPLE Get-GitBonesTemplate -Language 'PowerShell' .EXAMPLE BonesList -Application 'PowerShell' #> [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')] [Alias('BonesList')] Param( # The GitBones Template HTTPS URL hosted on GitBones [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=0)] [Alias("Bones")] [string]$GitBonesUri, # Filter results based on GitBones Name keyword or phrase [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=1)] [string]$Name, # Filter results based on GitBones Topic keyword or phrase [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=2)] [string]$Topic, # Filter results based on GitBones Author keyword or phrase [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=3)] [string]$Author, # Filter results based on GitBones programming Language keyword or phrase [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=4)] [string]$Language )# end params BEGIN { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Test-GitBonesConnection ## current location for the template master catalog $BonesURL = 'https://gitlab.com/GitBones/gitbones/raw/master/templates/templates.json' $Response = invoke-restmethod -uri $BonesURL -Method Get }# end BEGIN PROCESS{ if($Response.Projects.Count -GE 1){ $Result = $Response.Projects ## filter based on supplied URL if($GitBonesUri){ $Result = $Result | Where-Object -Property URL -LIKE $GitBonesUri }# end if GitBonesUri if($Name){ $Result = $Result | Where-Object -Property Name -LIKE "*$Name*" }# end if GitBonesUri ## filter based on supplied topic if($Topic){ $Result = $Result | Where-Object -Property Topic -LIKE "*$Topic*" }#enf if Topic ## filter based on supplied Author if($Author){ $Result = $Result | Where-Object -Property Author -LIKE "*$Author*" }# end if Author ## filter based on supplied programming language if($Language){ $Result = $Result | Where-Object -Property Language -LIKE "*$Language*" }#enf if application } else { Write-Error "GitBones connection is not returning queries at this time." -ErrorAction Stop }# end else-if }# end PROCESS END{ return $Result }# end END }# end Get-GitBonesTemplate Export-ModuleMember -Function Get-GitBonesTemplate -Alias BonesList function New-GitBonesRepo { <# .Synopsis Creates a git repository skeleton directory based on GitBones or user templates. .DESCRIPTION Creates a git project skeleton directory based on GitBones or user specified templates. Users are able to leverage the GitBones Template library via BoneList command or supply their own git project URI to clone their own git skeleton projects. Access to projects to GitBones is based on HTTPS and all projects are open to the public. User template access is reliant on the user having access to their specified templates through typical git clone process and supports both HTTPS and SSH. If using SSH or HTTPS, user will be prompted to authenticate if required. If access is denied, user should verify their permissions. .EXAMPLE New-GitBonesRepo -GitRepoUri 'git@gitlab.com:rolston/test.git' ` -GitBonesName 'GitLab-CloudFormation' Creates a project test in the present working directory using the GitBones Template GitLab-CloudFormation .EXAMPLE BonesInit -GitRepoUri 'git@gitlab.com:rolston/test.git' ` -GitBonesName 'GitLab-CloudFormation' Example of using alias BonesInit to create a project titled test in the present working directory using the GitBones Template GitLab-CloudFormation and with a target user Git Project using HTTPS as remote origin .EXAMPLE BonesInit -GitRepoUri 'https://gitlab.com/rolston/test.git' ` -Bones 'Gitlab-CloudFormation' Using simplified BonesInit alias and Bones parameter to create a project using a GitBones template GitLab-CloudFormation with a target user Git Project using HTTPS as remote origin. .EXAMPLE BonesInit -GitRepoUri 'git@gitlab.com:rolston/test.git' ` -UserTemplate 'git@gitlab.com:rolston/mytemplate.git' Using the user specified template, create a skeleton git project from the bones of the template "mytemplate.git" .EXAMPLE New-GitBonesRepo -GitRepoUri 'git@gitlab.com:rolston/test.git' ` -UserTemplate 'git@gitlab.com:rolston/mytemplate.git' Using the user specified template with SSH, create a skeleton git project from the bones of the template "mytemplate.git" .EXAMPLE New-GitBonesRepo -GitRepoUri 'git@gitlab.com:rolston/test.git' ` -UserTemplate 'https://gitlab.com/rolston/mytemplate.git' Using the user specified template with HTTPS, create a skeleton git project from the bones of the template "mytemplate.git" #> [CmdletBinding(SupportsShouldProcess=$true, DefaultParameterSetName='GitBones', ConfirmImpact='Medium')] [Alias('BonesInit')] Param( # Git Project SSH or HTTPS URL for new project [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateNotNullOrEmpty()] [Alias("p")] [string] $GitRepoUri, # The GitBones Project Name [Parameter(Mandatory=$false, ValueFromPipeline=$false, Position=1, ParameterSetName='GitBones')] [ValidateNotNullOrEmpty()] [Alias("Bones", "b")] [string] $GitBonesName, # The User Template Project URI [Parameter(Mandatory=$false, ValueFromPipeline=$false, Position=1, ParameterSetName='UserTemplate')] [ValidateNotNullOrEmpty()] [string] $UserTemplateUri ) BEGIN { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $GitBonesUri = 'https://gitlab.com/GitBones/gitbones/raw/master/templates/templates.json' if(!(Test-GitInstallation)){ Write-Error "Missing git installation requirements" -ErrorAction Stop }# end if }# end BEGIN PROCESS{ if($GitBonesName) { if ((Invoke-WebRequest -Uri $GitBonesUri -ErrorAction SilentlyContinue -UseBasicParsing).StatusCode -EQ 200) { Write-Verbose "connection succeeded to bones template $GitBonesUri" } else { Write-Verbose "connection failed to bones template $GitBonesUri" Write-Error "Bones Template network connection fail: $GitBonesUri" -ErrorAction Stop } [GitBonesTemplate]$GitBonesResult = [GitBonesTemplate]::new($GitBonesName) if($GitBonesResult.URL){ $GitBonesResult.CreateRepository($GitRepoUri) } else { Write-Error "No Bones Project Template found. Check the name of the Bone Project Template" -ErrorAction Stop } }# end if GitBonesName if($UserTemplateURI){ [GitBonesTemplate]$GitTemplate = [GitBonesTemplate]::new( ` 'Custom User Template', ` $UserTemplateURI, ` 'Custom User Template', ` $env:UserName, ` $env:UserName, ` 'User defined', ` 'User defined', ` 'User defined', ` 'User defined', ` $false ) $GitTemplate.CreateRepository($GitRepoUri) }# end if UserTemplateURI }# end PROCESS END{ }# end END }# end New-GitBonesRepo Export-ModuleMember -Function New-GitBonesRepo -Alias BonesInit function Set-GitPath { <# .Synopsis Sets the path for Windows OS for Git.exe installations. Note this script requires an elevated session (runas admin). .DESCRIPTION Sets the path for Windows OS Git.exe installations looking at $env:PATH checking for "$env:ProgramFiles\Git\cmd" to be in the path. This functions requires the session to be running under elevated privileges. .EXAMPLE Set-Path #> [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')] PARAM() if (Test-WindowsOS){ ## verify git is installed prior to setting path if(Test-GitApp){ ## git is installed, test if path is set in system path if(!(Test-GitPath)){ if(Test-IsAdmin){ $GitPath = "$env:ProgramFiles\Git\cmd" [Environment]::SetEnvironmentVariable("Path", $env:Path + ";$GitPath", [EnvironmentVariableTarget]::Machine) } else { Write-Warning "To set path you will need to run session as admin" Write-Warning "Path not set for Git installation" } } else { Write-Host "Git Path already set" } } else { Write-Warning "Cannot set path until Git is installed. Please run Invoke-GitInstall" } }# end if Windows OS else { Write-Host "Set-GitPath is only applicable to Windows OS." } }# end Set-GitPath Export-ModuleMember -Function Set-GitPath function Test-GitApp { [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')] PARAM() # Tests the Installation of Git if (Test-WindowsOS){ Write-Verbose "System identified as Windows OS." $GitPath = "$env:ProgramFiles\Git\cmd" if(!(Test-Path -Path "$GitPath\git.exe" -ErrorAction SilentlyContinue)){ return $false } else { return $true }# end if }# end if IsWindows else { ## leverage command -v to see if git is installed on Linux or Mac if(!(Invoke-Command -scriptblock {command -v git} -ErrorAction SilentlyContinue)){ return $false } else { return $true } }# end elseif Linux or Mac OS }# end Test-GitApp function Test-GitBonesConnection { [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')] PARAM() $GitBonesUri = 'https://gitlab.com/GitBones/gitbones/raw/master/templates/templates.json' if ((Invoke-WebRequest -Uri $GitBonesUri -ErrorAction SilentlyContinue -UseBasicParsing).StatusCode -EQ 200) { write-verbose "connection succeeded to bones template $GitBonesUri" } else { write-verbose "connection failed to bones template $GitBonesUri" Write-Error "Bones Template network connection fail: $GitBonesUri" -ErrorAction Stop } }# end Test-GitBonesConnection function Test-GitPath { ## Only for Windows do we need to check [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')] PARAM() ## run only on Windows OS if (Test-WindowsOS){ $GitPath = "$env:ProgramFiles\Git\cmd" if(($env:Path).Contains($GitPath)){ return $true } else { return $false }# end if env:Path } else { ## system in either Linux or Mac ## and path is not an issue return $true }# end if-else }# end Test-GitPath function Test-GitInstallation { BEGIN {}# end BEGIN PROCESS { if(!(Test-GitApp)) { Write-Warning "Git application not installed, please run Invoke-GitInstall to setup Git.exe" return $false }# end if if(!(Test-GitPath)){ if(Test-WindowOS){ Write-Warning "Git application not found under env:PATH, please run Set-GitPath to complete Git configuration" return $false } } return $true }# end PROCESS END {}# end END }# end Test-GitInstallation function Test-IsAdmin { ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") }# end Test-IsAdmin function Test-WindowsOS { if ((!($IsLinux) -AND (!($IsMacOS)))){ return $true } else { return $false }# end if-else }# end Test-WindowsOS |