cake-build / cake

:cake: Cake (C# Make) is a cross platform build automation system.
https://cakebuild.net
MIT License
3.84k stars 722 forks source link

Execution of Cake script fails if an addin defines an alias that uses nullable reference types in its signature #4197

Closed ap0llo closed 7 months ago

ap0llo commented 11 months ago

Prerequisites

Cake runner

Cake .NET Tool

Cake version

3.1

Operating system

Windows

Operating system architecture

64-Bit

CI Server

No response

What are you seeing?

I created an alias with an parameter that is allowed to be null and is thus marked as nullable, e.g.

namespace ExampleAddin;

[CakeAliasCategory("Example")]
public static class HelloWorldAliases
{
    [CakeMethodAlias]
    public static void HelloWorld(this ICakeContext context, string? parameter)
    {

    }
}

When the assembly that contains the alias is used in a Cake script, compilation of the script fails with the following error(s)

Error: Error(s) occurred when compiling build script:
(3465,57): error CS0234: The type or namespace name 'NullableAttribute' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?)
(3465,57): error CS0234: The type or namespace name 'Nullable' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?)

What is expected?

I would expect the script to be executed successfully, even is nullable reference types do not seem to be enabled in the scripting runner.

Steps to Reproduce

I prepared a repo here: https://github.com/ap0llo/repro-cake-nullable-reference-types-in-alias

I added a little more detailed instructions on how to run the repo in the repository's README

Output log

