Private/_MainFunctions.ps1

function Set-Colour(
    [string]$value
) {
    if ($value -eq "False") { 
        return "White" 
    } 
    elseif ($value -eq "Error") {
        return "Red"
    }
    elseif ($value -eq "Optional") {
        return "Magenta"
    }
    else { return "Green" }
}

function Install-XrmModule {
    $moduleName = "Microsoft.Xrm.Data.Powershell"
    $moduleVersion = "2.8.8"
    $module = Get-Module -ListAvailable -Name $moduleName
    if (!($module.Version -ge $moduleVersion )) {
        Write-host "Module $moduleName version $moduleVersion or higher not found, installing now"
        Install-Module -Name $moduleName -MinimumVersion $moduleVersion -Force -Scope CurrentUser
    }
    else {
        Write-host "Module $moduleName Found"
    }
}

function Install-PowerAppsAdmin {
    $moduleName = "Microsoft.PowerApps.Administration.PowerShell"
    $moduleVersion = "2.0.66"
    $module = Get-Module -ListAvailable -Name $moduleName
    if (!($module.Version -ge $moduleVersion )) {
        Write-host "Module $moduleName version $moduleVersion or higher not found, installing now"
        Install-Module -Name $moduleName -MinimumVersion $moduleVersion -Force -AllowClobber
    }
    else {
        Write-host "Module $moduleName version $moduleVersion or higher Found"
    }
}

function Install-PowerAppsPowerShell {
    $moduleName = "Microsoft.PowerApps.PowerShell"
    $moduleVersion = "1.0.13"
    $module = Get-Module -ListAvailable -Name $moduleName
    if (!($module.Version -ge $moduleVersion )) {
        Write-host "Module $moduleName version $moduleVersion or higher not found, installing now"
        Install-Module -Name $moduleName -MinimumVersion $moduleVersion -Force -AllowClobber
    }
    else {
        Write-host "Module $moduleName Found"
    }
}

function Install-XrmToolingPowerShell {
    $moduleName = "Microsoft.Xrm.Tooling.CrmConnector.PowerShell"
    $moduleVersion = "3.3.0.899"
    $module = Get-Module -ListAvailable -Name $moduleName
    if (!($module.Version -ge $moduleVersion )) {
        Write-host "Module $moduleName version $moduleVersion or higher not found, installing now"
        Install-Module -Name $moduleName -MinimumVersion $moduleVersion -Force -AllowClobber
    }
    else {
        Write-host "Module $moduleName Found"
        Import-Module -Name $moduleName -MinimumVersion $moduleVersion -Force
    }
}

function Format-Json {
    <#
  .SYNOPSIS
      Prettifies JSON output.
  .DESCRIPTION
      Reformats a JSON string so the output looks better than what ConvertTo-Json outputs.
  .PARAMETER Json
      Required: [string] The JSON text to prettify.
  .PARAMETER Minify
      Optional: Returns the json string compressed.
  .PARAMETER Indentation
      Optional: The number of spaces (1..1024) to use for indentation. Defaults to 4.
  .PARAMETER AsArray
      Optional: If set, the output will be in the form of a string array, otherwise a single string is output.
  .EXAMPLE
      $json | ConvertTo-Json | Format-Json -Indentation 2
  #>

    [CmdletBinding(DefaultParameterSetName = 'Prettify')]
    Param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
        [string]$Json,

        [Parameter(ParameterSetName = 'Minify')]
        [switch]$Minify,

        [Parameter(ParameterSetName = 'Prettify')]
        [ValidateRange(1, 1024)]
        [int]$Indentation = 4,

        [Parameter(ParameterSetName = 'Prettify')]
        [switch]$AsArray
    )

    if ($PSCmdlet.ParameterSetName -eq 'Minify') {
        return ($Json | ConvertFrom-Json) | ConvertTo-Json -Depth 100 -Compress
    }

    # If the input JSON text has been created with ConvertTo-Json -Compress
    # then we first need to reconvert it without compression
    if ($Json -notmatch '\r?\n') {
        $Json = ($Json | ConvertFrom-Json) | ConvertTo-Json -Depth 100
    }

    $indent = 0
    $regexUnlessQuoted = '(?=([^"]*"[^"]*")*[^"]*$)'

    $result = $Json -split '\r?\n' |
    ForEach-Object {
        # If the line contains a ] or } character,
        # we need to decrement the indentation level unless it is inside quotes.
        if ($_ -match "[}\]]$regexUnlessQuoted") {
            $indent = [Math]::Max($indent - $Indentation, 0)
        }

        # Replace all colon-space combinations by ": " unless it is inside quotes.
        $line = (' ' * $indent) + ($_.TrimStart() -replace ":\s+$regexUnlessQuoted", ': ')

        # If the line contains a [ or { character,
        # we need to increment the indentation level unless it is inside quotes.
        if ($_ -match "[\{\[]$regexUnlessQuoted") {
            $indent += $Indentation
        }

        $line
    }

    if ($AsArray) { return $result }
    return $result -Join [Environment]::NewLine
}

Function Invoke-Menu() {    
    Param(
        [Parameter(Mandatory = $True)][String]$MenuTitle,
        [Parameter(Mandatory = $True)][array]$MenuOptions
    )
    $MaxValue = $MenuOptions.count - 1
    $Selection = 0
    $EnterPressed = $False
    
    Clear-Host

    While ($EnterPressed -eq $False) { 
        Write-Host "$MenuTitle"
        For ($i = 0; $i -le $MaxValue; $i++) {            
            If ($i -eq $Selection) {
                Write-Host -BackgroundColor Cyan -ForegroundColor Black "[ $($MenuOptions[$i]) ]"
            }
            Else {
                Write-Host " $($MenuOptions[$i]) "
            }
        }
        $KeyInput = $host.ui.rawui.readkey("NoEcho,IncludeKeyDown").virtualkeycode
        Switch ($KeyInput) {
            13 {
                $EnterPressed = $True
                Return $Selection
                Clear-Host
                break
            }
            38 {
                If ($Selection -eq 0) {
                    $Selection = $MaxValue
                }
                Else {
                    $Selection -= 1
                }
                Clear-Host
                break
            }
            40 {
                If ($Selection -eq $MaxValue) {
                    $Selection = 0
                }
                Else {
                    $Selection += 1
                }
                Clear-Host
                break
            }
            Default {
                Clear-Host
            }
        }
    }
}

