8000 Merge pull request #629 from hrumhurum/gp-fix-a · dotnet-script/dotnet-script@bf52486 · GitHub
[go: up one dir, main page]

Skip to content

Commit bf52486

Browse files
authored
Merge pull request #629 from hrumhurum/gp-fix-a
Test issues when running from a folder containing a space character in its name
2 parents 34103f1 + 467eafd commit bf52486

File tree

6 files changed

+103
-9
lines changed

6 files changed

+103
-9
lines changed

src/Dotnet.Script.DependencyModel/Context/DotnetRestorer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Dotnet.Script.DependencyModel.Environment;
2+
using Dotnet.Script.DependencyModel.Internal;
23
using Dotnet.Script.DependencyModel.Logging;
34
using Dotnet.Script.DependencyModel.Process;
45
using Dotnet.Script.DependencyModel.ProjectSystem;
@@ -44,7 +45,7 @@ string CreatePackageSourcesArguments()
4445
{
4546
return packageSources.Length == 0
4647
? string.Empty
47-
: packageSources.Select(s => $"-s {s}")
48+
: packageSources.Select(s => $"-s {CommandLine.EscapeArgument(s)}")
4849
.Aggregate((current, next) => $"{current} {next}");
4950
}
5051

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using System;
2+
using System.Text;
3+
using System.Text.RegularExpressions;
4+
5+
namespace Dotnet.Script.DependencyModel.Internal
6+
{
7+
/// <summary>
8+
/// <para>
9+
/// Performs operations on <see cref="System.String"/> instances that contain command line information.
10+
/// </para>
11+
/// <para>
12+
/// Tip: a ready-to-use package with this functionality is available at https://www.nuget.org/packages/Gapotchenko.FX.Diagnostics.CommandLine.
13+
/// </para>
14+
/// </summary>
15+
/// <summary>
16+
/// Available
17+
/// </summary>
18+
static class CommandLine
19+
{
20+
/// <summary>
21+
/// Escapes and optionally quotes a command line argument.
22+
/// </summary>
23+
/// <param name="value">The command line argument.</param>
24+
/// <returns>The escaped and optionally quoted command line argument.</returns>
25+
public static string EscapeArgument(string value)
26+
{
27+
if (value == null)
28+
return null;
29+
30+
int length = value.Length;
31+
if (length == 0)
32+
return string.Empty;
33+
34+
var sb = new StringBuilder();
35+
Escape.AppendQuotedText(sb, value);
36+
37+
if (sb.Length == length)
38+
return value;
39+
40+
return sb.ToString();
41+
}
42+
43+
static class Escape
44+
{
45+
public static void AppendQuotedText(StringBuilder sb, string text)
46+
{
47+
bool quotingRequired = IsQuotingRequired(text);
48+
if (quotingRequired)
49+
sb.Append('"');
50+
51+
int numberOfQuotes = 0;
52+
for (int i = 0; i < text.Length; i++)
53+
{
54+
if (text[i] == '"')
55+
numberOfQuotes++;
56+
}
57+
58+
if (numberOfQuotes > 0)
59+
{
60+
if ((numberOfQuotes % 2) != 0)
61+
throw new Exception("Command line parameter cannot contain an odd number of double quotes.");
62+
text = text.Replace("\\\"", "\\\\\"").Replace("\"", "\\\"");
63+
}
64+
65+
sb.Append(text);
66+
67+
if (quotingRequired && text.EndsWith("\\"))
68+
sb.Append('\\');
69+
70+
if (quotingRequired)
71+
sb.Append('"');
72+
}
73+
74+
static bool IsQuotingRequired(string parameter) =>
75+
!AllowedUnquotedRegex.IsMatch(parameter) ||
76+
DefinitelyNeedQuotesRegex.IsMatch(parameter);
77+
78+
static Regex m_CachedAllowedUnquotedRegex;
79+
80+
static Regex AllowedUnquotedRegex =>
81+
m_CachedAllowedUnquotedRegex ??= new Regex(
82+
@"^[a-z\\/:0-9\._\-+=]*$",
83+
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
84+
85+
static Regex m_CachedDefinitelyNeedQuotesRegex;
86+
87+
static Regex DefinitelyNeedQuotesRegex =>
88+
m_CachedDefinitelyNeedQuotesRegex ??= new Regex(
89+
"[|><\\s,;\"]+",
90+
RegexOptions.CultureInvariant);
91+
}
92+
}
93+
}

src/Dotnet.Script.Tests/PackageSourceTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public void ShouldHandleSpecifyingPackageSource()
1717
{
1818
var fixture = "ScriptPackage/WithNoNuGetConfig";
1919
var pathToScriptPackages = ScriptPackagesFixture.GetPathToPackagesFolder();
20-
var result = ScriptTestRunner.Default.ExecuteFixture(fixture, $"--no-cache -s {pathToScriptPackages}");
20+
var result = ScriptTestRunner.Default.ExecuteFixture(fixture, $"--no-cache -s \"{pathToScriptPackages}\"");
2121
Assert.Contains("Hello", result.output);
2222
Assert.Equal(0, result.exitCode);
2323
}
@@ -27,7 +27,7 @@ public void ShouldHandleSpecifyingPackageSourceWhenEvaluatingCode()
2727
{
2828
var pathToScriptPackages = ScriptPackagesFixture.GetPathToPackagesFolder();
2929
var code = @"#load \""nuget:ScriptPackageWithMainCsx,1.0.0\"" SayHello();";
30-
var result = ScriptTestRunner.Default.Execute($"--no-cache -s {pathToScriptPackages} eval \"{code}\"");
30+
var result = ScriptTestRunner.Default.Execute($"--no-cache -s \"{pathToScriptPackages}\" eval \"{code}\"");
3131
Assert.Contains("Hello", result.output);
3232
Assert.Equal(0, result.exitCode);
3333
}

src/Dotnet.Script.Tests/ScriptExecutionTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public void ShouldHandleIssue181()
139139
[Fact]
140140
public void ShouldHandleIssue189()
141141
{
142-
var result = ScriptTestRunner.Default.Execute(Path.Combine(TestPathUtils.GetPathToTestFixtureFolder("Issue189"), "SomeFolder", "Script.csx"));
142+
var result = ScriptTestRunner.Default.Execute($"\"{Path.Combine(TestPathUtils.GetPathToTestFixtureFolder("Issue189"), "SomeFolder", "Script.csx")}\"");
143143
Assert.Contains("Newtonsoft.Json.JsonConvert", result.output);
144144
}
145145

src/Dotnet.Script.Tests/ScriptPackagesFixture.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ private void BuildScriptPackages()
4343
if (_scriptEnvironment.IsWindows)
4444
{
4545
command = pathtoNuget430;
46-
var result = ProcessHelper.RunAndCaptureOutput(command, $"pack {specFile} -OutputDirectory {pathToPackagesOutputFolder}");
46+
var result = ProcessHelper.RunAndCaptureOutput(command, $"pack \"{specFile}\" -OutputDirectory \"{pathToPackagesOutputFolder}\"");
4747
}
4848
else
4949
{
5050
command = "mono";
51-
var result = ProcessHelper.RunAndCaptureOutput(command, $"{pathtoNuget430} pack {specFile} -OutputDirectory {pathToPackagesOutputFolder}");
51+
var result = ProcessHelper.RunAndCaptureOutput(command, $"\"{pathtoNuget430}\" pack \"{specFile}\" -OutputDirectory \"{pathToPackagesOutputFolder}\"");
5252
}
5353

5454
}

