Private/Read-ProjectVersion.ps1

<#
.SYNOPSIS
    Reads the version from a project's native file.
.DESCRIPTION
    Extracts the current version from the appropriate ecosystem file.
    Supports .psd1 (PowerShell), .csproj (.NET), package.json (Node), pyproject.toml (Python), and git tags.
.PARAMETER Path
    Project directory. Defaults to current directory.
.PARAMETER ProjectType
    Override auto-detection by specifying the project type.
.OUTPUTS
    [PSCustomObject] with Version, Parsed, ProjectType, and File properties.
#>

function Read-ProjectVersion {
    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    param(
        [Parameter()]
        [string]$Path = (Get-Location).Path,

        [Parameter()]
        [PSCustomObject]$ProjectType
    )

    if (-not $ProjectType) {
        $ProjectType = Get-ProjectType -Path $Path
    }

    $version = $null

    switch ($ProjectType.Type) {
        'PowerShell' {
            $manifest = Import-PowerShellDataFile -Path $ProjectType.File
            $version = $manifest.ModuleVersion
        }
        'DotNet' {
            [xml]$csproj = Get-Content -Path $ProjectType.File -Raw
            $version = $csproj.Project.PropertyGroup.Version |
                Where-Object { $_ } |
                Select-Object -First 1
            if (-not $version) {
                $version = $csproj.Project.PropertyGroup.PackageVersion |
                    Where-Object { $_ } |
                    Select-Object -First 1
            }
        }
        'Node' {
            $pkg = Get-Content -Path $ProjectType.File -Raw | ConvertFrom-Json
            $version = $pkg.version
        }
        'Python' {
            $content = Get-Content -Path $ProjectType.File -Raw
            if ($content -match 'version\s*=\s*"([^"]+)"') {
                $version = $Matches[1]
            }
        }
        'GitTag' {
            $version = Get-LatestGitTag
            if ($version) {
                $version = $version -replace '^v', ''
            }
        }
        default {
            throw "Cannot read version: unknown project type '$($ProjectType.Type)'"
        }
    }

    if (-not $version) {
        throw "No version found in $($ProjectType.File ?? $ProjectType.Type)"
    }

    $parsed = Get-SemanticVersion -Version $version

    return [PSCustomObject]@{
        Version     = $version
        Parsed      = $parsed
        ProjectType = $ProjectType
        File        = $ProjectType.File
    }
}