mirror of
https://github.com/PowerShell/PowerShell.git
synced 2024-11-23 01:34:19 +08:00
Replace PSVersion
source generator with incremental one (#23815)
This commit is contained in:
parent
be59e5e80e
commit
5153f9ba63
@ -31,6 +31,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "powershell-unix", "src\powe
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "xUnit.tests", "test\xUnit\xUnit.tests.csproj", "{08704934-9764-48CE-86DB-BCF0A1CF7899}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "xUnit.tests", "test\xUnit\xUnit.tests.csproj", "{08704934-9764-48CE-86DB-BCF0A1CF7899}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PSVersionInfoGenerator", "src\System.Management.Automation\SourceGenerators\PSVersionInfoGenerator\PSVersionInfoGenerator.csproj", "{B22424E8-0516-4FC3-A9CB-D84D15EF0589}"
|
||||||
|
EndProject
|
||||||
# Configuration mapping comment
|
# Configuration mapping comment
|
||||||
# All global configurations must be mapped to project configurations
|
# All global configurations must be mapped to project configurations
|
||||||
#
|
#
|
||||||
|
@ -11,40 +11,70 @@ namespace SMA
|
|||||||
/// Source Code Generator to create partial PSVersionInfo class.
|
/// Source Code Generator to create partial PSVersionInfo class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Generator]
|
[Generator]
|
||||||
public class PSVersionInfoGenerator : ISourceGenerator
|
public class PSVersionInfoGenerator : IIncrementalGenerator
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Generate output PSVersionInfo.g.cs file.
|
|
||||||
/// This allows to directly get ProductVersion and others without reflection.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">Generator execution context.</param>
|
|
||||||
public void Execute(GeneratorExecutionContext context)
|
|
||||||
{
|
|
||||||
var result = CreatePSVersionInfoPartialClass(context);
|
|
||||||
|
|
||||||
// We must use specific file name suffix (*.g.cs,*.g, *.i.cs, *.generated.cs, *.designer.cs)
|
|
||||||
// so that Roslyn analyzers skip the file.
|
|
||||||
context.AddSource("PSVersionInfo.g.cs", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Not used.
|
/// Not used.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">Generator initialization context.</param>
|
/// <param name="context">Generator initialization context.</param>
|
||||||
public void Initialize(GeneratorInitializationContext context)
|
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||||
{
|
{
|
||||||
// No initialization required for this one.
|
IncrementalValueProvider<BuildOptions> buildOptionsProvider = context.AnalyzerConfigOptionsProvider
|
||||||
|
.Select(static (provider, _) =>
|
||||||
|
{
|
||||||
|
provider.GlobalOptions.TryGetValue("build_property.ProductVersion", out var productVersion);
|
||||||
|
provider.GlobalOptions.TryGetValue("build_property.PSCoreBuildVersion", out var mainVersion);
|
||||||
|
provider.GlobalOptions.TryGetValue("build_property.PowerShellVersion", out var gitDescribe);
|
||||||
|
provider.GlobalOptions.TryGetValue("build_property.ReleaseTag", out var releaseTag);
|
||||||
|
|
||||||
|
BuildOptions options = new()
|
||||||
|
{
|
||||||
|
ProductVersion = productVersion ?? string.Empty,
|
||||||
|
MainVersion = mainVersion ?? string.Empty,
|
||||||
|
GitDescribe = gitDescribe ?? string.Empty,
|
||||||
|
ReleaseTag = releaseTag ?? string.Empty
|
||||||
|
};
|
||||||
|
|
||||||
|
return options;
|
||||||
|
});
|
||||||
|
|
||||||
|
context.RegisterSourceOutput(
|
||||||
|
buildOptionsProvider,
|
||||||
|
static (context, buildOptions) =>
|
||||||
|
{
|
||||||
|
string gitCommitId = string.IsNullOrEmpty(buildOptions.ReleaseTag) ? buildOptions.GitDescribe : buildOptions.ReleaseTag;
|
||||||
|
if (gitCommitId.StartsWith("v"))
|
||||||
|
{
|
||||||
|
gitCommitId = gitCommitId.Substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var versions = ParsePSVersion(buildOptions.MainVersion);
|
||||||
|
string result = string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
SourceTemplate,
|
||||||
|
buildOptions.ProductVersion,
|
||||||
|
gitCommitId,
|
||||||
|
versions.major,
|
||||||
|
versions.minor,
|
||||||
|
versions.patch,
|
||||||
|
versions.preReleaseLabel);
|
||||||
|
|
||||||
|
// We must use specific file name suffix (*.g.cs,*.g, *.i.cs, *.generated.cs, *.designer.cs)
|
||||||
|
// so that Roslyn analyzers skip the file.
|
||||||
|
context.AddSource("PSVersionInfo.g.cs", result);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private struct BuildOptions
|
||||||
/// Generate source code for the partial PSVersionInfo class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">Generator execution context.</param>
|
|
||||||
/// <returns>A string with partial PSVersionInfo class.</returns>
|
|
||||||
private static string CreatePSVersionInfoPartialClass(GeneratorExecutionContext context)
|
|
||||||
{
|
{
|
||||||
// We must put "<auto-generated" on first line so that Roslyng analyzers skip the file.
|
public string ProductVersion;
|
||||||
const string SourceTemplate = @"// <auto-generated>
|
public string MainVersion;
|
||||||
|
public string GitDescribe;
|
||||||
|
public string ReleaseTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We must put "<auto-generated" on first line so that Roslyng analyzers skip the file.
|
||||||
|
private const string SourceTemplate = @"// <auto-generated>
|
||||||
// This file is auto-generated by PSVersionInfoGenerator.
|
// This file is auto-generated by PSVersionInfoGenerator.
|
||||||
// </auto-generated>
|
// </auto-generated>
|
||||||
|
|
||||||
@ -81,30 +111,6 @@ namespace System.Management.Automation
|
|||||||
}}
|
}}
|
||||||
}}";
|
}}";
|
||||||
|
|
||||||
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.ProductVersion", out var productVersion);
|
|
||||||
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.PSCoreBuildVersion", out var mainVersion);
|
|
||||||
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.PowerShellVersion", out var gitDescribe);
|
|
||||||
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.ReleaseTag", out var releaseTag);
|
|
||||||
|
|
||||||
string gitCommitId = string.IsNullOrEmpty(releaseTag) ? gitDescribe : releaseTag;
|
|
||||||
if (gitCommitId.StartsWith("v"))
|
|
||||||
{
|
|
||||||
gitCommitId = gitCommitId.Substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = ParsePSVersion(mainVersion);
|
|
||||||
|
|
||||||
return string.Format(
|
|
||||||
CultureInfo.InvariantCulture,
|
|
||||||
SourceTemplate,
|
|
||||||
productVersion,
|
|
||||||
gitCommitId,
|
|
||||||
result.major,
|
|
||||||
result.minor,
|
|
||||||
result.patch,
|
|
||||||
result.preReleaseLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static (int major, int minor, int patch, string preReleaseLabel) ParsePSVersion(string mainVersion)
|
private static (int major, int minor, int patch, string preReleaseLabel) ParsePSVersion(string mainVersion)
|
||||||
{
|
{
|
||||||
// We only handle the pre-defined PSVersion format here, e.g. 7.x.x or 7.x.x-preview.x
|
// We only handle the pre-defined PSVersion format here, e.g. 7.x.x or 7.x.x-preview.x
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<LangVersion>11.0</LangVersion>
|
<LangVersion>11.0</LangVersion>
|
||||||
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
|
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
|
||||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||||
<NoWarn>RS1035</NoWarn>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
Loading…
Reference in New Issue
Block a user