70 lines
2.6 KiB
C#
70 lines
2.6 KiB
C#
using System;
|
|||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Collections.Immutable;
|
||
|
|
using System.Diagnostics;
|
||
|
|
using System.Linq;
|
||
|
|
using System.Text;
|
||
|
|
using Microsoft.CodeAnalysis;
|
||
|
|
using Microsoft.CodeAnalysis.Text;
|
||
|
|
|
||
|
|
namespace PCL.Core.SourceGenerators;
|
||
|
|
|
||
|
|
[Generator(LanguageNames.CSharp)]
|
||
|
|
public class EnvironmentInteropGenerator : IIncrementalGenerator
|
||
|
|
{
|
||
|
|
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||
|
|
{
|
||
|
|
var secretProvider = context.CompilationProvider.Select(static (_, _) =>
|
||
|
|
{
|
||
|
|
// 判断 PCL_WRITE_SECRET 是否存在并遍历转换环境变量
|
||
|
|
// 打死也不会用 MSBuild Properties 这种非人类设计出来的垃圾
|
||
|
|
#pragma warning disable RS1035
|
||
|
|
var envs = Environment.GetEnvironmentVariables();
|
||
|
|
#pragma warning restore RS1035
|
||
|
|
var secretPairs = envs.Contains("PCL_WRITE_SECRET") ? (
|
||
|
|
from key in (
|
||
|
|
from key in envs.Keys.Cast<string>()
|
||
|
|
where !string.IsNullOrWhiteSpace(key) && key.StartsWith("PCL_") && key != "PCL_WRITE_SECRET"
|
||
|
|
select key
|
||
|
|
)
|
||
|
|
let value = envs[key]?.ToString()
|
||
|
|
where !string.IsNullOrWhiteSpace(value)
|
||
|
|
select (key.Substring(4), value)
|
||
|
|
) : [];
|
||
|
|
return secretPairs;
|
||
|
|
});
|
||
|
|
|
||
|
|
// 注册源代码输出
|
||
|
|
context.RegisterSourceOutput(secretProvider, static (spc, secretPairs) => _Execute(spc, secretPairs));
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void _Execute(SourceProductionContext context, IEnumerable<(string, string)> secretPairs)
|
||
|
|
{
|
||
|
|
var sb = new StringBuilder();
|
||
|
|
sb.AppendLine("// <auto-generated />");
|
||
|
|
sb.AppendLine("// 此文件由 Source Generator 自动生成,请勿手动修改");
|
||
|
|
sb.AppendLine();
|
||
|
|
sb.AppendLine("#nullable enable");
|
||
|
|
sb.AppendLine();
|
||
|
|
sb.AppendLine("namespace PCL.Core.Utils.OS;");
|
||
|
|
sb.AppendLine();
|
||
|
|
sb.AppendLine("partial class EnvironmentInterop");
|
||
|
|
sb.AppendLine("{");
|
||
|
|
sb.AppendLine(" private static readonly System.Collections.Generic.Dictionary<string, string?> SecretDictionary = new()");
|
||
|
|
sb.AppendLine(" {");
|
||
|
|
|
||
|
|
foreach (var (key, value) in secretPairs)
|
||
|
|
sb.AppendLine($" [\"{key}\"] = {_ToVerbatimString(value)},");
|
||
|
|
|
||
|
|
sb.AppendLine(" };");
|
||
|
|
sb.AppendLine("}");
|
||
|
|
|
||
|
|
context.AddSource("EnvironmentInterop.g.cs", SourceText.From(sb.ToString(), Encoding.UTF8));
|
||
|
|
}
|
||
|
|
|
||
|
|
private static string _ToVerbatimString(string text)
|
||
|
|
{
|
||
|
|
return "@\"" + text.Replace("\"", "\"\"") + "\"";
|
||
|
|
}
|
||
|
|
}
|