Looking for modules...
No modules found to install.
Module directory does not exist.
Analyzing build script...
Analyzing C:/.../CakeScript/build.cake...
Processing build script...
Verifying assembly 'ExampleAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Adding assembly reference to System.Private.CoreLib.dll...
Adding assembly reference to System.Linq.Expressions.dll...
Adding assembly reference to Microsoft.CSharp.dll...
Adding assembly reference to System.Runtime.dll...
Adding assembly reference to System.Runtime.InteropServices.dll...
Adding assembly reference to System.Collections.dll...
Adding assembly reference to System.Threading.dll...
Adding assembly reference to System.Memory.dll...
Adding assembly reference to System.Collections.Concurrent.dll...
Adding assembly reference to System.Linq.dll...
Adding assembly reference to System.Reflection.Emit.dll...
Adding assembly reference to Microsoft.VisualBasic.Core.dll...
Adding assembly reference to System.Reflection.Emit.Lightweight.dll...
Adding assembly reference to System.Reflection.Emit.ILGeneration.dll...
Adding assembly reference to System.Reflection.Primitives.dll...
Adding assembly reference to System.ObjectModel.dll...
Adding assembly reference to System.Threading.Thread.dll...
Adding assembly reference to System.IO.FileSystem.DriveInfo.dll...
Adding assembly reference to System.Collections.Specialized.dll...
Adding assembly reference to System.Diagnostics.Process.dll...
Adding assembly reference to Microsoft.Win32.Primitives.dll...
Adding assembly reference to System.ComponentModel.Primitives.dll...
Adding assembly reference to System.Text.RegularExpressions.dll...
Adding assembly reference to System.Collections.NonGeneric.dll...
Adding assembly reference to Microsoft.Win32.Registry.dll...
Adding assembly reference to Microsoft.VisualBasic.dll...
Adding assembly reference to System.Security.AccessControl.dll...
Adding assembly reference to System.Security.Principal.Windows.dll...
Adding assembly reference to mscorlib.dll...
Adding assembly reference to netstandard.dll...
Adding assembly reference to System.IO.MemoryMappedFiles.dll...
Adding assembly reference to System.IO.Pipes.dll...
Adding assembly reference to System.Security.Cryptography.dll...
Adding assembly reference to System.ComponentModel.TypeConverter.dll...
Adding assembly reference to System.ComponentModel.EventBasedAsync.dll...
Adding assembly reference to System.ComponentModel.dll...
Adding assembly reference to System.Console.dll...
Adding assembly reference to System.Data.Common.dll...
Adding assembly reference to System.Diagnostics.TraceSource.dll...
Adding assembly reference to System.Diagnostics.Contracts.dll...
Adding assembly reference to System.Diagnostics.TextWriterTraceListener.dll...
Adding assembly reference to System.Diagnostics.FileVersionInfo.dll...
Adding assembly reference to System.Diagnostics.StackTrace.dll...
Adding assembly reference to System.Diagnostics.Tracing.dll...
Adding assembly reference to System.Drawing.Primitives.dll...
Adding assembly reference to System.IO.Compression.Brotli.dll...
Adding assembly reference to System.IO.Compression.dll...
Adding assembly reference to System.IO.Compression.ZipFile.dll...
Adding assembly reference to System.IO.FileSystem.Watcher.dll...
Adding assembly reference to System.IO.IsolatedStorage.dll...
Adding assembly reference to System.Linq.Queryable.dll...
Adding assembly reference to System.Linq.Parallel.dll...
Adding assembly reference to System.Net.Requests.dll...
Adding assembly reference to System.Net.Primitives.dll...
Adding assembly reference to System.Net.HttpListener.dll...
Adding assembly reference to System.Net.ServicePoint.dll...
Adding assembly reference to System.Net.NameResolution.dll...
Adding assembly reference to System.Net.WebClient.dll...
Adding assembly reference to System.Net.Http.dll...
Adding assembly reference to System.Net.WebHeaderCollection.dll...
Adding assembly reference to System.Net.WebProxy.dll...
Adding assembly reference to System.Net.Mail.dll...
Adding assembly reference to System.Net.NetworkInformation.dll...
Adding assembly reference to System.Net.Ping.dll...
Adding assembly reference to System.Net.Security.dll...
Adding assembly reference to System.Net.Sockets.dll...
Adding assembly reference to System.Net.WebSockets.Client.dll...
Adding assembly reference to System.Net.WebSockets.dll...
Adding assembly reference to System.Runtime.Numerics.dll...
Adding assembly reference to System.Numerics.Vectors.dll...
Adding assembly reference to System.Reflection.DispatchProxy.dll...
Adding assembly reference to System.Resources.Writer.dll...
Adding assembly reference to System.Runtime.CompilerServices.VisualC.dll...
Adding assembly reference to System.Runtime.Serialization.Primitives.dll...
Adding assembly reference to System.Runtime.Serialization.Xml.dll...
Adding assembly reference to System.Runtime.Serialization.Json.dll...
Adding assembly reference to System.Runtime.Serialization.Formatters.dll...
Adding assembly reference to System.Security.Claims.dll...
Adding assembly reference to System.Text.Encoding.Extensions.dll...
Adding assembly reference to System.Threading.Overlapped.dll...
Adding assembly reference to System.Threading.ThreadPool.dll...
Adding assembly reference to System.Threading.Tasks.Parallel.dll...
Adding assembly reference to System.Transactions.Local.dll...
Adding assembly reference to System.Web.HttpUtility.dll...
Adding assembly reference to System.Xml.ReaderWriter.dll...
Adding assembly reference to System.Xml.XDocument.dll...
Adding assembly reference to System.Xml.XmlSerializer.dll...
Adding assembly reference to System.Xml.XPath.XDocument.dll...
Adding assembly reference to System.Xml.XPath.dll...
Adding assembly reference to System.AppContext.dll...
Adding assembly reference to System.Buffers.dll...
Adding assembly reference to System.Collections.Immutable.dll...
Adding assembly reference to System.ComponentModel.Annotations.dll...
Adding assembly reference to System.ComponentModel.DataAnnotations.dll...
Adding assembly reference to System.Runtime.Loader.dll...
Adding assembly reference to System.Configuration.dll...
Adding assembly reference to System.Core.dll...
Adding assembly reference to System.Private.Uri.dll...
Adding assembly reference to System.Data.DataSetExtensions.dll...
Adding assembly reference to System.Data.dll...
Adding assembly reference to System.Diagnostics.Debug.dll...
Adding assembly reference to System.Diagnostics.DiagnosticSource.dll...
Adding assembly reference to System.Reflection.Metadata.dll...
Adding assembly reference to System.Diagnostics.Tools.dll...
Adding assembly reference to System.dll...
Adding assembly reference to System.Drawing.dll...
Adding assembly reference to System.Dynamic.Runtime.dll...
Adding assembly reference to System.Formats.Asn1.dll...
Adding assembly reference to System.Formats.Tar.dll...
Adding assembly reference to System.Globalization.Calendars.dll...
Adding assembly reference to System.Globalization.dll...
Adding assembly reference to System.Globalization.Extensions.dll...
Adding assembly reference to System.IO.Compression.FileSystem.dll...
Adding assembly reference to System.IO.dll...
Adding assembly reference to System.IO.FileSystem.AccessControl.dll...
Adding assembly reference to System.IO.FileSystem.dll...
Adding assembly reference to System.IO.FileSystem.Primitives.dll...
Adding assembly reference to System.IO.Pipes.AccessControl.dll...
Adding assembly reference to System.IO.UnmanagedMemoryStream.dll...
Adding assembly reference to System.Net.dll...
Adding assembly reference to System.Net.Quic.dll...
Adding assembly reference to System.Threading.Channels.dll...
Adding assembly reference to System.Net.Http.Json.dll...
Adding assembly reference to System.Text.Json.dll...
Adding assembly reference to System.Numerics.dll...
Adding assembly reference to System.Reflection.dll...
Adding assembly reference to System.Reflection.Extensions.dll...
Adding assembly reference to System.Reflection.TypeExtensions.dll...
Adding assembly reference to System.Resources.Reader.dll...
Adding assembly reference to System.Resources.ResourceManager.dll...
Adding assembly reference to System.Runtime.CompilerServices.Unsafe.dll...
Adding assembly reference to System.Runtime.Extensions.dll...
Adding assembly reference to System.Runtime.Handles.dll...
Adding assembly reference to System.Runtime.InteropServices.JavaScript.dll...
Adding assembly reference to System.Runtime.InteropServices.RuntimeInformation.dll...
Adding assembly reference to System.Runtime.Intrinsics.dll...
Adding assembly reference to System.Runtime.Serialization.dll...
Adding assembly reference to System.Private.DataContractSerialization.dll...
Adding assembly reference to System.Security.Cryptography.Algorithms.dll...
Adding assembly reference to System.Security.Cryptography.Cng.dll...
Adding assembly reference to System.Security.Cryptography.Csp.dll...
Adding assembly reference to System.Security.Cryptography.Encoding.dll...
Adding assembly reference to System.Security.Cryptography.OpenSsl.dll...
Adding assembly reference to System.Security.Cryptography.Primitives.dll...
Adding assembly reference to System.Security.Cryptography.X509Certificates.dll...
Adding assembly reference to System.Security.dll...
Adding assembly reference to System.Security.Principal.dll...
Adding assembly reference to System.Security.SecureString.dll...
Adding assembly reference to System.ServiceModel.Web.dll...
Adding assembly reference to System.ServiceProcess.dll...
Adding assembly reference to System.Text.Encoding.CodePages.dll...
Adding assembly reference to System.Text.Encoding.dll...
Adding assembly reference to System.Text.Encodings.Web.dll...
Adding assembly reference to System.Threading.Tasks.Dataflow.dll...
Adding assembly reference to System.Threading.Tasks.dll...
Adding assembly reference to System.Threading.Tasks.Extensions.dll...
Adding assembly reference to System.Threading.Timer.dll...
Adding assembly reference to System.Transactions.dll...
Adding assembly reference to System.ValueTuple.dll...
Adding assembly reference to System.Web.dll...
Adding assembly reference to System.Windows.dll...
Adding assembly reference to System.Xml.dll...
Adding assembly reference to System.Xml.Linq.dll...
Adding assembly reference to System.Private.Xml.dll...
Adding assembly reference to System.Xml.Serialization.dll...
Adding assembly reference to System.Private.Xml.Linq.dll...
Adding assembly reference to System.Xml.XmlDocument.dll...
Adding assembly reference to WindowsBase.dll...
Adding assembly reference to Cake.Core.dll...
Adding assembly reference to Cake.Common.dll...
Adding assembly reference to Spectre.Console.dll...
Adding assembly reference to ExampleAddin.dll...
Importing namespace Cake.Common...
Importing namespace Cake.Common.Build...
Importing namespace Cake.Common.Build.AppVeyor...
Importing namespace Cake.Common.Build.AppVeyor.Data...
Importing namespace Cake.Common.Build.AzurePipelines...
Importing namespace Cake.Common.Build.AzurePipelines.Data...
Importing namespace Cake.Common.Build.Bamboo...
Importing namespace Cake.Common.Build.Bamboo.Data...
Importing namespace Cake.Common.Build.BitbucketPipelines...
Importing namespace Cake.Common.Build.BitbucketPipelines.Data...
Importing namespace Cake.Common.Build.Bitrise...
Importing namespace Cake.Common.Build.Bitrise.Data...
Importing namespace Cake.Common.Build.ContinuaCI...
Importing namespace Cake.Common.Build.ContinuaCI.Data...
Importing namespace Cake.Common.Build.GitHubActions...
Importing namespace Cake.Common.Build.GitHubActions.Data...
Importing namespace Cake.Common.Build.GitLabCI...
Importing namespace Cake.Common.Build.GitLabCI.Data...
Importing namespace Cake.Common.Build.GoCD...
Importing namespace Cake.Common.Build.GoCD.Data...
Importing namespace Cake.Common.Build.Jenkins...
Importing namespace Cake.Common.Build.Jenkins.Data...
Importing namespace Cake.Common.Build.MyGet...
Importing namespace Cake.Common.Build.TeamCity...
Importing namespace Cake.Common.Build.TravisCI...
Importing namespace Cake.Common.Build.TravisCI.Data...
Importing namespace Cake.Common.Diagnostics...
Importing namespace Cake.Common.IO...
Importing namespace Cake.Common.IO.Paths...
Importing namespace Cake.Common.Net...
Importing namespace Cake.Common.Security...
Importing namespace Cake.Common.Solution...
Importing namespace Cake.Common.Solution.Project...
Importing namespace Cake.Common.Solution.Project.Properties...
Importing namespace Cake.Common.Solution.Project.XmlDoc...
Importing namespace Cake.Common.Text...
Importing namespace Cake.Common.Tools.Cake...
Importing namespace Cake.Common.Tools.Chocolatey...
Importing namespace Cake.Common.Tools.Chocolatey.ApiKey...
Importing namespace Cake.Common.Tools.Chocolatey.Config...
Importing namespace Cake.Common.Tools.Chocolatey.Download...
Importing namespace Cake.Common.Tools.Chocolatey.Export...
Importing namespace Cake.Common.Tools.Chocolatey.Features...
Importing namespace Cake.Common.Tools.Chocolatey.Install...
Importing namespace Cake.Common.Tools.Chocolatey.New...
Importing namespace Cake.Common.Tools.Chocolatey.Pack...
Importing namespace Cake.Common.Tools.Chocolatey.Pin...
Importing namespace Cake.Common.Tools.Chocolatey.Push...
Importing namespace Cake.Common.Tools.Chocolatey.Sources...
Importing namespace Cake.Common.Tools.Chocolatey.Uninstall...
Importing namespace Cake.Common.Tools.Chocolatey.Upgrade...
Importing namespace Cake.Common.Tools.Command...
Importing namespace Cake.Common.Tools.DotCover...
Importing namespace Cake.Common.Tools.DotCover.Analyse...
Importing namespace Cake.Common.Tools.DotCover.Cover...
Importing namespace Cake.Common.Tools.DotCover.Merge...
Importing namespace Cake.Common.Tools.DotCover.Report...
Importing namespace Cake.Common.Tools.DotNet...
Importing namespace Cake.Common.Tools.DotNet.Build...
Importing namespace Cake.Common.Tools.DotNet.BuildServer...
Importing namespace Cake.Common.Tools.DotNet.Clean...
Importing namespace Cake.Common.Tools.DotNet.Execute...
Importing namespace Cake.Common.Tools.DotNet.Format...
Importing namespace Cake.Common.Tools.DotNet.MSBuild...
Importing namespace Cake.Common.Tools.DotNet.NuGet.Delete...
Importing namespace Cake.Common.Tools.DotNet.NuGet.Push...
Importing namespace Cake.Common.Tools.DotNet.NuGet.Source...
Importing namespace Cake.Common.Tools.DotNet.Pack...
Importing namespace Cake.Common.Tools.DotNet.Publish...
Importing namespace Cake.Common.Tools.DotNet.Restore...
Importing namespace Cake.Common.Tools.DotNet.Run...
Importing namespace Cake.Common.Tools.DotNet.SDKCheck...
Importing namespace Cake.Common.Tools.DotNet.Test...
Importing namespace Cake.Common.Tools.DotNet.Tool...
Importing namespace Cake.Common.Tools.DotNet.VSTest...
Importing namespace Cake.Common.Tools.DotNet.Workload.Install...
Importing namespace Cake.Common.Tools.DotNet.Workload.List...
Importing namespace Cake.Common.Tools.DotNet.Workload.Repair...
Importing namespace Cake.Common.Tools.DotNet.Workload.Restore...
Importing namespace Cake.Common.Tools.DotNet.Workload.Search...
Importing namespace Cake.Common.Tools.DotNet.Workload.Uninstall...
Importing namespace Cake.Common.Tools.DotNet.Workload.Update...
Importing namespace Cake.Common.Tools.DupFinder...
Importing namespace Cake.Common.Tools.Fixie...
Importing namespace Cake.Common.Tools.GitLink...
Importing namespace Cake.Common.Tools.GitReleaseManager...
Importing namespace Cake.Common.Tools.GitReleaseManager.AddAssets...
Importing namespace Cake.Common.Tools.GitReleaseManager.Close...
Importing namespace Cake.Common.Tools.GitReleaseManager.Create...
Importing namespace Cake.Common.Tools.GitReleaseManager.Discard...
Importing namespace Cake.Common.Tools.GitReleaseManager.Export...
Importing namespace Cake.Common.Tools.GitReleaseManager.Label...
Importing namespace Cake.Common.Tools.GitReleaseManager.Open...
Importing namespace Cake.Common.Tools.GitReleaseManager.Publish...
Importing namespace Cake.Common.Tools.GitReleaseNotes...
Importing namespace Cake.Common.Tools.GitVersion...
Importing namespace Cake.Common.Tools.ILMerge...
Importing namespace Cake.Common.Tools.ILRepack...
Importing namespace Cake.Common.Tools.InnoSetup...
Importing namespace Cake.Common.Tools.InspectCode...
Importing namespace Cake.Common.Tools.MSBuild...
Importing namespace Cake.Common.Tools.MSpec...
Importing namespace Cake.Common.Tools.MSTest...
Importing namespace Cake.Common.Tools.NSIS...
Importing namespace Cake.Common.Tools.NuGet...
Importing namespace Cake.Common.Tools.NuGet.Add...
Importing namespace Cake.Common.Tools.NuGet.Delete...
Importing namespace Cake.Common.Tools.NuGet.Init...
Importing namespace Cake.Common.Tools.NuGet.Install...
Importing namespace Cake.Common.Tools.NuGet.List...
Importing namespace Cake.Common.Tools.NuGet.Pack...
Importing namespace Cake.Common.Tools.NuGet.Push...
Importing namespace Cake.Common.Tools.NuGet.Restore...
Importing namespace Cake.Common.Tools.NuGet.SetApiKey...
Importing namespace Cake.Common.Tools.NuGet.SetProxy...
Importing namespace Cake.Common.Tools.NuGet.Sources...
Importing namespace Cake.Common.Tools.NuGet.Update...
Importing namespace Cake.Common.Tools.NUnit...
Importing namespace Cake.Common.Tools.OctopusDeploy...
Importing namespace Cake.Common.Tools.OpenCover...
Importing namespace Cake.Common.Tools.ReportGenerator...
Importing namespace Cake.Common.Tools.ReportUnit...
Importing namespace Cake.Common.Tools.Roundhouse...
Importing namespace Cake.Common.Tools.SignTool...
Importing namespace Cake.Common.Tools.SpecFlow...
Importing namespace Cake.Common.Tools.SpecFlow.StepDefinitionReport...
Importing namespace Cake.Common.Tools.SpecFlow.TestExecutionReport...
Importing namespace Cake.Common.Tools.TextTransform...
Importing namespace Cake.Common.Tools.VSTest...
Importing namespace Cake.Common.Tools.VSWhere...
Importing namespace Cake.Common.Tools.VSWhere.All...
Importing namespace Cake.Common.Tools.VSWhere.Latest...
Importing namespace Cake.Common.Tools.VSWhere.Legacy...
Importing namespace Cake.Common.Tools.VSWhere.Product...
Importing namespace Cake.Common.Tools.WiX...
Importing namespace Cake.Common.Tools.WiX.Heat...
Importing namespace Cake.Common.Tools.XBuild...
Importing namespace Cake.Common.Tools.XUnit...
Importing namespace Cake.Common.Xml...
Importing namespace Cake.Core...
Importing namespace Cake.Core.Diagnostics...
Importing namespace Cake.Core.IO...
Importing namespace Cake.Core.Scripting...
Importing namespace Cake.Core.Tooling...
Importing namespace ExampleAddin...
Importing namespace System...
Importing namespace System.Collections.Generic...
Importing namespace System.IO...
Importing namespace System.Linq...
Importing namespace System.Text...
Importing namespace System.Threading.Tasks...
Compiling build script...
(3465,57): error CS0234: The type or namespace name 'NullableAttribute' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?)
(3465,57): error CS0234: The type or namespace name 'Nullable' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?)
Error: Cake.Core.CakeException: Error(s) occurred when compiling build script:
(3465,57): error CS0234: The type or namespace name 'NullableAttribute' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?)
(3465,57): error CS0234: The type or namespace name 'Nullable' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?)
   at Cake.Infrastructure.Scripting.RoslynScriptSession.Execute(Script script) in C:\projects\cake\src\Cake\Infrastructure\Scripting\RoslynScriptSession.cs:line 186
   at Cake.Core.Scripting.ScriptRunner.Run(IScriptHost host, FilePath scriptPath) in C:\projects\cake\src\Cake.Core\Scripting\ScriptRunner.cs:line 172
   at Cake.Features.Building.BuildFeature.RunCore(IRemainingArguments arguments, BuildFeatureSettings settings) in C:\projects\cake\src\Cake\Features\Building\BuildFeature.cs:line 99
   at Cake.Features.Building.BuildFeature.Run(IRemainingArguments arguments, BuildFeatureSettings settings) in C:\projects\cake\src\Cake\Features\Building\BuildFeature.cs:line 49
   at Cake.Commands.DefaultCommand.Execute(CommandContext context, DefaultCommandSettings settings) in C:\projects\cake\src\Cake\Commands\DefaultCommand.cs:line 73
ap0llo commented 11 months ago

I tried to track down the problem by debugging into Cake.

The issue seems to be in ParameterEmitter.

It writes out all of the method parameter's attributes into the generated Cake script, including System.Runtime.CompilerServices.NullableAttribute. But the nullable attribute is a little special, since it does not seem to exist in the BCL but instead the C# compiler generates it into the addin assembly as internal class.

image

This attribute is thus not visible to the generated Cake script, causing the compilation error.

I could see multiple ways to fix this

I hope this information is helpful. I'd be happy in assisting with a bugfix and provide a PR once I know what the fix should look like

devlead commented 11 months ago

Ideally the proxy methods generated would have the same signature as the original addin extension method with the exception of the context being supplied.

The warnings could once be pragma disabled and enabled before and after method generation.

ap0llo commented 11 months ago

Ideally the proxy methods generated would have the same signature as the original addin extension method with the exception of the context being supplied.

The warnings could once be pragma disabled and enabled before and after method generation.

Okay, so that would point to special-casing the "Nullable" attribute and emitting a ? in the proper places. I'll see what I can come up with.

cake-build-bot commented 7 months ago

:tada: This issue has been resolved in version v4.0.0 :tada:

The release is available on:

Your GitReleaseManager bot :package::rocket: