Skip to content

Commit

Permalink
Merge pull request #492 from adamralph/pathext
Browse files Browse the repository at this point in the history
Pathext
  • Loading branch information
adamralph authored Jul 22, 2022
2 parents 319841f + 3427238 commit 086538c
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 3 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"NuGet",
"nupkg",
"paramref",
"PATHEXT",
"pipefail",
"refs",
"Robocopy",
Expand Down
12 changes: 9 additions & 3 deletions SimpleExec/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ namespace SimpleExec
/// </summary>
public static class Command
{
// an experiment in Windows revealed this order of precedence
private static readonly List<string> windowsExecutableExtensions = new List<string> { "exe", "bat", "cmd" };

private static readonly Action<IDictionary<string, string?>> defaultAction = _ => { };
private static readonly string defaultEchoPrefix = Assembly.GetEntryAssembly()?.GetName().Name ?? "SimpleExec";

Expand Down Expand Up @@ -385,6 +382,15 @@ private static string Resolve(string name)
return name;
}

var pathExt = Environment.GetEnvironmentVariable("PATHEXT") ?? ".EXE;.BAT;.CMD";

var windowsExecutableExtensions = pathExt.Split(';')
.Select(extension => extension.TrimStart('.'))
.Where(extension =>
string.Equals(extension, "exe", StringComparison.OrdinalIgnoreCase) ||
string.Equals(extension, "bat", StringComparison.OrdinalIgnoreCase) ||
string.Equals(extension, "cmd", StringComparison.OrdinalIgnoreCase));

var searchFileNames = string.IsNullOrEmpty(extension)
? windowsExecutableExtensions.Select(ex => Path.ChangeExtension(name, ex)).ToList()
: new List<string> { name, };
Expand Down
14 changes: 14 additions & 0 deletions SimpleExecTests/Infra/WindowsTheoryAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Runtime.InteropServices;
using Xunit;

namespace SimpleExecTests.Infra
{
internal sealed class WindowsTheoryAttribute : TheoryAttribute
{
public override string Skip
{
get => !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "Windows only" : base.Skip;
set => base.Skip = value;
}
}
}
44 changes: 44 additions & 0 deletions SimpleExecTests/RunningCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,49 @@ public static async Task RunningCommandsInPathOnWindows()
// assert
Assert.Null(exception);
}

[WindowsTheory]
[InlineData(".BAT;.CMD", "hello from bat")]
[InlineData(".CMD;.BAT", "hello from cmd")]
public static async Task RunningCommandsInPathOnWindowsWithSpecificPathExt(
string pathExt, string expected)
{
// arrange
var directory = Path.Combine(
Path.GetTempPath(),
"SimpleExecTests",
DateTimeOffset.UtcNow.UtcTicks.ToString(CultureInfo.InvariantCulture),
"RunningCommandsInPathOnWindows");

_ = Directory.CreateDirectory(directory);

if (!SpinWait.SpinUntil(() => Directory.Exists(directory), 50))
{
throw new IOException($"Failed to create directory '{directory}'.");
}

var name = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
var batName = Path.Combine(directory, Path.ChangeExtension(name, "bat"));
await File.WriteAllTextAsync(batName, "@echo hello from bat");

var cmdName = Path.Combine(directory, Path.ChangeExtension(name, "cmd"));
await File.WriteAllTextAsync(cmdName, "@echo hello from cmd");

Environment.SetEnvironmentVariable(
"PATH",
$"{Environment.GetEnvironmentVariable("PATH")}{Path.PathSeparator}{directory}",
EnvironmentVariableTarget.Process);

Environment.SetEnvironmentVariable(
"PATHEXT",
pathExt,
EnvironmentVariableTarget.Process);

// act
var actual = (await Command.ReadAsync(name)).StandardOutput.Trim();

// assert
Assert.Equal(expected, actual);
}
}
}

0 comments on commit 086538c

Please sign in to comment.