function Copy-GitRepoFromTemplate {
    Write-Host "Select a folder to create a new git Repository for your Power Platform Project"
    try {
        $application = New-Object -ComObject Shell.Application
        $path = ($application.BrowseForFolder(0, 'Select a folder', 0)).Self.Path
    
        if (!(Test-Path -Path "$path\$gitRepo") -and !($null -eq $path)) {
            Write-Host "Creating Project Folder"
            New-Item -Path $path -Name $gitRepo -ItemType Directory
            $global:projectFile.ProjectLocation = "$path\$gitRepo" 
            $global:projectFile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.Devops\$global:gitRepo\$global:gitRepo.json")
            Set-Location -Path "$path\$gitRepo"   
    
            $message = "Setting up PowerPlatformCICD locally"
            Write-Host $message
    
            Remove-Item -Path (Join-Path $PSScriptRoot ..\FrameworkTemplate\node_modules) -Recurse -Force -ErrorAction SilentlyContinue  
            Copy-Item -Path (Join-Path $PSScriptRoot ..\FrameworkTemplate\*) -Destination $path\$gitRepo\ -Recurse -Force
        
            $message = "Confirming Git User Details"
            Write-Host $message
    
            $GitUser = git config --global user.name
            $GitEmail = git config --global user.email
    
            If ($null -eq $GitUser) {
                $GitUser = Read-Host "Enter your name (to use when committing changes to Git)"
                git config --global user.name $GitUser
            }
    
            If ($null -eq $GitEmail) {
                $GitEmail = Read-Host "Enter your email address (to use when committing changes to Git)"
                git config --global user.email $GitEmail
            }  
    
            Remove-Item .git -Recurse -Force -ErrorAction SilentlyContinue
    
            git init

            Write-Host "Updating Build.yaml ..."
            (Get-Content -Path $path\$gitRepo\build.yaml) -replace "replaceRepo", $gitRepo | Set-Content -Path $path\$gitRepo\build.yaml

            Write-Host "Rename PowerPlatformDevOps.sln to $gitRepo.sln"
            Rename-Item -Path $path\$gitRepo\PowerPlatformDevOps.sln -NewName "$gitRepo.sln"
    
        }
        else {
            Write-Warning "The Path $path\$gitRepo already exists, please select a different path or project name"
            $continue = Read-Host -Prompt "Press [Enter] to Continue or [Q] to Quit"
            if (!$continue -eq 'Q') {
            }
        } 
    }
    catch {
    
    }
}
function Add-GitRepo {
    do {
        $gitRepo = Read-Host -Prompt "Please enter a Name for the Git Repository you wish to Create"
    }until ($gitRepo -ne "")
    $global:gitRepo = $gitRepo
    if (!(Test-Path $env:APPDATA\Microsoft.PowerPlatform.DevOps)) {
        New-Item -Path $env:APPDATA\Microsoft.PowerPlatform.Devops -ItemType Directory
    }
    if (!(Test-Path $env:APPDATA\Microsoft.PowerPlatform.DevOps\$gitRepo)) {
        New-Item -Path $env:APPDATA\Microsoft.PowerPlatform.Devops\$gitRepo -ItemType Directory
        Copy-Item -Path (Join-Path $PSScriptRoot emptyProject.json) -Destination $env:APPDATA\Microsoft.PowerPlatform.Devops\$gitRepo\$gitRepo.json
        $global:projectFile = Get-Content ("$env:APPDATA\Microsoft.PowerPlatform.Devops\$gitRepo\$gitRepo.json") | ConvertFrom-Json 
        $global:projectFile.gitRepo = $gitRepo
        $global:projectFile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.Devops\$gitRepo\$gitRepo.json")
        if ($global:configfile.Projects[0].ID -eq "placeholder") {
            $global:configfile.Projects[0].ID = "0"
            $global:configfile.Projects[0].Name = $gitRepo
            $global:configfile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json")
        }
        else {
            $newProject = @([ordered]@{ID = $global:configfile.Projects.Count; Name = $gitRepo; })
            $global:configfile.Projects += $newProject
            $global:configfile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json")
        }
        Copy-GitRepoFromTemplate
        pause
    }
    else {
        Write-Host "You already have a repo called $gitRepo, please select a different name"
        $gitRepo = ""
        Add-GitRepo
    }
}

function Select-GitRepo {
    $options = $global:configfile.Projects | ForEach-Object { "$($_.Name)" }

    do {
        $sel = Invoke-Menu -MenuTitle "---- Please Select your Project ------" -MenuOptions $options
        $selectedRepo = $global:configfile.Projects[$sel].Name
    } until ($selectedRepo -ne "")
    $global:projectFile = Get-Content ("$env:APPDATA\Microsoft.PowerPlatform.Devops\$selectedRepo\$selectedRepo.json") | ConvertFrom-Json 
    Set-Location $global:projectFile.ProjectLocation
    $global:projectTitle = $global:projectFile.gitRepo
    $global:message = @"
 
Welcome to the Power Platform DevOps configuration script.
 
 ver: $global:version
 project: $global:projectTitle
 
"@


}