diff --git a/.generated.NoMobile.sln b/.generated.NoMobile.sln index 62290abdc9..ea50adc690 100644 --- a/.generated.NoMobile.sln +++ b/.generated.NoMobile.sln @@ -170,7 +170,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.Hangfire", "src\Sent EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.Hangfire.Tests", "test\Sentry.Hangfire.Tests\Sentry.Hangfire.Tests.csproj", "{46E40BE8-1AB0-4846-B0A2-A40AD0272C64}" EndProject -Project("{00000000-0000-0000-0000-000000000000}") = "Sentry.Samples.AspNetCore.WebAPI.Profiling", "samples\Sentry.Samples.AspNetCore.WebAPI.Profiling\Sentry.Samples.AspNetCore.WebAPI.Profiling.csproj", "{A5B26C14-7313-4EDC-91E3-287F9374AB75}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.Samples.AspNetCore.WebAPI.Profiling", "samples\Sentry.Samples.AspNetCore.WebAPI.Profiling\Sentry.Samples.AspNetCore.WebAPI.Profiling.csproj", "{A5B26C14-7313-4EDC-91E3-287F9374AB75}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "root", "root", "{233D34AB-970E-4913-AA1E-172E833FB5B2}" ProjectSection(SolutionItems) = preProject @@ -197,6 +197,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.TrimTest", "test\Sen EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.MauiTrimTest", "test\Sentry.MauiTrimTest\Sentry.MauiTrimTest.csproj", "{DF92E098-822C-4B94-B96B-56BFB91FBB54}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.SourceGenerators", "src\Sentry.SourceGenerators\Sentry.SourceGenerators.csproj", "{C3CDF61C-3E28-441C-A9CE-011C89D11719}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.SourceGenerators.Tests", "test\Sentry.SourceGenerators.Tests\Sentry.SourceGenerators.Tests.csproj", "{3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -532,6 +536,14 @@ Global {DF92E098-822C-4B94-B96B-56BFB91FBB54}.Debug|Any CPU.Build.0 = Debug|Any CPU {DF92E098-822C-4B94-B96B-56BFB91FBB54}.Release|Any CPU.ActiveCfg = Release|Any CPU {DF92E098-822C-4B94-B96B-56BFB91FBB54}.Release|Any CPU.Build.0 = Release|Any CPU + {C3CDF61C-3E28-441C-A9CE-011C89D11719}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3CDF61C-3E28-441C-A9CE-011C89D11719}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3CDF61C-3E28-441C-A9CE-011C89D11719}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3CDF61C-3E28-441C-A9CE-011C89D11719}.Release|Any CPU.Build.0 = Release|Any CPU + {3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -619,5 +631,7 @@ Global {D7DF0B26-AD43-4F8B-9BFE-C4471CCC9821} = {21B42F60-5802-404E-90F0-AEBCC56760C0} {6030B748-0000-43B5-B8A8-399AA42F5229} = {6987A1CC-608E-4868-A02C-09D30C8B7B2D} {DF92E098-822C-4B94-B96B-56BFB91FBB54} = {6987A1CC-608E-4868-A02C-09D30C8B7B2D} + {C3CDF61C-3E28-441C-A9CE-011C89D11719} = {230B9384-90FD-4551-A5DE-1A5C197F25B6} + {3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893} = {6987A1CC-608E-4868-A02C-09D30C8B7B2D} EndGlobalSection EndGlobal diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b5c90b209..21213821a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +### Features + +- New source generator allows Sentry to see true build variables like PublishAot and PublishTrimmed to properly adapt checks in the Sentry SDK ([#4101](https://github.com/getsentry/sentry-dotnet/pull/4101)) ### Dependencies - Bump CLI from v2.43.1 to v2.44.0 ([#4169](https://github.com/getsentry/sentry-dotnet/pull/4169)) diff --git a/Sentry-CI-Build-Linux.slnf b/Sentry-CI-Build-Linux.slnf index 06a3bafeea..70d49a65ef 100644 --- a/Sentry-CI-Build-Linux.slnf +++ b/Sentry-CI-Build-Linux.slnf @@ -49,6 +49,7 @@ "src\\Sentry.OpenTelemetry\\Sentry.OpenTelemetry.csproj", "src\\Sentry.Profiling\\Sentry.Profiling.csproj", "src\\Sentry.Serilog\\Sentry.Serilog.csproj", + "src\\Sentry.SourceGenerators\\Sentry.SourceGenerators.csproj", "src\\Sentry\\Sentry.csproj", "test\\Sentry.Analyzers.Tests\\Sentry.Analyzers.Tests.csproj", "test\\Sentry.Android.AssemblyReader.Tests\\Sentry.Android.AssemblyReader.Tests.csproj", @@ -69,6 +70,7 @@ "test\\Sentry.OpenTelemetry.Tests\\Sentry.OpenTelemetry.Tests.csproj", "test\\Sentry.Profiling.Tests\\Sentry.Profiling.Tests.csproj", "test\\Sentry.Serilog.Tests\\Sentry.Serilog.Tests.csproj", + "test\\Sentry.SourceGenerators.Tests\\Sentry.SourceGenerators.Tests.csproj", "test\\Sentry.Testing.CrashableApp\\Sentry.Testing.CrashableApp.csproj", "test\\Sentry.Testing\\Sentry.Testing.csproj", "test\\Sentry.Tests\\Sentry.Tests.csproj", diff --git a/Sentry-CI-Build-Windows.slnf b/Sentry-CI-Build-Windows.slnf index 1ad751775d..0e2a79aa0c 100644 --- a/Sentry-CI-Build-Windows.slnf +++ b/Sentry-CI-Build-Windows.slnf @@ -51,6 +51,7 @@ "src\\Sentry.OpenTelemetry\\Sentry.OpenTelemetry.csproj", "src\\Sentry.Profiling\\Sentry.Profiling.csproj", "src\\Sentry.Serilog\\Sentry.Serilog.csproj", + "src\\Sentry.SourceGenerators\\Sentry.SourceGenerators.csproj", "src\\Sentry\\Sentry.csproj", "test\\Sentry.Analyzers.Tests\\Sentry.Analyzers.Tests.csproj", "test\\Sentry.Android.AssemblyReader.Tests\\Sentry.Android.AssemblyReader.Tests.csproj", @@ -71,6 +72,7 @@ "test\\Sentry.OpenTelemetry.Tests\\Sentry.OpenTelemetry.Tests.csproj", "test\\Sentry.Profiling.Tests\\Sentry.Profiling.Tests.csproj", "test\\Sentry.Serilog.Tests\\Sentry.Serilog.Tests.csproj", + "test\\Sentry.SourceGenerators.Tests\\Sentry.SourceGenerators.Tests.csproj", "test\\Sentry.Testing.CrashableApp\\Sentry.Testing.CrashableApp.csproj", "test\\Sentry.Testing\\Sentry.Testing.csproj", "test\\Sentry.Tests\\Sentry.Tests.csproj", diff --git a/Sentry-CI-Build-macOS.slnf b/Sentry-CI-Build-macOS.slnf index 7857558117..fa6698101a 100644 --- a/Sentry-CI-Build-macOS.slnf +++ b/Sentry-CI-Build-macOS.slnf @@ -56,6 +56,7 @@ "src\\Sentry.OpenTelemetry\\Sentry.OpenTelemetry.csproj", "src\\Sentry.Profiling\\Sentry.Profiling.csproj", "src\\Sentry.Serilog\\Sentry.Serilog.csproj", + "src\\Sentry.SourceGenerators\\Sentry.SourceGenerators.csproj", "src\\Sentry\\Sentry.csproj", "test\\Sentry.Analyzers.Tests\\Sentry.Analyzers.Tests.csproj", "test\\Sentry.Android.AssemblyReader.Tests\\Sentry.Android.AssemblyReader.Tests.csproj", @@ -77,6 +78,7 @@ "test\\Sentry.OpenTelemetry.Tests\\Sentry.OpenTelemetry.Tests.csproj", "test\\Sentry.Profiling.Tests\\Sentry.Profiling.Tests.csproj", "test\\Sentry.Serilog.Tests\\Sentry.Serilog.Tests.csproj", + "test\\Sentry.SourceGenerators.Tests\\Sentry.SourceGenerators.Tests.csproj", "test\\Sentry.Testing.CrashableApp\\Sentry.Testing.CrashableApp.csproj", "test\\Sentry.Testing\\Sentry.Testing.csproj", "test\\Sentry.Tests\\Sentry.Tests.csproj", diff --git a/Sentry-CI-CodeQL.slnf b/Sentry-CI-CodeQL.slnf index 44eb07a6e4..be252d4fe2 100644 --- a/Sentry-CI-CodeQL.slnf +++ b/Sentry-CI-CodeQL.slnf @@ -20,6 +20,7 @@ "src\\Sentry.OpenTelemetry\\Sentry.OpenTelemetry.csproj", "src\\Sentry.Profiling\\Sentry.Profiling.csproj", "src\\Sentry.Serilog\\Sentry.Serilog.csproj", + "src\\Sentry.SourceGenerators\\Sentry.SourceGenerators.csproj", "src\\Sentry\\Sentry.csproj" ] } diff --git a/Sentry.sln b/Sentry.sln index 3ef6fd24aa..ea50adc690 100644 --- a/Sentry.sln +++ b/Sentry.sln @@ -197,6 +197,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.TrimTest", "test\Sen EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.MauiTrimTest", "test\Sentry.MauiTrimTest\Sentry.MauiTrimTest.csproj", "{DF92E098-822C-4B94-B96B-56BFB91FBB54}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.SourceGenerators", "src\Sentry.SourceGenerators\Sentry.SourceGenerators.csproj", "{C3CDF61C-3E28-441C-A9CE-011C89D11719}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.SourceGenerators.Tests", "test\Sentry.SourceGenerators.Tests\Sentry.SourceGenerators.Tests.csproj", "{3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -532,6 +536,14 @@ Global {DF92E098-822C-4B94-B96B-56BFB91FBB54}.Debug|Any CPU.Build.0 = Debug|Any CPU {DF92E098-822C-4B94-B96B-56BFB91FBB54}.Release|Any CPU.ActiveCfg = Release|Any CPU {DF92E098-822C-4B94-B96B-56BFB91FBB54}.Release|Any CPU.Build.0 = Release|Any CPU + {C3CDF61C-3E28-441C-A9CE-011C89D11719}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3CDF61C-3E28-441C-A9CE-011C89D11719}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3CDF61C-3E28-441C-A9CE-011C89D11719}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3CDF61C-3E28-441C-A9CE-011C89D11719}.Release|Any CPU.Build.0 = Release|Any CPU + {3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -619,5 +631,7 @@ Global {D7DF0B26-AD43-4F8B-9BFE-C4471CCC9821} = {21B42F60-5802-404E-90F0-AEBCC56760C0} {6030B748-0000-43B5-B8A8-399AA42F5229} = {6987A1CC-608E-4868-A02C-09D30C8B7B2D} {DF92E098-822C-4B94-B96B-56BFB91FBB54} = {6987A1CC-608E-4868-A02C-09D30C8B7B2D} + {C3CDF61C-3E28-441C-A9CE-011C89D11719} = {230B9384-90FD-4551-A5DE-1A5C197F25B6} + {3A76FF7D-2F32-4EA5-8999-2FFE3C7CB893} = {6987A1CC-608E-4868-A02C-09D30C8B7B2D} EndGlobalSection EndGlobal diff --git a/SentryNoMobile.slnf b/SentryNoMobile.slnf index e6e27c6ee7..1592f77697 100644 --- a/SentryNoMobile.slnf +++ b/SentryNoMobile.slnf @@ -47,6 +47,7 @@ "src\\Sentry.OpenTelemetry\\Sentry.OpenTelemetry.csproj", "src\\Sentry.Profiling\\Sentry.Profiling.csproj", "src\\Sentry.Serilog\\Sentry.Serilog.csproj", + "src\\Sentry.SourceGenerators\\Sentry.SourceGenerators.csproj", "src\\Sentry\\Sentry.csproj", "test\\Sentry.Analyzers.Tests\\Sentry.Analyzers.Tests.csproj", "test\\Sentry.AspNet.Tests\\Sentry.AspNet.Tests.csproj", @@ -65,6 +66,7 @@ "test\\Sentry.OpenTelemetry.Tests\\Sentry.OpenTelemetry.Tests.csproj", "test\\Sentry.Profiling.Tests\\Sentry.Profiling.Tests.csproj", "test\\Sentry.Serilog.Tests\\Sentry.Serilog.Tests.csproj", + "test\\Sentry.SourceGenerators.Tests\\Sentry.SourceGenerators.Tests.csproj", "test\\Sentry.Testing.CrashableApp\\Sentry.Testing.CrashableApp.csproj", "test\\Sentry.Testing\\Sentry.Testing.csproj", "test\\Sentry.Tests\\Sentry.Tests.csproj", diff --git a/SentryNoSamples.slnf b/SentryNoSamples.slnf index 66ce4d76a5..f823107fbf 100644 --- a/SentryNoSamples.slnf +++ b/SentryNoSamples.slnf @@ -21,6 +21,7 @@ "src\\Sentry.OpenTelemetry\\Sentry.OpenTelemetry.csproj", "src\\Sentry.Profiling\\Sentry.Profiling.csproj", "src\\Sentry.Serilog\\Sentry.Serilog.csproj", + "src\\Sentry.SourceGenerators\\Sentry.SourceGenerators.csproj", "src\\Sentry\\Sentry.csproj", "test\\Sentry.Analyzers.Tests\\Sentry.Analyzers.Tests.csproj", "test\\Sentry.Android.AssemblyReader.Tests\\Sentry.Android.AssemblyReader.Tests.csproj", @@ -41,6 +42,7 @@ "test\\Sentry.OpenTelemetry.Tests\\Sentry.OpenTelemetry.Tests.csproj", "test\\Sentry.Profiling.Tests\\Sentry.Profiling.Tests.csproj", "test\\Sentry.Serilog.Tests\\Sentry.Serilog.Tests.csproj", + "test\\Sentry.SourceGenerators.Tests\\Sentry.SourceGenerators.Tests.csproj", "test\\Sentry.Testing.CrashableApp\\Sentry.Testing.CrashableApp.csproj", "test\\Sentry.Testing\\Sentry.Testing.csproj", "test\\Sentry.Tests\\Sentry.Tests.csproj" diff --git a/samples/Sentry.Samples.Android/Sentry.Samples.Android.csproj b/samples/Sentry.Samples.Android/Sentry.Samples.Android.csproj index ace5748bae..61fcb9bc31 100644 --- a/samples/Sentry.Samples.Android/Sentry.Samples.Android.csproj +++ b/samples/Sentry.Samples.Android/Sentry.Samples.Android.csproj @@ -12,6 +12,9 @@ + @@ -40,4 +43,6 @@ full + + diff --git a/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj b/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj index 0b0adbbe72..25f4b66c46 100644 --- a/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj +++ b/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj @@ -44,5 +44,11 @@ + + + + diff --git a/samples/Sentry.Samples.MacCatalyst/Sentry.Samples.MacCatalyst.csproj b/samples/Sentry.Samples.MacCatalyst/Sentry.Samples.MacCatalyst.csproj index deacfb2b37..e48c894e34 100644 --- a/samples/Sentry.Samples.MacCatalyst/Sentry.Samples.MacCatalyst.csproj +++ b/samples/Sentry.Samples.MacCatalyst/Sentry.Samples.MacCatalyst.csproj @@ -44,6 +44,11 @@ + + + diff --git a/samples/Sentry.Samples.Maui/Sentry.Samples.Maui.csproj b/samples/Sentry.Samples.Maui/Sentry.Samples.Maui.csproj index d570b75527..b71221612f 100644 --- a/samples/Sentry.Samples.Maui/Sentry.Samples.Maui.csproj +++ b/samples/Sentry.Samples.Maui/Sentry.Samples.Maui.csproj @@ -103,10 +103,15 @@ + + + diff --git a/scripts/generate-solution-filters-config.yaml b/scripts/generate-solution-filters-config.yaml index d3f0701202..1b829b1c59 100644 --- a/scripts/generate-solution-filters-config.yaml +++ b/scripts/generate-solution-filters-config.yaml @@ -48,7 +48,6 @@ filterConfigs: - "**/*AndroidTestApp.csproj" - "**/*DeviceTests*.csproj" - "**/*Maui.Device.TestApp.csproj" - - "**/*SourceGen.csproj" - outputPath: Sentry-CI-Build-macOS.slnf include: @@ -64,7 +63,6 @@ filterConfigs: patterns: - "**/*AndroidTestApp.csproj" - "**/*DeviceTests*.csproj" - - "**/*SourceGen.csproj" - outputPath: Sentry-CI-Build-Windows.slnf include: @@ -84,7 +82,6 @@ filterConfigs: - "**/*Sentry.Maui.Device.TestApp.csproj" - "**/*Sentry.Samples.Android.csproj" - "**/*OpenTelemetry.AspNet.csproj" - - "**/*SourceGen.csproj" - outputPath: Sentry-CI-CodeQL.slnf include: diff --git a/src/Sentry.SourceGenerators/BuildPropertySourceGenerator.cs b/src/Sentry.SourceGenerators/BuildPropertySourceGenerator.cs new file mode 100644 index 0000000000..7110b4f3a7 --- /dev/null +++ b/src/Sentry.SourceGenerators/BuildPropertySourceGenerator.cs @@ -0,0 +1,98 @@ +using System; +using System.Linq; +using Microsoft.CodeAnalysis; + +namespace Sentry.SourceGenerators; + + +/// +/// Generates the necessary msbuild variables +/// +[Generator(LanguageNames.CSharp)] +public class BuildPropertySourceGenerator : ISourceGenerator +{ + /// + /// Initialize the source gen + /// + public void Initialize(GeneratorInitializationContext context) + { + } + + /// + /// Execute the source gen + /// + public void Execute(GeneratorExecutionContext context) + { + var opts = context.AnalyzerConfigOptions.GlobalOptions; + var properties = opts.Keys.Where(x => x.StartsWith("build_property.")).ToList(); + if (properties.Count == 0) + { + return; + } + + if (opts.TryGetValue("build_property.SentryDisableSourceGenerator", out var disable) && + disable.Equals("true", StringComparison.InvariantCultureIgnoreCase)) + { + return; + } + + // we only want to generate code where host setup takes place + if (!opts.TryGetValue("build_property.outputtype", out var outputType)) + { + return; + } + + if (!outputType.Equals("exe", StringComparison.InvariantCultureIgnoreCase)) + { + return; + } + + var sb = new StringBuilder(); + sb + .Append( +""" +// +// Code generated by Sentry Source Generators +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +#if NET8_0_OR_GREATER +namespace Sentry; + +[global::System.Runtime.CompilerServices.CompilerGenerated] +public static class BuildVariableInitializer +{ + [global::System.Runtime.CompilerServices.ModuleInitializer] + public static void Initialize() + { + global::Sentry.CompilerServices.BuildProperties.Initialize(new global::System.Collections.Generic.Dictionary { + +""" + ); + + foreach (var property in properties) + { + if (opts.TryGetValue(property, out var value)) + { + var pn = EscapeString(property.Replace("build_property.", "")); + var ev = EscapeString(value); + sb + .Append("\t\t\t{") + .Append($"\"{pn}\", \"{ev}\"") + .AppendLine("},"); + } + } + + sb + .AppendLine("\t\t});") // close dictionary + .AppendLine("\t}") + .AppendLine("}") + .AppendLine("#endif"); + + context.AddSource("__BuildProperties.g.cs", sb.ToString()); + } + + + private static string EscapeString(string value) => value.Replace("\\", "\\\\"); +} diff --git a/src/Sentry.SourceGenerators/Sentry.SourceGenerators.csproj b/src/Sentry.SourceGenerators/Sentry.SourceGenerators.csproj new file mode 100644 index 0000000000..047ca032ed --- /dev/null +++ b/src/Sentry.SourceGenerators/Sentry.SourceGenerators.csproj @@ -0,0 +1,25 @@ + + + + netstandard2.0 + false + enable + false + + true + true + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/src/Sentry/CompilerServices/BuildProperties.cs b/src/Sentry/CompilerServices/BuildProperties.cs new file mode 100644 index 0000000000..d4cd7db07e --- /dev/null +++ b/src/Sentry/CompilerServices/BuildProperties.cs @@ -0,0 +1,26 @@ +using Sentry.Internal.Extensions; + +namespace Sentry.CompilerServices; + +/// +/// This class is not meant for external usage +/// +public static class BuildProperties +{ + /// + /// The Build Variables generated from you csproj file and initialized by the Sentry Source Generated Module Initializer + /// + public static IReadOnlyDictionary? Values { get; private set; } + + /// + /// This is called by a Sentry Source-Generator module initializers to help us determine things like + /// Is your app AOT + /// Has your application been trimmed + /// What build configuration is being used + /// + /// + public static void Initialize(Dictionary properties) + { + Values ??= properties.AsReadOnly(); + } +} diff --git a/src/Sentry/Internal/AotHelper.cs b/src/Sentry/Internal/AotHelper.cs index 53165c81ca..a10449e6fe 100644 --- a/src/Sentry/Internal/AotHelper.cs +++ b/src/Sentry/Internal/AotHelper.cs @@ -1,4 +1,4 @@ -using Sentry.Protocol; +using Sentry.CompilerServices; namespace Sentry.Internal; @@ -13,10 +13,37 @@ static AotHelper() IsTrimmed = CheckIsTrimmed(); } + [UnconditionalSuppressMessage("Trimming", "IL2026: RequiresUnreferencedCode", Justification = AvoidAtRuntime)] private static bool CheckIsTrimmed() { + if (TryGetBoolean("publishtrimmed", out var trimmed)) + { + return trimmed; + } + + if (TryGetBoolean("publishaot", out var aot)) + { + return aot; + } + + // fallback check var stackTrace = new StackTrace(false); return stackTrace.GetFrame(0)?.GetMethod() is null; } + + private static bool TryGetBoolean(string key, out bool value) + { + value = false; + if (BuildProperties.Values?.TryGetValue(key, out var aotValue) ?? false) + { + if (bool.TryParse(aotValue, out var result)) + { + value = result; + return true; + } + } + + return false; + } } diff --git a/src/Sentry/Sentry.csproj b/src/Sentry/Sentry.csproj index 266a08f5f1..256506c9f3 100644 --- a/src/Sentry/Sentry.csproj +++ b/src/Sentry/Sentry.csproj @@ -107,10 +107,6 @@ This file contains targets that are invoked during the end-user's build. The same file is included twice, so it ends up being used for both direct and transitive package references to Sentry. --> - - - - @@ -196,4 +192,17 @@ + + + + + + + + + + diff --git a/src/Sentry/SentrySdk.cs b/src/Sentry/SentrySdk.cs index 0670f31729..6627007cda 100644 --- a/src/Sentry/SentrySdk.cs +++ b/src/Sentry/SentrySdk.cs @@ -1,6 +1,7 @@ using Sentry.Extensibility; using Sentry.Infrastructure; using Sentry.Internal; +using Sentry.Internal.Extensions; using Sentry.Protocol.Envelopes; namespace Sentry; diff --git a/src/Sentry/buildTransitive/Sentry.SourceGenerators.targets b/src/Sentry/buildTransitive/Sentry.SourceGenerators.targets new file mode 100644 index 0000000000..292d49e34b --- /dev/null +++ b/src/Sentry/buildTransitive/Sentry.SourceGenerators.targets @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/Sentry/buildTransitive/Sentry.targets b/src/Sentry/buildTransitive/Sentry.targets index 6169666d28..c2f12b2763 100644 --- a/src/Sentry/buildTransitive/Sentry.targets +++ b/src/Sentry/buildTransitive/Sentry.targets @@ -5,6 +5,14 @@ + + + + + + + + Sentry.Attributes$(MSBuildProjectExtension.Replace('proj', '')) diff --git a/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_BadStrings.verified.txt b/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_BadStrings.verified.txt new file mode 100644 index 0000000000..94298c45c3 --- /dev/null +++ b/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_BadStrings.verified.txt @@ -0,0 +1,368 @@ +{ + Generator: {}, + GeneratedSources: [ + { + SyntaxTree: { + FilePath: Sentry.SourceGenerators/Sentry.SourceGenerators.BuildPropertySourceGenerator/__BuildProperties.g.cs, + Encoding: utf-8, + Length: 639, + HasCompilationUnitRoot: true, + Options: { + LanguageVersion: CSharp12, + Language: C#, + DocumentationMode: Parse, + Errors: null + } + }, + SourceText: { + Encoding: utf-8, + Source: +// +// Code generated by Sentry Source Generators +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +#if NET8_0_OR_GREATER +namespace Sentry; + +[global::System.Runtime.CompilerServices.CompilerGenerated] +public static class BuildVariableInitializer +{ + [global::System.Runtime.CompilerServices.ModuleInitializer] + public static void Initialize() + { + global::Sentry.CompilerServices.BuildProperties.Initialize(new global::System.Collections.Generic.Dictionary { + {"My\\Key", "test\\test"}, + {"OutputType", "exe"}, + }); + } +} +#endif +, + Length: 639, + ChecksumAlgorithm: Sha1, + CanBeEmbedded: true, + Container: {}, + Lines: [ + { + End: 19, + EndIncludingLineBreak: 20, + Span: { + Length: 19 + }, + SpanIncludingLineBreak: { + Length: 20 + } + }, + { + LineNumber: 1, + Start: 20, + End: 65, + EndIncludingLineBreak: 66, + Span: { + Start: 20, + Length: 45 + }, + SpanIncludingLineBreak: { + Start: 20, + Length: 46 + } + }, + { + LineNumber: 2, + Start: 66, + End: 137, + EndIncludingLineBreak: 138, + Span: { + Start: 66, + Length: 71 + }, + SpanIncludingLineBreak: { + Start: 66, + Length: 72 + } + }, + { + LineNumber: 3, + Start: 138, + End: 153, + EndIncludingLineBreak: 154, + Span: { + Start: 138, + Length: 15 + }, + SpanIncludingLineBreak: { + Start: 138, + Length: 16 + } + }, + { + LineNumber: 4, + Start: 154, + End: 174, + EndIncludingLineBreak: 175, + Span: { + Start: 154, + Length: 20 + }, + SpanIncludingLineBreak: { + Start: 154, + Length: 21 + } + }, + { + LineNumber: 5, + Start: 175, + End: 175, + EndIncludingLineBreak: 176, + Span: { + Start: 175 + }, + SpanIncludingLineBreak: { + Start: 175, + Length: 1 + } + }, + { + LineNumber: 6, + Start: 176, + End: 197, + EndIncludingLineBreak: 198, + Span: { + Start: 176, + Length: 21 + }, + SpanIncludingLineBreak: { + Start: 176, + Length: 22 + } + }, + { + LineNumber: 7, + Start: 198, + End: 215, + EndIncludingLineBreak: 216, + Span: { + Start: 198, + Length: 17 + }, + SpanIncludingLineBreak: { + Start: 198, + Length: 18 + } + }, + { + LineNumber: 8, + Start: 216, + End: 216, + EndIncludingLineBreak: 217, + Span: { + Start: 216 + }, + SpanIncludingLineBreak: { + Start: 216, + Length: 1 + } + }, + { + LineNumber: 9, + Start: 217, + End: 276, + EndIncludingLineBreak: 277, + Span: { + Start: 217, + Length: 59 + }, + SpanIncludingLineBreak: { + Start: 217, + Length: 60 + } + }, + { + LineNumber: 10, + Start: 277, + End: 321, + EndIncludingLineBreak: 322, + Span: { + Start: 277, + Length: 44 + }, + SpanIncludingLineBreak: { + Start: 277, + Length: 45 + } + }, + { + LineNumber: 11, + Start: 322, + End: 323, + EndIncludingLineBreak: 324, + Span: { + Start: 322, + Length: 1 + }, + SpanIncludingLineBreak: { + Start: 322, + Length: 2 + } + }, + { + LineNumber: 12, + Start: 324, + End: 387, + EndIncludingLineBreak: 388, + Span: { + Start: 324, + Length: 63 + }, + SpanIncludingLineBreak: { + Start: 324, + Length: 64 + } + }, + { + LineNumber: 13, + Start: 388, + End: 423, + EndIncludingLineBreak: 424, + Span: { + Start: 388, + Length: 35 + }, + SpanIncludingLineBreak: { + Start: 388, + Length: 36 + } + }, + { + LineNumber: 14, + Start: 424, + End: 429, + EndIncludingLineBreak: 430, + Span: { + Start: 424, + Length: 5 + }, + SpanIncludingLineBreak: { + Start: 424, + Length: 6 + } + }, + { + LineNumber: 15, + Start: 430, + End: 564, + EndIncludingLineBreak: 565, + Span: { + Start: 430, + Length: 134 + }, + SpanIncludingLineBreak: { + Start: 430, + Length: 135 + } + }, + { + LineNumber: 16, + Start: 565, + End: 594, + EndIncludingLineBreak: 595, + Span: { + Start: 565, + Length: 29 + }, + SpanIncludingLineBreak: { + Start: 565, + Length: 30 + } + }, + { + LineNumber: 17, + Start: 595, + End: 620, + EndIncludingLineBreak: 621, + Span: { + Start: 595, + Length: 25 + }, + SpanIncludingLineBreak: { + Start: 595, + Length: 26 + } + }, + { + LineNumber: 18, + Start: 621, + End: 626, + EndIncludingLineBreak: 627, + Span: { + Start: 621, + Length: 5 + }, + SpanIncludingLineBreak: { + Start: 621, + Length: 6 + } + }, + { + LineNumber: 19, + Start: 627, + End: 629, + EndIncludingLineBreak: 630, + Span: { + Start: 627, + Length: 2 + }, + SpanIncludingLineBreak: { + Start: 627, + Length: 3 + } + }, + { + LineNumber: 20, + Start: 630, + End: 631, + EndIncludingLineBreak: 632, + Span: { + Start: 630, + Length: 1 + }, + SpanIncludingLineBreak: { + Start: 630, + Length: 2 + } + }, + { + LineNumber: 21, + Start: 632, + End: 638, + EndIncludingLineBreak: 639, + Span: { + Start: 632, + Length: 6 + }, + SpanIncludingLineBreak: { + Start: 632, + Length: 7 + } + }, + { + LineNumber: 22, + Start: 639, + End: 639, + EndIncludingLineBreak: 639, + Span: { + Start: 639 + }, + SpanIncludingLineBreak: { + Start: 639 + } + } + ] + }, + HintName: __BuildProperties.g.cs + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_Expect_None.verified.txt b/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_Expect_None.verified.txt new file mode 100644 index 0000000000..f2b746dde0 --- /dev/null +++ b/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_Expect_None.verified.txt @@ -0,0 +1,5 @@ +{ + Generator: {}, + GeneratedSources: null, + Diagnostics: null +} \ No newline at end of file diff --git a/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_Publish_AotTrue.verified.txt b/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_Publish_AotTrue.verified.txt new file mode 100644 index 0000000000..37b44b9ecd --- /dev/null +++ b/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_Publish_AotTrue.verified.txt @@ -0,0 +1,368 @@ +{ + Generator: {}, + GeneratedSources: [ + { + SyntaxTree: { + FilePath: Sentry.SourceGenerators/Sentry.SourceGenerators.BuildPropertySourceGenerator/__BuildProperties.g.cs, + Encoding: utf-8, + Length: 636, + HasCompilationUnitRoot: true, + Options: { + LanguageVersion: CSharp12, + Language: C#, + DocumentationMode: Parse, + Errors: null + } + }, + SourceText: { + Encoding: utf-8, + Source: +// +// Code generated by Sentry Source Generators +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +#if NET8_0_OR_GREATER +namespace Sentry; + +[global::System.Runtime.CompilerServices.CompilerGenerated] +public static class BuildVariableInitializer +{ + [global::System.Runtime.CompilerServices.ModuleInitializer] + public static void Initialize() + { + global::Sentry.CompilerServices.BuildProperties.Initialize(new global::System.Collections.Generic.Dictionary { + {"PublishAot", "true"}, + {"OutputType", "exe"}, + }); + } +} +#endif +, + Length: 636, + ChecksumAlgorithm: Sha1, + CanBeEmbedded: true, + Container: {}, + Lines: [ + { + End: 19, + EndIncludingLineBreak: 20, + Span: { + Length: 19 + }, + SpanIncludingLineBreak: { + Length: 20 + } + }, + { + LineNumber: 1, + Start: 20, + End: 65, + EndIncludingLineBreak: 66, + Span: { + Start: 20, + Length: 45 + }, + SpanIncludingLineBreak: { + Start: 20, + Length: 46 + } + }, + { + LineNumber: 2, + Start: 66, + End: 137, + EndIncludingLineBreak: 138, + Span: { + Start: 66, + Length: 71 + }, + SpanIncludingLineBreak: { + Start: 66, + Length: 72 + } + }, + { + LineNumber: 3, + Start: 138, + End: 153, + EndIncludingLineBreak: 154, + Span: { + Start: 138, + Length: 15 + }, + SpanIncludingLineBreak: { + Start: 138, + Length: 16 + } + }, + { + LineNumber: 4, + Start: 154, + End: 174, + EndIncludingLineBreak: 175, + Span: { + Start: 154, + Length: 20 + }, + SpanIncludingLineBreak: { + Start: 154, + Length: 21 + } + }, + { + LineNumber: 5, + Start: 175, + End: 175, + EndIncludingLineBreak: 176, + Span: { + Start: 175 + }, + SpanIncludingLineBreak: { + Start: 175, + Length: 1 + } + }, + { + LineNumber: 6, + Start: 176, + End: 197, + EndIncludingLineBreak: 198, + Span: { + Start: 176, + Length: 21 + }, + SpanIncludingLineBreak: { + Start: 176, + Length: 22 + } + }, + { + LineNumber: 7, + Start: 198, + End: 215, + EndIncludingLineBreak: 216, + Span: { + Start: 198, + Length: 17 + }, + SpanIncludingLineBreak: { + Start: 198, + Length: 18 + } + }, + { + LineNumber: 8, + Start: 216, + End: 216, + EndIncludingLineBreak: 217, + Span: { + Start: 216 + }, + SpanIncludingLineBreak: { + Start: 216, + Length: 1 + } + }, + { + LineNumber: 9, + Start: 217, + End: 276, + EndIncludingLineBreak: 277, + Span: { + Start: 217, + Length: 59 + }, + SpanIncludingLineBreak: { + Start: 217, + Length: 60 + } + }, + { + LineNumber: 10, + Start: 277, + End: 321, + EndIncludingLineBreak: 322, + Span: { + Start: 277, + Length: 44 + }, + SpanIncludingLineBreak: { + Start: 277, + Length: 45 + } + }, + { + LineNumber: 11, + Start: 322, + End: 323, + EndIncludingLineBreak: 324, + Span: { + Start: 322, + Length: 1 + }, + SpanIncludingLineBreak: { + Start: 322, + Length: 2 + } + }, + { + LineNumber: 12, + Start: 324, + End: 387, + EndIncludingLineBreak: 388, + Span: { + Start: 324, + Length: 63 + }, + SpanIncludingLineBreak: { + Start: 324, + Length: 64 + } + }, + { + LineNumber: 13, + Start: 388, + End: 423, + EndIncludingLineBreak: 424, + Span: { + Start: 388, + Length: 35 + }, + SpanIncludingLineBreak: { + Start: 388, + Length: 36 + } + }, + { + LineNumber: 14, + Start: 424, + End: 429, + EndIncludingLineBreak: 430, + Span: { + Start: 424, + Length: 5 + }, + SpanIncludingLineBreak: { + Start: 424, + Length: 6 + } + }, + { + LineNumber: 15, + Start: 430, + End: 564, + EndIncludingLineBreak: 565, + Span: { + Start: 430, + Length: 134 + }, + SpanIncludingLineBreak: { + Start: 430, + Length: 135 + } + }, + { + LineNumber: 16, + Start: 565, + End: 591, + EndIncludingLineBreak: 592, + Span: { + Start: 565, + Length: 26 + }, + SpanIncludingLineBreak: { + Start: 565, + Length: 27 + } + }, + { + LineNumber: 17, + Start: 592, + End: 617, + EndIncludingLineBreak: 618, + Span: { + Start: 592, + Length: 25 + }, + SpanIncludingLineBreak: { + Start: 592, + Length: 26 + } + }, + { + LineNumber: 18, + Start: 618, + End: 623, + EndIncludingLineBreak: 624, + Span: { + Start: 618, + Length: 5 + }, + SpanIncludingLineBreak: { + Start: 618, + Length: 6 + } + }, + { + LineNumber: 19, + Start: 624, + End: 626, + EndIncludingLineBreak: 627, + Span: { + Start: 624, + Length: 2 + }, + SpanIncludingLineBreak: { + Start: 624, + Length: 3 + } + }, + { + LineNumber: 20, + Start: 627, + End: 628, + EndIncludingLineBreak: 629, + Span: { + Start: 627, + Length: 1 + }, + SpanIncludingLineBreak: { + Start: 627, + Length: 2 + } + }, + { + LineNumber: 21, + Start: 629, + End: 635, + EndIncludingLineBreak: 636, + Span: { + Start: 629, + Length: 6 + }, + SpanIncludingLineBreak: { + Start: 629, + Length: 7 + } + }, + { + LineNumber: 22, + Start: 636, + End: 636, + EndIncludingLineBreak: 636, + Span: { + Start: 636 + }, + SpanIncludingLineBreak: { + Start: 636 + } + } + ] + }, + HintName: __BuildProperties.g.cs + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_Success.verified.txt b/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_Success.verified.txt new file mode 100644 index 0000000000..ff9d84c52d --- /dev/null +++ b/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.RunResult_Success.verified.txt @@ -0,0 +1,368 @@ +{ + Generator: {}, + GeneratedSources: [ + { + SyntaxTree: { + FilePath: Sentry.SourceGenerators/Sentry.SourceGenerators.BuildPropertySourceGenerator/__BuildProperties.g.cs, + Encoding: utf-8, + Length: 637, + HasCompilationUnitRoot: true, + Options: { + LanguageVersion: CSharp12, + Language: C#, + DocumentationMode: Parse, + Errors: null + } + }, + SourceText: { + Encoding: utf-8, + Source: +// +// Code generated by Sentry Source Generators +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +#if NET8_0_OR_GREATER +namespace Sentry; + +[global::System.Runtime.CompilerServices.CompilerGenerated] +public static class BuildVariableInitializer +{ + [global::System.Runtime.CompilerServices.ModuleInitializer] + public static void Initialize() + { + global::Sentry.CompilerServices.BuildProperties.Initialize(new global::System.Collections.Generic.Dictionary { + {"PublishAot", "false"}, + {"OutputType", "exe"}, + }); + } +} +#endif +, + Length: 637, + ChecksumAlgorithm: Sha1, + CanBeEmbedded: true, + Container: {}, + Lines: [ + { + End: 19, + EndIncludingLineBreak: 20, + Span: { + Length: 19 + }, + SpanIncludingLineBreak: { + Length: 20 + } + }, + { + LineNumber: 1, + Start: 20, + End: 65, + EndIncludingLineBreak: 66, + Span: { + Start: 20, + Length: 45 + }, + SpanIncludingLineBreak: { + Start: 20, + Length: 46 + } + }, + { + LineNumber: 2, + Start: 66, + End: 137, + EndIncludingLineBreak: 138, + Span: { + Start: 66, + Length: 71 + }, + SpanIncludingLineBreak: { + Start: 66, + Length: 72 + } + }, + { + LineNumber: 3, + Start: 138, + End: 153, + EndIncludingLineBreak: 154, + Span: { + Start: 138, + Length: 15 + }, + SpanIncludingLineBreak: { + Start: 138, + Length: 16 + } + }, + { + LineNumber: 4, + Start: 154, + End: 174, + EndIncludingLineBreak: 175, + Span: { + Start: 154, + Length: 20 + }, + SpanIncludingLineBreak: { + Start: 154, + Length: 21 + } + }, + { + LineNumber: 5, + Start: 175, + End: 175, + EndIncludingLineBreak: 176, + Span: { + Start: 175 + }, + SpanIncludingLineBreak: { + Start: 175, + Length: 1 + } + }, + { + LineNumber: 6, + Start: 176, + End: 197, + EndIncludingLineBreak: 198, + Span: { + Start: 176, + Length: 21 + }, + SpanIncludingLineBreak: { + Start: 176, + Length: 22 + } + }, + { + LineNumber: 7, + Start: 198, + End: 215, + EndIncludingLineBreak: 216, + Span: { + Start: 198, + Length: 17 + }, + SpanIncludingLineBreak: { + Start: 198, + Length: 18 + } + }, + { + LineNumber: 8, + Start: 216, + End: 216, + EndIncludingLineBreak: 217, + Span: { + Start: 216 + }, + SpanIncludingLineBreak: { + Start: 216, + Length: 1 + } + }, + { + LineNumber: 9, + Start: 217, + End: 276, + EndIncludingLineBreak: 277, + Span: { + Start: 217, + Length: 59 + }, + SpanIncludingLineBreak: { + Start: 217, + Length: 60 + } + }, + { + LineNumber: 10, + Start: 277, + End: 321, + EndIncludingLineBreak: 322, + Span: { + Start: 277, + Length: 44 + }, + SpanIncludingLineBreak: { + Start: 277, + Length: 45 + } + }, + { + LineNumber: 11, + Start: 322, + End: 323, + EndIncludingLineBreak: 324, + Span: { + Start: 322, + Length: 1 + }, + SpanIncludingLineBreak: { + Start: 322, + Length: 2 + } + }, + { + LineNumber: 12, + Start: 324, + End: 387, + EndIncludingLineBreak: 388, + Span: { + Start: 324, + Length: 63 + }, + SpanIncludingLineBreak: { + Start: 324, + Length: 64 + } + }, + { + LineNumber: 13, + Start: 388, + End: 423, + EndIncludingLineBreak: 424, + Span: { + Start: 388, + Length: 35 + }, + SpanIncludingLineBreak: { + Start: 388, + Length: 36 + } + }, + { + LineNumber: 14, + Start: 424, + End: 429, + EndIncludingLineBreak: 430, + Span: { + Start: 424, + Length: 5 + }, + SpanIncludingLineBreak: { + Start: 424, + Length: 6 + } + }, + { + LineNumber: 15, + Start: 430, + End: 564, + EndIncludingLineBreak: 565, + Span: { + Start: 430, + Length: 134 + }, + SpanIncludingLineBreak: { + Start: 430, + Length: 135 + } + }, + { + LineNumber: 16, + Start: 565, + End: 592, + EndIncludingLineBreak: 593, + Span: { + Start: 565, + Length: 27 + }, + SpanIncludingLineBreak: { + Start: 565, + Length: 28 + } + }, + { + LineNumber: 17, + Start: 593, + End: 618, + EndIncludingLineBreak: 619, + Span: { + Start: 593, + Length: 25 + }, + SpanIncludingLineBreak: { + Start: 593, + Length: 26 + } + }, + { + LineNumber: 18, + Start: 619, + End: 624, + EndIncludingLineBreak: 625, + Span: { + Start: 619, + Length: 5 + }, + SpanIncludingLineBreak: { + Start: 619, + Length: 6 + } + }, + { + LineNumber: 19, + Start: 625, + End: 627, + EndIncludingLineBreak: 628, + Span: { + Start: 625, + Length: 2 + }, + SpanIncludingLineBreak: { + Start: 625, + Length: 3 + } + }, + { + LineNumber: 20, + Start: 628, + End: 629, + EndIncludingLineBreak: 630, + Span: { + Start: 628, + Length: 1 + }, + SpanIncludingLineBreak: { + Start: 628, + Length: 2 + } + }, + { + LineNumber: 21, + Start: 630, + End: 636, + EndIncludingLineBreak: 637, + Span: { + Start: 630, + Length: 6 + }, + SpanIncludingLineBreak: { + Start: 630, + Length: 7 + } + }, + { + LineNumber: 22, + Start: 637, + End: 637, + EndIncludingLineBreak: 637, + Span: { + Start: 637 + }, + SpanIncludingLineBreak: { + Start: 637 + } + } + ] + }, + HintName: __BuildProperties.g.cs + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.cs b/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.cs new file mode 100644 index 0000000000..b952748dd5 --- /dev/null +++ b/test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.cs @@ -0,0 +1,115 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.VisualStudio.TestPlatform.TestHost; + +namespace Sentry.SourceGenerators.Tests; + + +public class BuildPropertySourceGeneratorTests +{ + [SkippableFact] + public Task RunResult_Success() + { + Skip.If(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + + var driver = BuildDriver(typeof(Program).Assembly, ("PublishAot", "false"), ("OutputType", "exe")); + var result = driver.GetRunResult().Results.FirstOrDefault(); + result.Exception.Should().BeNull(); + result.GeneratedSources.Length.Should().Be(1); + result.GeneratedSources.First().HintName.Should().Be("__BuildProperties.g.cs"); + return Verify(result); + } + + + [SkippableFact] + public Task RunResult_BadStrings() + { + Skip.If(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + + // we're hijacking PublishAot to make life easy + var driver = BuildDriver(typeof(Program).Assembly, ("My\\Key", "test\\test"), ("OutputType", "exe")); + var result = driver.GetRunResult().Results.FirstOrDefault(); + result.Exception.Should().BeNull(); + result.GeneratedSources.Length.Should().Be(1); + result.GeneratedSources.First().HintName.Should().Be("__BuildProperties.g.cs"); + return Verify(result); + } + + + [SkippableFact] + public Task RunResult_Publish_AotTrue() + { + Skip.If(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + + var driver = BuildDriver(typeof(Program).Assembly, ("PublishAot", "true"), ("OutputType", "exe")); + var result = driver.GetRunResult().Results.FirstOrDefault(); + result.Exception.Should().BeNull(); + result.GeneratedSources.Length.Should().Be(1); + result.GeneratedSources.First().HintName.Should().Be("__BuildProperties.g.cs"); + return Verify(result); + } + + + [SkippableTheory] + [InlineData("no", true)] + [InlineData("true", false)] + [InlineData("false", true)] + public void RunResult_SentryDisableSourceGenerator_Values(string value, bool sourceGenExpected) + { + Skip.If(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + + var driver = BuildDriver(typeof(Program).Assembly, ("SentryDisableSourceGenerator", value), ("OutputType", "exe")); + var result = driver.GetRunResult().Results.FirstOrDefault(); + result.Exception.Should().BeNull(); + + var generated = result.GeneratedSources.Any(x => x.HintName.Equals("__BuildProperties.g.cs")); + generated.Should().Be(sourceGenExpected); + } + + + [SkippableFact] + public Task RunResult_Expect_None() + { + Skip.If(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + + var driver = BuildDriver(typeof(Program).Assembly, ("PublishAot", "false")); + var result = driver.GetRunResult().Results.FirstOrDefault(); + result.Exception.Should().BeNull(); + result.GeneratedSources.Length.Should().Be(0); + + return Verify(result); + } + + + private static GeneratorDriver BuildDriver(Assembly metadataAssembly, params IEnumerable<(string Key, string Value)> buildProperties) + { + var metadataReference = MetadataReference.CreateFromFile(metadataAssembly.Location); + var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); + var compilation = CSharpCompilation.Create("TestAssembly", [], [metadataReference], options); + var generator = new BuildPropertySourceGenerator(); + + var dict = buildProperties.ToDictionary(x => "build_property." + x.Key, x => x.Value, comparer: StringComparer.InvariantCultureIgnoreCase); + var provider = new MockAnalyzerConfigOptionsProvider(dict); + + var driver = CSharpGeneratorDriver.Create([generator], optionsProvider: provider); + return driver.RunGenerators(compilation); + } +} + +file class MockAnalyzerConfigOptionsProvider(Dictionary buildProperties) : AnalyzerConfigOptionsProvider +{ + private readonly MockAnalyzerConfigOptions _options = new(buildProperties); + + public override AnalyzerConfigOptions GetOptions(SyntaxTree tree) => _options; + public override AnalyzerConfigOptions GetOptions(AdditionalText textFile) => _options; + public override AnalyzerConfigOptions GlobalOptions => _options; +} + +file class MockAnalyzerConfigOptions(Dictionary values) : AnalyzerConfigOptions +{ + public override bool TryGetValue(string key, [NotNullWhen(true)] out string? value) + => values.TryGetValue(key, out value); + + public override IEnumerable Keys => values.Keys; +} diff --git a/test/Sentry.SourceGenerators.Tests/Sentry.SourceGenerators.Tests.csproj b/test/Sentry.SourceGenerators.Tests/Sentry.SourceGenerators.Tests.csproj new file mode 100644 index 0000000000..820c77dd05 --- /dev/null +++ b/test/Sentry.SourceGenerators.Tests/Sentry.SourceGenerators.Tests.csproj @@ -0,0 +1,22 @@ + + + + net9.0;net8.0 + enable + enable + + + + + + + + + + + + + + + + diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt index 925a97874c..f70df81000 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt @@ -1285,6 +1285,14 @@ namespace Sentry.Ben.BlockingDetector public void Dispose() { } } } +namespace Sentry.CompilerServices +{ + public static class BuildProperties + { + public static System.Collections.Generic.IReadOnlyDictionary? Values { get; } + public static void Initialize(System.Collections.Generic.Dictionary properties) { } + } +} namespace Sentry.Extensibility { public abstract class BaseRequestPayloadExtractor : Sentry.Extensibility.IRequestPayloadExtractor diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt index 925a97874c..f70df81000 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt @@ -1285,6 +1285,14 @@ namespace Sentry.Ben.BlockingDetector public void Dispose() { } } } +namespace Sentry.CompilerServices +{ + public static class BuildProperties + { + public static System.Collections.Generic.IReadOnlyDictionary? Values { get; } + public static void Initialize(System.Collections.Generic.Dictionary properties) { } + } +} namespace Sentry.Extensibility { public abstract class BaseRequestPayloadExtractor : Sentry.Extensibility.IRequestPayloadExtractor diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt index 583b80f350..3060d147e9 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt @@ -1266,6 +1266,14 @@ namespace Sentry.Ben.BlockingDetector public void Dispose() { } } } +namespace Sentry.CompilerServices +{ + public static class BuildProperties + { + public static System.Collections.Generic.IReadOnlyDictionary? Values { get; } + public static void Initialize(System.Collections.Generic.Dictionary properties) { } + } +} namespace Sentry.Extensibility { public abstract class BaseRequestPayloadExtractor : Sentry.Extensibility.IRequestPayloadExtractor diff --git a/test/Sentry.Tests/Sentry.Tests.csproj b/test/Sentry.Tests/Sentry.Tests.csproj index d2c5db0dfc..d2e0edd2a5 100644 --- a/test/Sentry.Tests/Sentry.Tests.csproj +++ b/test/Sentry.Tests/Sentry.Tests.csproj @@ -42,5 +42,4 @@ -