nuke-build / nuke

🏗 The AKEless Build System for C#/.NET
https://nuke.build
MIT License
3.07k stars 367 forks source link

Problem calling Tool with two AbsolutePath's containing spaces. #1376

Closed bitzer-sbc closed 5 months ago

bitzer-sbc commented 6 months ago

Usage Information

Nuke 8.0.0 / SDK 8.0.200 / Net8.0 / Windows 10 Pro 22H2

Description

I have many Nuke scripts where this works with Tools like Git. But in this particular case, I use a Tool instantiated with ToolResolver.GetTool, and it gets the parameters all wrong.

Reproduction Steps

My Build project is in a path with spaces in one directory name (C:\projects\Nuke test). In real life the tool is an exe we built ourselves, but for the demo, I use xcopy.exe as a Tool and have the following code:

        Tool xcopy = ToolResolver.GetTool((AbsolutePath)@"C:" / "Windows" / "System32" / "xcopy.exe");
        xcopy($"{RootDirectory / "test.ps1"} {RootDirectory / "test.ps2"}");

Expected Behavior

I would expect Nuke to call: C:\Windows\System32\xcopy.exe "C:\projects\Nuke Test\test.ps1" "C:\projects\Nuke Test\test.ps2"

Actual Behavior

Nuke calls C:\Windows\System32\xcopy.exe C:\projects\Nuke Test\test.ps1" "C:\projects\Nuke Test\test.ps2

Nuke.Common.Tooling.ProcessException: Process 'xcopy.exe' exited with code 4.

C:\Windows\System32\xcopy.exe C:\projects\Nuke Test\test.ps1" "C:\projects\Nuke Test\test.ps2 @ C:\projects\Nuke Test Error output: Invalid number of parameters

Regression?

I don't know, but I often use Tool with paths including spaces, just not from ToolResolver.GetTool()

Known Workarounds

No response

Could you help with a pull-request?

No

bitzer-sbc commented 6 months ago

The problem is that both parameters have a space in their path. If only one has a space in the path, it works fine.

bitzer-sbc commented 6 months ago

In the Nuke.Tooling.Tests Project, extend the ArgumentStringHandlerTest with this Fact: [Fact] public void TestAbsolutePathsWithSpaces() { ArgsToString($"{(AbsolutePath)"C:" / "Some dir" / "file1.sh"} {(AbsolutePath)"C:" / "Some dir" / "file2.sh"}").Should().Be("\"C:\Some dir\file1.sh\" \"C:\Some dir\file2.sh\""); }

...and it will fail due to the extra TrimMatchingDoubleQuotes() in ArgumentStringHandler.ToStringAndClear()