Public/Invoke-MkLicense.ps1

function Invoke-MkLicense {
    <#
    .SYNOPSIS
    Creates a complete LICENSE file from a bundled SPDX template.

    .DESCRIPTION
    Generates complete MIT, Apache-2.0, or GPL-3.0-only license text from
    templates pinned to SPDX License List v3.28.0. MIT substitutes the requested
    copyright owner and year. Existing files are not overwritten unless -Force
    is used.

    .PARAMETER Type
    License type to generate. GPL-3.0 is retained as a compatibility spelling
    for the precise GPL-3.0-only SPDX identifier.

    .PARAMETER Force
    Overwrites LICENSE if it already exists.

    .PARAMETER Owner
    MIT copyright owner. Defaults to the current operating-system user.

    .PARAMETER Year
    MIT four-digit copyright year. Defaults to the current year.

    .EXAMPLE
    mklicense -Type MIT
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    [OutputType([System.IO.FileInfo])]
    [Alias('mklicense')]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateSet('MIT', 'Apache-2.0', 'GPL-3.0', 'GPL-3.0-only')]
        [string]$Type,

        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [ValidateScript({
            if ($_ -match '[\r\n]') {
                throw 'Owner must be a single-line value.'
            }
            $true
        })]
        [string]$Owner = [System.Environment]::UserName,

        [Parameter()]
        [ValidateRange(1970, 9999)]
        [int]$Year = (Get-Date).Year,

        [switch]$Force
    )

    $path = Join-Path -Path (Get-Location) -ChildPath 'LICENSE'
    $moduleRoot = Split-Path -Path $PSScriptRoot -Parent
    $templateRoot = Join-Path -Path $moduleRoot -ChildPath 'LicenseTemplates'
    $templateName = switch ($Type) {
        'MIT' { 'MIT.txt' }
        'Apache-2.0' { 'Apache-2.0.txt' }
        default { 'GPL-3.0-only.txt' }
    }
    $templatePath = Join-Path -Path $templateRoot -ChildPath $templateName
    if (-not (Test-Path -LiteralPath $templatePath -PathType Leaf)) {
        throw "Bundled license template is missing: $templatePath"
    }

    if (-not $PSCmdlet.ShouldProcess($path, "Write $Type license")) {
        return
    }

    $content = [System.IO.File]::ReadAllText($templatePath).TrimEnd("`r", "`n")
    if ($Type -eq 'MIT') {
        $content = $content.Replace('<year>', $Year.ToString())
        $content = $content.Replace('<copyright holders>', $Owner)
    }

    Set-DtFileContent -Path $path -Content $content -Force:$Force -Confirm:$false | Out-Null

    if (Test-Path -LiteralPath $path) {
        [System.IO.FileInfo]::new($path)
    }
}