-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest-analyzer-package.ps1
More file actions
142 lines (123 loc) · 5.28 KB
/
Copy pathtest-analyzer-package.ps1
File metadata and controls
142 lines (123 loc) · 5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
param(
[Parameter(Mandatory = $true)][string]$PackagePath,
[ValidateSet('NTComponents', 'NTComponents.Analyzers')][string]$ExpectedPackageId = 'NTComponents.Analyzers'
)
$ErrorActionPreference = 'Stop'
$resolvedPackagePath = (Resolve-Path -LiteralPath $PackagePath).Path
Add-Type -AssemblyName System.IO.Compression.FileSystem
$archive = [System.IO.Compression.ZipFile]::OpenRead($resolvedPackagePath)
try {
$requiredEntries = @(
'analyzers/dotnet/cs/NTComponents.Analyzers.dll',
'README.md',
'Logo.png'
)
foreach ($requiredEntry in $requiredEntries) {
if (-not ($archive.Entries | Where-Object FullName -eq $requiredEntry)) {
throw "Analyzer package is missing required entry '$requiredEntry'."
}
}
if ($ExpectedPackageId -eq 'NTComponents.Analyzers' -and ($archive.Entries | Where-Object { $_.FullName -like 'lib/*.dll' -or $_.FullName -like 'lib/*/*.dll' })) {
throw 'Analyzer package must not expose its assembly as a compile or runtime library.'
}
$nuspecEntry = $archive.Entries | Where-Object FullName -like '*.nuspec' | Select-Object -First 1
if (-not $nuspecEntry) {
throw 'Analyzer package does not contain a nuspec file.'
}
$reader = [System.IO.StreamReader]::new($nuspecEntry.Open())
try {
[xml]$nuspec = $reader.ReadToEnd()
}
finally {
$reader.Dispose()
}
$packageId = [string]$nuspec.package.metadata.id
$packageVersion = [string]$nuspec.package.metadata.version
if ($packageId -ne $ExpectedPackageId -or [string]::IsNullOrWhiteSpace($packageVersion)) {
throw "Unexpected analyzer package identity '$packageId' version '$packageVersion'."
}
}
finally {
$archive.Dispose()
}
$temporaryDirectory = Join-Path ([System.IO.Path]::GetTempPath()) "ntcomponents-analyzer-package-$([Guid]::NewGuid().ToString('N'))"
$feedDirectory = Join-Path $temporaryDirectory 'feed'
$projectDirectory = Join-Path $temporaryDirectory 'consumer'
$packagesDirectory = Join-Path $temporaryDirectory 'packages'
try {
New-Item -ItemType Directory -Path $feedDirectory, $projectDirectory | Out-Null
Copy-Item -LiteralPath $resolvedPackagePath -Destination $feedDirectory
$escapedFeedDirectory = [System.Security.SecurityElement]::Escape($feedDirectory)
$escapedPackagesDirectory = [System.Security.SecurityElement]::Escape($packagesDirectory)
$project = @"
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RestoreSources>$escapedFeedDirectory;https://api.nuget.org/v3/index.json</RestoreSources>
<RestorePackagesPath>$escapedPackagesDirectory</RestorePackagesPath>
<NuGetAudit>false</NuGetAudit>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="$packageId" Version="$packageVersion" />
</ItemGroup>
</Project>
"@
$source = if ($packageId -eq 'NTComponents') {
@'
using Microsoft.AspNetCore.Components.Rendering;
using NTComponents;
public static class ButtonFactory {
public static void Build(RenderTreeBuilder builder) {
builder.OpenComponent<NTButton>(0);
builder.CloseComponent();
}
}
'@
}
else {
@'
namespace Microsoft.AspNetCore.Components.Rendering {
public sealed class RenderTreeBuilder {
public void OpenComponent<TComponent>(int sequence) { }
public void AddAttribute(int sequence, string name, object? value) { }
public void CloseComponent() { }
}
}
namespace NTComponents {
public sealed class NTButton { }
public enum NTButtonVariant { Elevated, Filled, Tonal, Outlined, Text }
public enum TnTColor { None, Transparent, Primary, OnPrimary, SecondaryContainer, OnSecondaryContainer, SurfaceContainerLow, InverseSurface }
public enum NTElevation { None, Lowest, Low, Medium, High, Highest }
}
public static class ButtonFactory {
public static void Build(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) {
builder.OpenComponent<NTComponents.NTButton>(0);
builder.CloseComponent();
}
}
'@
}
$projectPath = Join-Path $projectDirectory 'AnalyzerPackageConsumer.csproj'
[System.IO.File]::WriteAllText($projectPath, $project, [System.Text.UTF8Encoding]::new($false))
[System.IO.File]::WriteAllText((Join-Path $projectDirectory 'ButtonFactory.cs'), $source, [System.Text.UTF8Encoding]::new($false))
$restoreOutput = & dotnet restore $projectPath --ignore-failed-sources --verbosity minimal 2>&1
if ($LASTEXITCODE -ne 0) {
throw "Analyzer package consumer restore failed:`n$($restoreOutput -join [Environment]::NewLine)"
}
$buildOutput = & dotnet build $projectPath --no-restore --configuration Release --verbosity minimal 2>&1
$buildText = $buildOutput -join [Environment]::NewLine
if ($LASTEXITCODE -ne 0) {
throw "Analyzer package consumer build failed:`n$buildText"
}
if ($buildText -notmatch '\bNTC1008\b') {
throw "Analyzer package consumer build did not report NTC1008:`n$buildText"
}
Write-Host "Verified $packageId $packageVersion and observed NTC1008 in a consumer build."
}
finally {
if (Test-Path -LiteralPath $temporaryDirectory) {
Remove-Item -LiteralPath $temporaryDirectory -Recurse -Force
}
}