Public/Install-CpmfUipsPackGitHook.ps1

function Install-CpmfUipsPackGitHook {
<#
.SYNOPSIS
    Installs a git pre-push hook that calls Invoke-CpmfUipsPack -UseWorktree
    automatically before every push.
 
.DESCRIPTION
    Writes a pre-push hook script to <RepoRoot>/.git/hooks/pre-push with
    LF line endings and no file extension (required by Git for Windows).
 
    The hook calls Invoke-CpmfUipsPack with -UseWorktree so it packs from a
    clean worktree, never touching the working directory.
 
    ProjectJson is written as an absolute path at install time. If you move
    or re-clone the repository, re-run Install-CpmfUipsPackGitHook.
 
.PARAMETER RepoRoot
    Root of the git repository. Defaults to the current directory.
 
.PARAMETER ProjectJson
    Absolute path to the UiPath project.json. Written verbatim into the hook.
 
.PARAMETER ModulePath
    Path to CpmfUipsPack.psd1. Written verbatim into the hook so the hook can
    Import-Module without relying on the user's PSModulePath. Defaults to
    the path of the currently loaded CpmfUipsPack module manifest.
 
.PARAMETER AdditionalArgs
    Extra arguments appended to the Invoke-CpmfUipsPack call in the hook,
    e.g. @('-SkipInstall', '-FeedPath', 'C:\myfeed').
 
.EXAMPLE
    Install-CpmfUipsPackGitHook `
        -RepoRoot 'C:\repos\MyProject' `
        -ProjectJson 'C:\repos\MyProject\project.json'
#>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        [string]  $RepoRoot       = (Get-Location).Path,
        [Parameter(Mandatory)]
        [string]  $ProjectJson,
        [string]  $ModulePath     = (Get-Module CpmfUipsPack | Select-Object -ExpandProperty Path),
        [string[]]$AdditionalArgs = @()
    )

    Set-StrictMode -Version Latest
    $ErrorActionPreference = 'Stop'

    $ProjectJson = (Resolve-Path $ProjectJson).Path
    $RepoRoot    = (Resolve-Path $RepoRoot).Path
    $hooksDir    = Join-Path $RepoRoot '.git\hooks'
    $hookFile    = Join-Path $hooksDir 'pre-push'

    if (-not (Test-Path $hooksDir)) {
        throw "'$hooksDir' not found — is '$RepoRoot' a git repository?"
    }

    if ([string]::IsNullOrEmpty($ModulePath)) {
        throw "CpmfUipsPack module is not loaded. Import-Module CpmfUipsPack before calling Install-CpmfUipsPackGitHook, or pass -ModulePath explicitly."
    }

    $extraArgs = if ($AdditionalArgs.Count -gt 0) {
        ' ' + ($AdditionalArgs | ForEach-Object { "'$_'" }) -join ' '
    } else { '' }

    # Hook content — must use LF line endings; shebang required by Git for Windows bash
    $hookContent = @"
#!/bin/sh
# Auto-generated by Install-CpmfUipsPackGitHook (CpmfUipsPack module)
# Re-run Install-CpmfUipsPackGitHook if the repo or project is moved.
pwsh -NonInteractive -Command "
Import-Module '$ModulePath' -ErrorAction Stop
Invoke-CpmfUipsPack ``
    -ProjectJson '$ProjectJson' ``
    -UseWorktree$extraArgs
"
"@


    # Normalise to LF
    $hookContent = $hookContent -replace "`r`n", "`n" -replace "`r", "`n"

    if ($PSCmdlet.ShouldProcess($hookFile, 'Write pre-push hook')) {
        [System.IO.File]::WriteAllText($hookFile, $hookContent, (New-Object System.Text.UTF8Encoding $false))
        Write-Verbose "[Hook] Installed pre-push hook at $hookFile"
        Write-Verbose "[Hook] ProjectJson : $ProjectJson"
        Write-Verbose "[Hook] Module : $ModulePath"
    }
}