FileSystemHelpers.psm1

function GetTempPath {
    [System.IO.Path]::GetTempPath()
}


function ResolveFullPath {
    param ([string]$Path)
    if ($Path -notlike "*$([System.IO.Path]::DirectorySeparatorChar)*") {
        $Path = Join-Path -Path (Get-Location).Path -ChildPath $Path
    }
    $Path
}

function TestDirectoryExists {
    param ([string]$Path)
    if ([System.IO.Directory]::Exists($Path)) {
        throw "A directory exists at the path '$Path'."
    }
}


function TestFileExists {
    param ([string]$Path)
    if ([System.IO.File]::Exists($Path)) {
        throw "A file exists at the path '$Path'."
    }
}


function TestPathExists {
    param ([string]$Path)
    TestFileExists -Path $Path
    TestDirectoryExists -Path $Path
}


function Get-TempPath {
    $tempPath = GetTempPath
    if ([String]::IsNullOrEmpty($tempPath)) {
        throw [System.IO.FileNotFoundException]::new('The temporary path returned by [System.IO.Path]::GetTempPath() is empty.')
    }
    $tempPath
}


function New-File {
    [CmdletBinding(SupportsShouldProcess)]
    [Alias('touch')]
    param (
        [ValidateScript({
            $_path = ResolveFullPath -Path $_
            -not(TestPathExists -Path $_path)
        })]
        [Parameter(ValueFromPipeline=$true)]
        [string[]] $Path
    )

    process {
        foreach ($p in $Path) {
            $_p = ResolveFullPath -Path $p

            if ($PSCmdlet.ShouldProcess($_p)) {
                New-Item -Path $_p -ItemType 'File' -WhatIf:$WhatIfPreference
            }
        }
    }
}


function New-TempDirectory {
    [CmdletBinding(SupportsShouldProcess)]
    param ()
    $tempPath = New-TempPath
    if ($PSCmdlet.ShouldProcess($tempPath)) {
        New-Item -Path $tempPath -ItemType 'Directory' -WhatIf:$WhatIfPreference
    }
}


function New-TempFile {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$Extension
    )
    $tempPath = New-TempPath -Extension $Extension
    if ($PSCmdlet.ShouldProcess($tempPath)) {
        New-Item -Path $tempPath -ItemType 'File' -WhatIf:$WhatIfPreference
    }
}


function New-TempPath {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
    param (
        [string]$Extension
    )
    do {
        if ([System.String]::IsNullOrWhiteSpace($Extension)) {
            $name = (New-Guid).Guid
        } else {
            $name = '{0}.{1}' -f (New-Guid).Guid, $Extension
        }
        $tempPath = [System.IO.Path]::Combine((Get-TempPath), $name)
    } while (Test-Path -Path $tempPath)
    $tempPath
}