Netscoot.Core/Public/Move-PowerShell.ps1

function Move-PowerShell {
    <#
    .SYNOPSIS
        Move a PowerShell item and reconcile references, routing by type to the right
        specialist. The front door for PowerShell moves.
 
    .DESCRIPTION
        Dispatches a PowerShell item to the right specialist by type (see Output for the routing):
        the script specialist fixes dot-source/call references (AST-based), the module specialist
        fixes the paths that load the module. -WhatIf/-Confirm/-Verbose propagate to the specialist,
        -Force is forwarded, and -RepositoryRoot is forwarded to the script specialist (the module
        specialist has no RepositoryRoot).
 
    .PARAMETER Path
        The PowerShell item to move: a .ps1 script, a .psd1 manifest, or a module folder.
        Accepts a path string or a Get-ChildItem/Get-Item item from the pipeline, and rejects other
        object types.
 
    .PARAMETER Destination
        New path (file or folder), following `git mv` rules, and passed through to the specialist.
 
    .PARAMETER RepositoryRoot
        Repository root scanned for referencing scripts. Defaults to the enclosing git repository root.
        Forwarded to the script specialist only (the module specialist has no RepositoryRoot).
 
    .PARAMETER Force
        When git is not installed, move with a plain PowerShell `Move-Item` without asking first.
        Without -Force it asks before falling back. The plain move does not preserve git history.
 
    .PARAMETER NoJournal
        Skip recording this move in the undo journal for this call (forwarded to the specialist),
        even when journaling is enabled.
 
    .OUTPUTS
        The result object from the PowerShell specialist it routes to, by item type.
 
    .EXAMPLE
        # A .ps1 routes to the script mover (fixes dot-source/call references)
        Move-PowerShell -Path ./lib/helpers.ps1 -Destination ./shared/helpers.ps1 -WhatIf
        # A module folder (or its .psd1) routes to the module mover (fixes the paths that load it)
        Move-PowerShell -Path ./tools/Mayo -Destination ./modules/Mayo
        # Destination is an existing folder -> the script lands at ./shared/helpers.ps1
        Move-PowerShell -Path ./lib/helpers.ps1 -Destination ./shared
    #>


    # SupportsShouldProcess so -WhatIf/-Confirm bind and propagate to the specialist; this
    # dispatcher only routes (the specialist calls ShouldProcess), so suppress the rule here.
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '', Justification = 'Delegates to a specialist cmdlet that calls ShouldProcess')]
    [CmdletBinding(SupportsShouldProcess)]
    [OutputType('Netscoot.ScriptMoveResult', 'Netscoot.PSModuleMoveResult')]
    param(
        [Parameter(Mandatory, Position = 0, ValueFromPipeline)]
        [Netscoot.PathInputTransform()]
        [ValidateNotNullOrEmpty()]
        [string]$Path,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Destination,

        [string]$RepositoryRoot,
        [switch]$Force,
        [switch]$NoJournal
    )

    process {
        $full = Resolve-FullPath $Path
        if (-not (Test-Path -LiteralPath $full)) {
            $PSCmdlet.WriteError([System.Management.Automation.ErrorRecord]::new(
                    [System.IO.FileNotFoundException]::new("Path not found: $Path"),
                    'PathNotFound', [System.Management.Automation.ErrorCategory]::ObjectNotFound, $Path))
            return
        }

        $isContainer = Test-Path -LiteralPath $full -PathType Container
        $ext = ([System.IO.Path]::GetExtension($full)).ToLowerInvariant()

        if (-not $isContainer -and $ext -eq '.ps1') {
            # Move-PowerShellScript takes -Path.
            $fwd = New-ForwardArgs $PSBoundParameters -Add @{ Path = $full }
            Write-Verbose 'Routing .ps1 -> Move-PowerShellScript'
            Move-PowerShellScript @fwd
        }
        elseif ($isContainer -or $ext -eq '.psd1') {
            # Move-PowerShellModule takes -ModulePath and does not accept RepositoryRoot.
            $fwd = New-ForwardArgs $PSBoundParameters -Drop 'Path', 'RepositoryRoot' -Add @{ ModulePath = $full }
            Write-Verbose 'Routing module -> Move-PowerShellModule'
            Move-PowerShellModule @fwd
        }
        else {
            $PSCmdlet.WriteError([System.Management.Automation.ErrorRecord]::new(
                    [System.NotSupportedException]::new("Not a PowerShell item: $Path. Expected a .ps1 script, a .psd1 manifest, or a module folder."),
                    'NotAPowerShellItem', [System.Management.Automation.ErrorCategory]::InvalidArgument, $Path))
        }
    }
}