Public/Invoke-GitOpen.ps1
<#
.SYNOPSIS Opens up a browser window to the git repository's remote .DESCRIPTION When executed from in a git repository, will open up a web browser to the repository's remote configuration. This allows for easy and seamless transition between local work and remote work - managing pull requests, issues, and general code management stuff. .PARAMETER PR Switch to open up the remote config pull request screen .PARAMETER CustomRepoTypes This array allows for some customization. In a lot of enterprise settings, a custom URL is used for the source control management system. An array of repo types that can be used to find & replace values in the .gitconfig. Each object in the array should include these properties: Name: The name of the custom config Type: "BitBucket" or "Github" Find: String to look for in the .gitconfig to determine whether repo is this type Replace: *OPTIONAL* when finding the string, optional ability to replace Example: @{ Name = 'BitBucketCustom' Type = 'BitBucket' Find = 'ssh://git@git.companyname.com:7999' Replace = 'https://git.companyname.com' } .EXAMPLE PS C:\SomeGitRepo> Invoke-GitOpen Will open up a web browser to the "SomeGitRepo" remote. .EXAMPLE PS C:\SomeGitRepo> $companyRepoType = @{ Name = 'BitBucketCustom' Type = 'BitBucket' Find = 'ssh://git@git.companyname.com:7999' Replace = 'https://git.companyname.com' } PS C:\SomeGitRepo> Invoke-GitOpen -CustomRepoTypes @($companyRepoType) My company uses SSH for git operations. This configuration will find the ssh configuration for my company repositories and then replace that ssh remote configuration with the https remote URL. #> function Invoke-GitOpen { [CmdletBinding()] param( # open the pull request page [Parameter()] [Switch]$PR, [Parameter()] [Array]$CustomRepoTypes ) # TO DO # Make this more dynamic. We should be able to find this # if the shell is in a repo $configPath = './.git/config' <# DEBUG $urlRaw = 'url = ssh://git@git.companyname.com:7999/bbproject/bbrepo.git' $urlRaw = 'url = https://github.com/nhudacin/git-open.git' #> # pull the url out of the .gitconfig, clean it up a little $urlRaw = Get-Content -Path $configPath | Where-Object { $_ -match 'url =' } | Select-Object -First 1 if ($urlRaw -match '(?<=url = )(.*)(?=\.git)' ) { $sanitizedUrl = $Matches[1] } # gotta stop here if we didn't snag a url if (-not $sanitizedUrl) { throw 'Couldn''t get a url from the git config' } # get the repo name # sanitizedUrl = ssh://git@git.companyname.com:7999/bbproject/bbrepo # --------------------------------------------------------------^ $repoName = Split-Path -Leaf $sanitizedUrl # we need the Github Organization || BitBucket Project # sanitizedUrl = ssh://git@git.companyname.com:7999/bbproject/bbrepo # ------------------------------------------------------^ $repoParent = Split-Path -Leaf $(Split-Path -Parent $sanitizedUrl) <# TO DO: Move this hostname section to it's own function The Find & Replace functionality inside $customRepoTypes must be run in oder to find the correct hostname/url $sanitizedURL can be changed during this process! At the end of this block --> we should also know the $repoType in order to construct the url query #> # get the host name # take into consideration the requirement to support custom urls [array]$repoTypes = Get-DefaultRepoTypes if ($customRepoTypes) { # TO DO: Validate input foreach ($customDataType in $customRepoTypes) { $repoTypes += $customRepoTypes } } # find the url type & run any customizations foreach($repoType in $repoTypes) { if ($sanitizedUrl.Contains($repoType.Find)) { if ($repoType.Replace) { $sanitizedUrl = $sanitizedUrl.Replace($repoType.Find,$repoType.Replace) } break } # no repoType found. do NOT be fooled with $repoType being populated $repoType = $null } # FINALLY - get the repoUrlBase $repoUrlBase = $sanitizedUrl.Remove($sanitizedUrl.IndexOf("/$repoParent/$repoName")).TrimEnd('/') # now that we know all of the parts, it's time to re-assemble them depending on the # repo type. $formattedUrlBase = switch($repoType.Type) { 'BitBucket' { "$repoUrlBase/projects/$repoParent/repos/$repoName" } default { "$repoUrlBase/$repoParent/$repoName" } } # PR is easy! no more processing needed if ($PR) { # stupid var name - I've been burned in posh using "special" variable names like $args $startArgz = switch($repoType.Type) { 'BitBucket' { "$formattedUrlBase/pull-requests" } default { "$formattedUrlBase/pulls" } } } # TO DO: # add issues $startAgz # if we don't have the args set then we have a little more digging to do # get the branch and open up to the branch tree if (-not $startArgz) { # get the ref (current branch) <# DEBUG $ref = "ref: refs/heads/nuix_develop" #> $ref = Get-Content -Path $(Join-Path $(Split-Path -Parent $configPath) 'HEAD') # will be in this format: # ref: refs/heads/nuix_develop # # grab the branch (end) $branchName = $ref.Substring($ref.LastIndexOf('/') + 1) $startArgz = switch($repoType.Type) { 'BitBucket' { "$formattedUrlBase/browse?at=refs%2Fheads%2F$branchName" } default { "$formattedUrlBase/tree/$branchName" } } } # open 'er up! Start-Process $startArgz } |