diff options
author | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2019-11-21 15:08:52 +0100 |
---|---|---|
committer | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2019-11-21 14:53:00 +0100 |
commit | f91416d9acabb76f6efcdc2d09835d04cd98c881 (patch) | |
tree | 4239a51d8587294bd994be8240c93be480a0b9d1 | |
parent | 95f1f4e82a948f064bbbe32812a3f4b5c3c90bb7 (diff) |
C#: Fix PathWhich on Windows when name already has extension
Also make the Posix version of PathWhich check if the file has executable access.
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj | 1 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs | 86 |
2 files changed, 50 insertions, 37 deletions
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj index d0c78d095b..fb2cbabc8e 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj +++ b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj @@ -30,6 +30,7 @@ <ConsolePause>false</ConsolePause> </PropertyGroup> <ItemGroup> + <Reference Include="Mono.Posix" /> <Reference Include="System" /> <Reference Include="GodotSharp"> <HintPath>$(GodotSourceRootPath)/bin/GodotSharp/Api/$(GodotApiConfiguration)/GodotSharp.dll</HintPath> diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs index 21ee85f2a9..1a8c26acd7 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs @@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using Mono.Unix.Native; namespace GodotTools.Utils { @@ -55,21 +56,23 @@ namespace GodotTools.Utils return name.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); } - public static bool IsWindows => IsOS(Names.Windows); - - public static bool IsOSX => IsOS(Names.OSX); - - public static bool IsX11 => IsOS(Names.X11); - - public static bool IsServer => IsOS(Names.Server); - - public static bool IsUWP => IsOS(Names.UWP); - - public static bool IsHaiku => IsOS(Names.Haiku); - - public static bool IsAndroid => IsOS(Names.Android); - - public static bool IsHTML5 => IsOS(Names.HTML5); + private static readonly Lazy<bool> _isWindows = new Lazy<bool>(() => IsOS(Names.Windows)); + private static readonly Lazy<bool> _isOSX = new Lazy<bool>(() => IsOS(Names.OSX)); + private static readonly Lazy<bool> _isX11 = new Lazy<bool>(() => IsOS(Names.X11)); + private static readonly Lazy<bool> _isServer = new Lazy<bool>(() => IsOS(Names.Server)); + private static readonly Lazy<bool> _isUWP = new Lazy<bool>(() => IsOS(Names.UWP)); + private static readonly Lazy<bool> _isHaiku = new Lazy<bool>(() => IsOS(Names.Haiku)); + private static readonly Lazy<bool> _isAndroid = new Lazy<bool>(() => IsOS(Names.Android)); + private static readonly Lazy<bool> _isHTML5 = new Lazy<bool>(() => IsOS(Names.HTML5)); + + public static bool IsWindows => _isWindows.Value; + public static bool IsOSX => _isOSX.Value; + public static bool IsX11 => _isX11.Value; + public static bool IsServer => _isServer.Value; + public static bool IsUWP => _isUWP.Value; + public static bool IsHaiku => _isHaiku.Value; + public static bool IsAndroid => _isAndroid.Value; + public static bool IsHTML5 => _isHTML5.Value; private static bool? _isUnixCache; private static readonly string[] UnixLikePlatforms = {Names.OSX, Names.X11, Names.Server, Names.Haiku, Names.Android}; @@ -88,7 +91,12 @@ namespace GodotTools.Utils public static string PathWhich(string name) { - string[] windowsExts = IsWindows ? Environment.GetEnvironmentVariable("PATHEXT")?.Split(PathSep) : null; + return IsWindows ? PathWhichWindows(name) : PathWhichUnix(name); + } + + private static string PathWhichWindows(string name) + { + string[] windowsExts = Environment.GetEnvironmentVariable("PATHEXT")?.Split(PathSep) ?? new string[] { }; string[] pathDirs = Environment.GetEnvironmentVariable("PATH")?.Split(PathSep); var searchDirs = new List<string>(); @@ -96,30 +104,34 @@ namespace GodotTools.Utils if (pathDirs != null) searchDirs.AddRange(pathDirs); + string nameExt = Path.GetExtension(name); + bool hasPathExt = string.IsNullOrEmpty(nameExt) || windowsExts.Contains(nameExt, StringComparer.OrdinalIgnoreCase); + searchDirs.Add(System.IO.Directory.GetCurrentDirectory()); // last in the list - foreach (var dir in searchDirs) - { - string path = Path.Combine(dir, name); - - if (IsWindows && windowsExts != null) - { - foreach (var extension in windowsExts) - { - string pathWithExtension = path + extension; - - if (File.Exists(pathWithExtension)) - return pathWithExtension; - } - } - else - { - if (File.Exists(path)) - return path; - } - } + if (hasPathExt) + return searchDirs.Select(dir => Path.Combine(dir, name)).FirstOrDefault(File.Exists); + + return (from dir in searchDirs + select Path.Combine(dir, name) + into path + from ext in windowsExts + select path + ext).FirstOrDefault(File.Exists); + } + + private static string PathWhichUnix(string name) + { + string[] pathDirs = Environment.GetEnvironmentVariable("PATH")?.Split(PathSep); + + var searchDirs = new List<string>(); + + if (pathDirs != null) + searchDirs.AddRange(pathDirs); + + searchDirs.Add(System.IO.Directory.GetCurrentDirectory()); // last in the list - return null; + return searchDirs.Select(dir => Path.Combine(dir, name)) + .FirstOrDefault(path => File.Exists(path) && Syscall.access(path, AccessModes.X_OK) == 0); } public static void RunProcess(string command, IEnumerable<string> arguments) |