src/Dotnet.Script.Tests/ScriptTestRunner.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ public int ExecuteInProcess(string arguments = null)
3838
public (string output, int exitCode) ExecuteFixture(string fixture, string arguments = null, string workingDirectory = null)
3939
{
4040
var pathToFixture = TestPathUtils.GetPathToTestFixture(fixture);
41-
var result = ProcessHelper.RunAndCaptureOutput("dotnet", GetDotnetScriptArguments($"{pathToFixture} {arguments}"), workingDirectory);
41+
var result = ProcessHelper.RunAndCaptureOutput("dotnet", GetDotnetScriptArguments($"\"{pathToFixture}\" {arguments}"), workingDirectory);
4242
return result;
4343
}
4444

4545
public (string output, int exitcode) ExecuteWithScriptPackage(string fixture, string arguments = null, string workingDirectory = null)
4646
{
4747
var pathToScriptPackageFixtures = TestPathUtils.GetPathToTestFixtureFolder("ScriptPackage");
4848
var pathToFixture = Path.Combine(pathToScriptPackageFixtures, fixture, $"{fixture}.csx");
49-
return ProcessHelper.RunAndCaptureOutput("dotnet", GetDotnetScriptArguments($"{pathToFixture} {arguments}"), workingDirectory);
49+
return ProcessHelper.RunAndCaptureOutput("dotnet", GetDotnetScriptArguments($"\"{pathToFixture}\" {arguments}"), workingDirectory);
5050
}
5151

5252
public int ExecuteFixtureInProcess(string fixture, string arguments = null)
@@ -88,7 +88,7 @@ private string GetDotnetScriptArguments(string arguments)
8888
configuration = "Release";
8989
#endif
9090

91-
var allArgs = $"exec {Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "Dotnet.Script", "bin", configuration, _scriptEnvironment.TargetFramework, "dotnet-script.dll")} {arguments}";
91+
var allArgs = $"exec \"{Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "Dotnet.Script", "bin", configuration, _scriptEnvironment.TargetFramework, "dotnet-script.dll")}\" {arguments}";
9292

9393
return allArgs;
9494
}

0 commit comments

Comments
 (0)
0