99 lines
4.8 KiB
PowerShell
99 lines
4.8 KiB
PowerShell
param(
|
|
[Parameter(Mandatory = $true)][string]$RepoRoot,
|
|
[Parameter(Mandatory = $true)][string]$OutputRoot
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$repo = (Resolve-Path $RepoRoot).Path
|
|
$assetFiles = @(Get-ChildItem (Join-Path $repo "companion") -Filter project.assets.json -File -Recurse -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.FullName -notmatch '[\\/]installer[\\/]output[\\/]' })
|
|
if ($assetFiles.Count -eq 0) { throw "No restored NuGet project.assets.json files were found after publish." }
|
|
|
|
Remove-Item $OutputRoot -Recurse -Force -ErrorAction SilentlyContinue
|
|
New-Item -ItemType Directory -Force -Path $OutputRoot | Out-Null
|
|
|
|
|
|
function Get-ChildText([System.Xml.XmlNode]$Node, [string]$Name) {
|
|
if (!$Node) { return $null }
|
|
$child = $Node.SelectSingleNode("*[local-name()='$Name']")
|
|
if (!$child) { return $null }
|
|
return $child.InnerText.Trim()
|
|
}
|
|
|
|
$packages = @{}
|
|
foreach ($assetFile in $assetFiles) {
|
|
$assets = Get-Content $assetFile.FullName -Raw | ConvertFrom-Json
|
|
$packageFolders = @($assets.packageFolders.PSObject.Properties.Name)
|
|
foreach ($libraryProperty in $assets.libraries.PSObject.Properties) {
|
|
if ($libraryProperty.Value.type -ne "package") { continue }
|
|
$parts = $libraryProperty.Name -split '/', 2
|
|
if ($parts.Count -ne 2) { continue }
|
|
$id = $parts[0]
|
|
$version = $parts[1]
|
|
$key = "$($id.ToLowerInvariant())/$($version.ToLowerInvariant())"
|
|
if ($packages.ContainsKey($key)) { continue }
|
|
|
|
$packageRoot = $null
|
|
foreach ($folder in $packageFolders) {
|
|
$candidate = Join-Path $folder ($key -replace '/', [IO.Path]::DirectorySeparatorChar)
|
|
if (Test-Path $candidate) { $packageRoot = (Resolve-Path $candidate).Path; break }
|
|
}
|
|
if (!$packageRoot) { throw "Restored package files are missing for $id $version." }
|
|
$packages[$key] = [ordered]@{ Id = $id; Version = $version; Root = $packageRoot }
|
|
}
|
|
}
|
|
|
|
$inventory = [Collections.Generic.List[string]]::new()
|
|
$inventory.Add("LUMI COMPANION - EXACT NUGET PACKAGE LICENCE INVENTORY")
|
|
$inventory.Add("Generated: $([DateTime]::UtcNow.ToString('yyyy-MM-dd HH:mm:ss')) UTC")
|
|
$inventory.Add("")
|
|
$inventory.Add("This file is generated from the restored project.assets.json files used by the Companion build. Package-specific licence, notice, copying, and copyright files found in the restored packages are copied into the adjacent package directories.")
|
|
$inventory.Add("")
|
|
|
|
foreach ($package in @($packages.Values | Sort-Object Id, Version)) {
|
|
$safeName = ("$($package.Id)-$($package.Version)" -replace '[^A-Za-z0-9._-]', '_')
|
|
$packageOutput = Join-Path $OutputRoot $safeName
|
|
New-Item -ItemType Directory -Force -Path $packageOutput | Out-Null
|
|
|
|
$nuspec = Get-ChildItem $package.Root -Filter *.nuspec -File | Select-Object -First 1
|
|
$metadata = $null
|
|
if ($nuspec) {
|
|
[xml]$nuspecXml = Get-Content $nuspec.FullName -Raw
|
|
$metadata = $nuspecXml.SelectSingleNode("/*[local-name()='package']/*[local-name()='metadata']")
|
|
}
|
|
$licenseText = Get-ChildText $metadata "license"
|
|
if (!$licenseText) { $licenseText = Get-ChildText $metadata "licenseUrl" }
|
|
$authorsText = Get-ChildText $metadata "authors"
|
|
$copyrightText = Get-ChildText $metadata "copyright"
|
|
$projectUrlText = Get-ChildText $metadata "projectUrl"
|
|
$license = if ($licenseText) { $licenseText } else { "Not declared in package metadata" }
|
|
$authors = if ($authorsText) { $authorsText } else { "Not declared" }
|
|
$copyright = if ($copyrightText) { $copyrightText } else { "Not declared" }
|
|
$projectUrl = if ($projectUrlText) { $projectUrlText } else { "Not declared" }
|
|
|
|
$copied = [Collections.Generic.List[string]]::new()
|
|
$noticeFiles = @(Get-ChildItem $package.Root -File -Recurse -ErrorAction SilentlyContinue | Where-Object {
|
|
$_.Length -le 5MB -and $_.Name -match '^(license|licence|notice|third[-_. ]?party|thirdparty|copying|copyright)([._ -].*)?$'
|
|
})
|
|
foreach ($notice in $noticeFiles) {
|
|
$rootPrefix = $package.Root.TrimEnd([char[]]"\/")
|
|
$relative = $notice.FullName.Substring($rootPrefix.Length).TrimStart([char[]]"\/")
|
|
$targetName = ($relative -replace '[\\/:*?"<>|]', '__')
|
|
$target = Join-Path $packageOutput $targetName
|
|
Copy-Item $notice.FullName $target -Force
|
|
$copied.Add($targetName)
|
|
}
|
|
if ($copied.Count -eq 0) { Remove-Item $packageOutput -Force }
|
|
|
|
$inventory.Add("Package: $($package.Id) $($package.Version)")
|
|
$inventory.Add("Authors: $authors")
|
|
$inventory.Add("Copyright: $copyright")
|
|
$inventory.Add("Licence declaration: $license")
|
|
$inventory.Add("Project: $projectUrl")
|
|
$inventory.Add("Copied notice files: $(if ($copied.Count) { $copied -join ', ' } else { 'none found in restored package' })")
|
|
$inventory.Add("")
|
|
}
|
|
|
|
[IO.File]::WriteAllLines((Join-Path $OutputRoot "NuGet-LICENCE-INVENTORY.txt"), $inventory, [Text.UTF8Encoding]::new($false))
|
|
Write-Host "Collected legal metadata for $($packages.Count) restored NuGet packages."
|