cake-build / cake

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

"Index was outside the bounds of the array" from dotnet CLI #1927

Open kimbell opened 6 years ago

kimbell commented 6 years ago

I'm running Cake 0.23.0 locally on Windows 10 Pro 64 bit version.

In my Cake script I've been using "" for the project in order to let the CLI tools figure out things. I basically want to build everything.

DotNetCoreBuild("", new DotNetCoreBuildSettings   
    {
        Configuration = configuration,
        MSBuildSettings = msBuildSettings
    });

This worked fine with the 1.1 tooling, but fails with the 2.0 tooling.

Turning on diagnostics information, I see that following command is being called "C:/Program Files/dotnet/dotnet.exe" build "" --configuration Release /property:AssemblyVersion=1.0.2.1 /property:FileVersion=1.0.2.1 /property:PackageVersion=1.0.2.1

Note the "" after build. If I remove them, things work fine. If I try to pass inn null in the Cake script, I get an ArgumentNullException.

I had a look at the code and think I've spotted the problem in https://github.com/cake-build/cake/blob/develop/src/Cake.Common/Tools/DotNetCore/Build/DotNetCoreBuilder.cs

The Build() method has a null check for project, but when you look at the GetArguments() method, you can see that also has a null check for project. If it's not defined, you don't escape an empty string.

From what I can tell, it should only be a matter of removing the null check from the Build() method.

 public void Build(string project, DotNetCoreBuildSettings settings)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            RunCommand(settings, GetArguments(project, settings));
        }

        private ProcessArgumentBuilder GetArguments(string project, DotNetCoreBuildSettings settings)
        {
            var builder = CreateArgumentBuilder(settings);

            builder.Append("build");

            // Specific path?
            if (project != null)
            {
                builder.AppendQuoted(project);
            }

            // Output directory
            if (settings.OutputDirectory != null)
            {
                builder.Append("--output");
                builder.AppendQuoted(settings.OutputDirectory.MakeAbsolute(_environment).FullPath);
            }
========================================
Build
========================================
Executing task: Build
Executing: "C:/Program Files/dotnet/dotnet.exe" build "" --configuration Release /property:AssemblyVersion=1.0.2.1 /prop
erty:FileVersion=1.0.2.1 /property:PackageVersion=1.0.2.1
System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.String.get_Chars(Int32 index)
   at Microsoft.DotNet.Cli.CommandLine.StringExtensions.HasPrefix(String arg)
   at Microsoft.DotNet.Cli.CommandLine.StringExtensions.<Lex>d__7.MoveNext()
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source, Int32& length)
   at System.Collections.Generic.Queue`1..ctor(IEnumerable`1 collection)
   at Microsoft.DotNet.Cli.CommandLine.Parser.Parse(IReadOnlyCollection`1 rawArgs, Boolean isProgressive)
   at Microsoft.DotNet.Cli.CommandLine.Parser.Parse(String[] args)
   at Microsoft.DotNet.Cli.ParserExtensions.ParseFrom(Parser parser, String context, String[] args)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
   at Microsoft.DotNet.Cli.Program.Main(String[] args)
An error occurred when executing task 'Build'.
Error: System.AggregateException: One or more errors occurred. ---> Cake.Core.CakeException: .NET Core CLI: Process retu
rned an error (exit code 1).
   at Cake.Core.Tooling.Tool`1.ProcessExitCode(Int32 exitCode)
   at Cake.Core.Tooling.Tool`1.Run(TSettings settings, ProcessArgumentBuilder arguments, ProcessSettings processSettings
, Action`1 postAction)
   at Cake.Common.Tools.DotNetCore.Build.DotNetCoreBuilder.Build(String project, DotNetCoreBuildSettings settings)
   at Submission#0.DotNetCoreBuild(String project, DotNetCoreBuildSettings settings)
   at Submission#0.<<Initialize>>b__0_2()
   at Cake.Core.CakeTaskBuilderExtensions.<>c__DisplayClass8_0.<Does>b__0(ICakeContext x)
   at Cake.Core.ActionTask.<Execute>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Cake.Core.DefaultExecutionStrategy.<ExecuteAsync>d__4.MoveNext()
nick4fake commented 6 years ago

Looks like a bug in dotnet. We experience similar behavior:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.String.get_Chars(Int32 index)
   at Microsoft.DotNet.Cli.CommandLine.StringExtensions.HasPrefix(String arg)
   at Microsoft.DotNet.Cli.CommandLine.StringExtensions.<Lex>d__7.MoveNext()
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source, Int32& length)
   at System.Collections.Generic.Queue`1..ctor(IEnumerable`1 collection)
   at Microsoft.DotNet.Cli.CommandLine.Parser.Parse(IReadOnlyCollection`1 rawArgs, Boolean isProgressive)
   at Microsoft.DotNet.Cli.CommandLine.Parser.Parse(String[] args)
   at Microsoft.DotNet.Cli.ParserExtensions.ParseFrom(Parser parser, String context, String[] args)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
   at Microsoft.DotNet.Cli.Program.Main(String[] args)
tugberkugurlu commented 6 years ago

I am getting the same:

Time Elapsed 00:00:02.24
System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.String.get_Chars(Int32 index)
   at Microsoft.DotNet.Cli.CommandLine.StringExtensions.HasPrefix(String arg)
   at Microsoft.DotNet.Cli.CommandLine.StringExtensions.<Lex>d__7.MoveNext()
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source, Int32& length)
   at System.Collections.Generic.Queue`1..ctor(IEnumerable`1 collection)
   at Microsoft.DotNet.Cli.CommandLine.Parser.Parse(IReadOnlyCollection`1 rawArgs, Boolean isProgressive)
   at Microsoft.DotNet.Cli.CommandLine.Parser.Parse(String[] args)
   at Microsoft.DotNet.Cli.ParserExtensions.ParseFrom(Parser parser, String context, String[] args)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
   at Microsoft.DotNet.Cli.Program.Main(String[] args)

when running:

dotnet build $scriptsDir --configuration RELEASE --verbosity normal --version-suffix '' /property:VersionPrefix=0.0.0

I have this version.props which I am referencing from all projects:

<!-- This file may be overwritten by automation. Only values allowed here are VersionPrefix and VersionSuffix.  -->
<Project>
    <PropertyGroup>
        <VersionPrefix>0.0.0</VersionPrefix>
        <VersionSuffix>dev</VersionSuffix>
    </PropertyGroup>
</Project>

Let me know if you need anything else from me to repro this. I will try to get a clean repro project as well.

tugberkugurlu commented 6 years ago

This worked as expected:

dotnet build $scriptsDir --configuration RELEASE --verbosity normal /property:VersionPrefix=0.0.0 /property:VersionSuffix=''
patriksvensson commented 6 years ago

@kimbell Have you tried pointing dotnet build at the solution file? That's what I generally do.