GitHelperUtil.psm1

#Region 'PREFIX' 0
$ModuleRoot = $MyInvocation.MyCommand.ScriptBlock.Module.ModuleBase
. $ModuleRoot\Scripts\PreLoad.ps1 -ModuleRoot $ModuleRoot
#EndRegion 'PREFIX'
#Region '.\Private\Get-ModuleVariable.ps1' 0
function Get-ModuleVariable {
     [CmdletBinding()]
     param(
        [string]$Name = (throw "The Name parameter is required"),
        [switch]$DoNotAllowEmpty,
        [switch]$AllowNotSet,
        [AllowNull()][Object]$DefaultValue,
     [string]$ErrorMessage = "The '$Name' variable is not set.")

    $var = Get-Variable -Name $Name -ErrorAction SilentlyContinue
    

    #Case 1: The variable does not exist and no default value was set
    if(-not $DefaultValue -and ((-not $var -and -not $AllowNotSet))) {
        throw $ErrorMessage
    }

    #Case 2: The variable exists, but it has no value
    if($var -and -not $var.Value -and $DoNotAllowEmpty) {
        throw "The '$Name' variable is set, but it has an empty or null value and the '-DoNotAllowEmpty' switch was specified"
    }
    
    #Case 3: The variable does not exist, and the default was specified
    if($DefaultValue -and (-not $var -or -not $var.Value)) {
        Set-ModuleVariable -Name $Name -Value $DefaultValue -PassThru
    } else {
        $var.Value
    }
}
#EndRegion '.\Private\Get-ModuleVariable.ps1' 29
#Region '.\Private\Set-ModuleVariable.ps1' 0
function Set-ModuleVariable {
    [CmdletBinding(SupportsShouldProcess=$False)]
    param(
            
            [string]$Name,
            [object]$Value,
            [switch]$PassThru)

    Set-Variable -Force:$true -Name $Name -Value $Value -Visibility Public -Scope Script -WhatIf:$false
    if($PassThru) {
        $Value
    }

}
#EndRegion '.\Private\Set-ModuleVariable.ps1' 14
#Region '.\Public\Get-CodeChurn.ps1' 0
function Get-CodeChurn {
    param([string]$RepoDir,
        [string]$After,
        [string]$Before,
        [string]$GitArgs
    )
    <#
            .SYNOPSIS
            Get the code churn (number of time a file has been modified) for all files in a Git repository
 
            .PARAMETER RepoDir
            The repository location
 
            .PARAMETER After
            Optional parameter to specify to only look at code after a specified date (i.e. "after 2 months ago" or "1/1/2001")
 
             
            .PARAMETER Before
            Optional parameter to specify to only look at code before a specified date (i.e. "before 2 months ago" or "1/1/2001")
 
             
            .PARAMETER GitArgs
            Optional parameter to specify any additional arguments to pass to the "git log" command
 
 
    #>
   
    if($After) {
        $afterArg = "--after='$After'"
    }
    if($Before) {
        $beforeArg = "--before='$Before'"
    }
    
    
    Invoke-GitCommand -Command "log --all -M -C --name-only --format='format:' $afterArg $beforeArg $GitArgs" -RepoDir $RepoDir | group-object | foreach {
        if($_.Name) {        
            [PSCustomObject]@{
                TimesModified = $_.Count;
                FileName = $_.Name
            }
        }
    }
}
#EndRegion '.\Public\Get-CodeChurn.ps1' 43
#Region '.\Public\Install-ChocoPackage.ps1' 0
function Install-ChocoPackage {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$PackageId,
        [string]$ChocoArgs,
        [ValidateSet('upgrade','install')]
        [string]$InstallType = 'upgrade',
        [string]$Source
    )
    
    if($Source) {
        $Source = "-source $Source"
    }
    
    $chocoCmd = "choco.exe $InstallType $PackageId -y $Source $ChocoArgs"
    Invoke-Expression $chocoCmd
    if($LASTEXITCODE) {
        throw "Failed to install chocolatey package '$PackageId'"
    }
}
#EndRegion '.\Public\Install-ChocoPackage.ps1' 21
#Region '.\Public\Install-GitCommandline.ps1' 0
function Install-GitCommandline {
    [CmdletBinding()]
    param()
    $gitCmd = Get-Command git -ErrorAction SilentlyContinue
    if(-not $gitCmd) {
        Install-ChocoPackage -PackageId 'git.commandline' -ChocoArgs '--force'

        $gitCmd = Get-Command git
    }
    
    return $gitCmd.Path
}
#EndRegion '.\Public\Install-GitCommandline.ps1' 12
#Region '.\Public\Invoke-GitCommand.ps1' 0
function Invoke-GitCommand {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$Command, 
        [AllowNull()][int[]]$AllowedExitCodes,
        [AllowNull()][string]$RepoDir
    )
    

    $gitPath = Install-GitCommandline
    if(-not ($Command.Trim().ToLower().StartsWith('git'))) {
        $Command = ". `"$gitPath`" $Command"
    }
    Write-Host -fore green $Command
    try{
        if($RepoDir) {
            Push-Location -LiteralPath $RepoDir
        }
        $origPref = $ErrorActionPreference
        $ErrorActionPreference = 'continue'
        $result = ''
        Invoke-Expression -Command $Command -Verbose -ErrorVariable erroroutput  -ErrorAction SilentlyContinue -OutVariable output 2>&1 | Tee-Object -Variable result 
    } finally {
        
        if($RepoDir) {
            Pop-Location
        }
        $ErrorActionPreference = $origPref
        if($LASTEXITCODE -and $AllowedExitCodes -notcontains $LASTEXITCODE) {
            Write-Error ('LASTEXITCODE: ' + $LASTEXITCODE + ([Environment]::Newline) + $erroroutput + ([Environment]::Newline) + $result)
        }
        
    }
}
#EndRegion '.\Public\Invoke-GitCommand.ps1' 35
#Region '.\Public\New-GitHubRepository.ps1' 0
Function New-GitHubRepository {
  [cmdletbinding(SupportsShouldProcess)]

  Param(
    [Parameter(Position = 0, Mandatory, HelpMessage = "Enter the new repository name")]
    [ValidateNotNullorEmpty()]
    [string]$Name,

    [string]$Description,

    [switch]$Private,
    [switch]$NoWiki,
    [switch]$NoIssues,
    [switch]$NoDownloads,
    [switch]$AutoInitialize,

    #license templates found at https://github.com/github/choosealicense.com/tree/gh-pages/_licenses
    [ValidateSet("MIT","apache-2.0","gpl-3.0","ms-pl","unlicense")]
    [string]$LicenseTemplate,

    [Alias("token")]
    [ValidateNotNullorEmpty()]
    [Parameter(Mandatory=$true, ParameterSetName='Token')]
    [string]$UserToken = $gitToken,
    [Parameter(Mandatory= $true, ParameterSetname='Username')]
    [string]$UserName,
    #write full native response to the pipeline
    [switch]$Raw
  )

  Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)"
  #display PSBoundparameters formatted nicely for Verbose output
  [string]$pb = ($PSBoundParameters | Format-Table -AutoSize | Out-String).TrimEnd()
  Write-Verbose "[BEGIN ] PSBoundparameters: `n$($pb.split("`n").Foreach({"$("`t"*2)$_"}) | Out-String) `n" 

  if(-not $UserToken -and $UserName) {

    if(-not $pass) {
      $securePass = Read-Host -Prompt Password -AsSecureString
      $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePass)
      $pass = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
    }
    $pair = "$($UserName):$($pass)"

    $bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
    $base64 = [System.Convert]::ToBase64String($bytes)

    $head = @{ Authorization = "Basic $base64" }

  } else {
    #create the header
    $head = @{
      Authorization = 'Basic ' + $UserToken
    }
  }



  #create a hashtable from properties
  $hash = @{
    name = $Name
    description = $Description
    private = $Private -as [boolean]
    has_wiki = (-Not $NoWiki)
    has_issues = (-Not $NoIssues)
    has_downloads = (-Not $NoDownloads)
    auto_init = $AutoInitialize -as [boolean]
  }

  if ($LicenseTemplate) {
    $hash.add("license_template",$LicenseTemplate)
  }

  $body = $hash | ConvertTo-Json

  Write-Verbose "[PROCESS] Sending json"
  Write-Verbose $body

  #define parameter hashtable for Invoke-RestMethod
  $paramHash = @{
    Uri = "https://api.github.com/user/repos" 
    Method = "Post"
    body = $body 
    ContentType = "application/json"
    Headers = $head
    UseBasicParsing = $True
    DisableKeepAlive = $True
  }

  #should process
  if ($PSCmdlet.ShouldProcess("$name [$description]")) {
    #Invoke the web-request
    [System.Net.ServicePointManager]::Expect100Continue = $true
    [System.Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    
    $r = Invoke-RestMethod @paramHash

    if ($r.id -AND $Raw) {
      Write-Verbose "[PROCESS] Raw result"
      $r

    } elseif ($r.id) {
      write-Verbose "[PROCESS] Formatted results"

      $r | Select-Object @{Name = "Name";Expression = {$_.name}},
      @{Name = "Description";Expression = {$_.description}},
      @{Name = "Private";Expression = {$_.private}},
      @{Name = "Issues";Expression = {$_.has_issues}},
      @{Name = "Wiki";Expression = {$_.has_wiki}},
      @{Name = "URL";Expression = {$_.html_url}},
      @{Name = "Clone";Expression = {$_.clone_url}}
    } else {
        
      Write-Warning "Something went wrong with this process"
    }

    if ($r.clone_url) {
      $msg = @"
 
To push an existing local repository to Github run these commands:
-> git remote add origin $($r.clone_url)"
-> git push -u origin master
 
"@

      Write-Host $msg -ForegroundColor Green

    }
  }

  Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)"

}
#EndRegion '.\Public\New-GitHubRepository.ps1' 132
#Region 'SUFFIX' 0
$ModuleRoot = $MyInvocation.MyCommand.ScriptBlock.Module.ModuleBase
. $ModuleRoot\Scripts\PostLoad.ps1 -ModuleRoot $ModuleRoot
#EndRegion 'SUFFIX'