From 77915fb647db79e84ed6fae0d1067561bea7e906 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 10 Oct 2022 18:31:06 +0100 Subject: [PATCH] Fix SPath serialization and make runtime and editor versions the same --- .gitignore | 5 +- .../Runtime/SimpleIO.cs | 126 ++++++---- .../Editor/SimpleIO.cs | 227 +++++++----------- .../Tests/Editor/BaseTest_Shared.cs | 12 +- .../Unity.ProcessTests/ProcessTaskTests.cs | 2 +- test.sh | 0 6 files changed, 176 insertions(+), 196 deletions(-) mode change 100644 => 100755 test.sh diff --git a/.gitignore b/.gitignore index 99d96f50..6ff1c770 100644 --- a/.gitignore +++ b/.gitignore @@ -135,10 +135,11 @@ UpgradeLog*.htm .idea/ upm-ci~/ setenv.sh -.Editor/ +/.Editor/ +/.Editor TestResults MonoBleedingEdge /.bin/ /.download/ .store -nbgv.exe \ No newline at end of file +nbgv.exe diff --git a/src/com.spoiledcat.simpleio.runtime/Runtime/SimpleIO.cs b/src/com.spoiledcat.simpleio.runtime/Runtime/SimpleIO.cs index fc632530..f84b96dc 100644 --- a/src/com.spoiledcat.simpleio.runtime/Runtime/SimpleIO.cs +++ b/src/com.spoiledcat.simpleio.runtime/Runtime/SimpleIO.cs @@ -42,6 +42,16 @@ using System.Reflection; using System.Text; +#if UNITY_5_3_OR_NEWER +using SerializeField=UnityEngine.SerializeField; +using SerializeFieldProperty=UnityEngine.SerializeField; +#else +using SerializeField=SerializePropertyAttribute; +using SerializeFieldProperty=SerializePropertyAttribute; +[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Field)] +public sealed class SerializePropertyAttribute : Attribute{} +#endif + namespace SpoiledCat.SimpleIO { using System.Globalization; @@ -59,14 +69,12 @@ struct SPath : IEquatable, IComparable { public static SPath Default; -#if UNITY_5_3_OR_NEWER - [UnityEngine.SerializeField] -#endif - private readonly string[] elements; -#if UNITY_5_3_OR_NEWER - [UnityEngine.SerializeField] -#endif - private readonly string driveLetter; + [SerializeField] private string[] elements; + [SerializeField] private string driveLetter; + [SerializeField] private bool isInitialized; + [SerializeField] private bool isRelative; + + [NonSerialized] private bool driveLetterInitialized; #region construction @@ -74,22 +82,21 @@ public SPath(string path) { EnsureNotNull(path, "path"); - IsInitialized = true; + isInitialized = true; + driveLetterInitialized = true; path = ParseDriveLetter(path, out driveLetter); if (path == "/") { - IsRelative = false; + isRelative = false; elements = new string[] {}; } else { var split = path.Split('/', '\\'); - - IsRelative = driveLetter == null && IsRelativeFromSplitString(split); - - elements = ParseSplitStringIntoElements(split.Where(s => s.Length > 0).ToArray(), IsRelative); + isRelative = driveLetter == null && IsRelativeFromSplitString(split); + elements = ParseSplitStringIntoElements(split.Where(s => s.Length > 0).ToArray(), isRelative); } } @@ -103,9 +110,11 @@ public static (SPath, bool) TryParse(string path) private SPath(string[] elements, bool isRelative, string driveLetter) { this.elements = elements; - IsRelative = isRelative; - this.driveLetter = driveLetter; - IsInitialized = true; + this.isRelative = isRelative; + this.driveLetter = driveLetter?.Length == 0 ? null : driveLetter; + + driveLetterInitialized = true; + isInitialized = true; } private static string[] ParseSplitStringIntoElements(IEnumerable inputs, bool isRelative) @@ -184,7 +193,6 @@ public SPath Parent { throw new InvalidOperationException("Parent is called on an empty path"); var newElements = elements.Take(elements.Length - 1).ToArray(); - return new SPath(newElements, IsRelative, driveLetter); } } @@ -195,7 +203,7 @@ public SPath RelativeTo(SPath path) if (!IsChildOf(path)) { - if (!IsRelative && !path.IsRelative && driveLetter != path.driveLetter) + if (!IsRelative && !path.IsRelative && DriveLetter != path.DriveLetter) throw new ArgumentException( "Path.RelativeTo() was invoked with two paths that are on different volumes. invoked on: " + ToString() + " asked to be made relative to: " + path); @@ -233,7 +241,7 @@ public SPath GetCommonParent(SPath path) if (!IsChildOf(path)) { - if (!IsRelative && !path.IsRelative && driveLetter != path.driveLetter) + if (!IsRelative && !path.IsRelative && DriveLetter != path.DriveLetter) return Default; SPath commonParent = Default; @@ -268,7 +276,19 @@ public SPath ChangeExtension(string extension) #region inspection - public bool IsRelative { get; } + public bool IsRelative => isRelative; + public bool IsInitialized => isInitialized; + + private string DriveLetter { + get { + if (!driveLetterInitialized) + { + driveLetter = driveLetter?.Length == 0 ? null : driveLetter; + driveLetterInitialized = true; + } + return driveLetter; + } + } public string FileName { get { @@ -301,8 +321,6 @@ public int Depth { } } - public bool IsInitialized { get; } - public bool Exists() { ThrowIfNotInitialized(); @@ -312,10 +330,8 @@ public bool Exists() public bool Exists(string append) { ThrowIfNotInitialized(); - if (String.IsNullOrEmpty(append)) - { + if (string.IsNullOrEmpty(append)) return Exists(); - } return Exists(new SPath(append)); } @@ -336,7 +352,7 @@ public bool DirectoryExists() public bool DirectoryExists(string append) { ThrowIfNotInitialized(); - if (String.IsNullOrEmpty(append)) + if (string.IsNullOrEmpty(append)) return DirectoryExists(); return DirectoryExists(new SPath(append)); } @@ -358,7 +374,7 @@ public bool FileExists() public bool FileExists(string append) { ThrowIfNotInitialized(); - if (String.IsNullOrEmpty(append)) + if (string.IsNullOrEmpty(append)) return FileExists(); return FileExists(new SPath(append)); } @@ -378,8 +394,8 @@ public string ExtensionWithDot { throw new ArgumentException("A root directory does not have an extension"); var last = elements.Last(); - var index = last.LastIndexOf("."); - if (index < 0) return String.Empty; + var index = last.LastIndexOf(".", StringComparison.InvariantCulture); + if (index < 0) return string.Empty; return last.Substring(index); } } @@ -402,17 +418,17 @@ public override string ToString() public string ToString(SlashMode slashMode) { if (!IsInitialized) - return String.Empty; + return string.Empty; // Check if it's linux root / - if (IsRoot && string.IsNullOrEmpty(driveLetter)) + if (IsRoot && DriveLetter == null) return Slash(slashMode).ToString(); if (IsRelative && elements.Length == 0) return "."; var sb = new StringBuilder(); - if (driveLetter != null) + if (DriveLetter != null) { sb.Append(driveLetter); sb.Append(":"); @@ -470,7 +486,7 @@ public bool Equals(SPath p) if (p.IsRelative != IsRelative) return false; - if (!string.Equals(p.driveLetter, driveLetter, PathStringComparison)) + if (!string.Equals(p.DriveLetter, DriveLetter, PathStringComparison)) return false; if (p.elements.Length != elements.Length) @@ -492,16 +508,13 @@ public override int GetHashCode() { unchecked { - int hash = 17; - // Suitable nullity checks etc, of course :) - hash = hash * 23 + IsInitialized.GetHashCode(); - if (!IsInitialized) + int hash = (int) 2166136261; + if (!isInitialized) return hash; - hash = hash * 23 + IsRelative.GetHashCode(); + hash = hash * 16777619 + isRelative.GetHashCode(); + hash = hash * 16777619 + DriveLetter?.ToUpperInvariant().GetHashCode() ?? 0; foreach (var element in elements) - hash = hash * 23 + (IsUnix ? element : element.ToUpperInvariant()).GetHashCode(); - if (driveLetter != null) - hash = hash * 23 + (IsUnix ? driveLetter : driveLetter.ToUpperInvariant()).GetHashCode(); + hash = hash * 16777619 + (IsUnix ? element : element.ToUpperInvariant()).GetHashCode(); return hash; } } @@ -602,6 +615,9 @@ public SPath CreateFile(string file) public SPath CreateFile(SPath file) { ThrowIfNotInitialized(); + if (!file.IsRelative) + throw new ArgumentException( + "You cannot call CreateFile() on an existing path with a non relative argument"); return Combine(file).CreateFile(); } @@ -670,6 +686,14 @@ public SPath MakeAbsolute() return SPath.CurrentDirectory.Combine(this); } + public SPath MakeRelative() + { + ThrowIfNotInitialized(); + if (IsRelative) + return this; + + return new SPath(elements, true, null); + } SPath CopyWithDeterminedDestination(SPath absoluteDestination, Func fileFilter) { @@ -783,7 +807,7 @@ public static SPath CreateTempDirectory(string myprefix) public static SPath GetTempFilename(string myprefix = "") { var random = new Random(); - var prefix = FileSystem.TempPath+ "/" + (String.IsNullOrEmpty(myprefix) ? "" : myprefix + "_"); + var prefix = FileSystem.TempPath+ "/" + (string.IsNullOrEmpty(myprefix) ? "" : myprefix + "_"); while (true) { var candidate = new SPath(prefix + random.Next()); @@ -1022,8 +1046,10 @@ public SPath EnsureDirectoryExists(string append = "") { ThrowIfNotInitialized(); - if (String.IsNullOrEmpty(append)) + if (string.IsNullOrEmpty(append)) { + if (IsRoot) + return this; if (DirectoryExists()) return this; EnsureParentDirectoryExists(); @@ -1052,7 +1078,7 @@ public SPath EnsureParentDirectoryExists() var parent = Parent; parent.EnsureDirectoryExists(); - return parent; + return this; } public SPath FileMustExist() @@ -1091,7 +1117,7 @@ public bool IsChildOf(SPath potentialBasePath) // If the other path is the root directory, then anything is a child of it as long as it's not a Windows path if (potentialBasePath.IsRoot) { - if (driveLetter != potentialBasePath.driveLetter) + if (DriveLetter != potentialBasePath.DriveLetter) return false; return true; } @@ -1180,7 +1206,7 @@ private static T EnsureNotNull(T value, string name, string caller = "") { if (value != null) return value; - string message = String.Format(CultureInfo.InvariantCulture, "In {0}, '{1}' must not be null", caller, name); + var message = string.Format(CultureInfo.InvariantCulture, "In {0}, '{1}' must not be null", caller, name); throw new ArgumentNullException(name, message); } @@ -1603,7 +1629,7 @@ public string[] ReadAllLines(string path) public void WriteLines(string path, string[] contents) { ValidatePath(path, nameof(path)); - using (StreamWriter fs = File.AppendText(path)) + using (var fs = File.AppendText(path)) { foreach (var line in contents) fs.WriteLine(line); @@ -1693,7 +1719,7 @@ public string LocalAppData public string CommonAppData { - get => commonAppData ?? (localAppData = GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); + get => commonAppData ?? (commonAppData = GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); set => commonAppData = value; } @@ -1753,7 +1779,7 @@ public MemoryFileSystem() #else fileSystemImplementation = new FileSystem(Directory.GetCurrentDirectory()); #endif - + } private string Normalize(string path) => path.ToSPath().ToString(SlashMode.Forward); diff --git a/src/com.spoiledcat.simpleio/Editor/SimpleIO.cs b/src/com.spoiledcat.simpleio/Editor/SimpleIO.cs index 5b8108ab..f0c80182 100644 --- a/src/com.spoiledcat.simpleio/Editor/SimpleIO.cs +++ b/src/com.spoiledcat.simpleio/Editor/SimpleIO.cs @@ -42,6 +42,16 @@ using System.Reflection; using System.Text; +#if UNITY_5_3_OR_NEWER +using SerializeField=UnityEngine.SerializeField; +using SerializeFieldProperty=UnityEngine.SerializeField; +#else +using SerializeField=SerializePropertyAttribute; +using SerializeFieldProperty=SerializePropertyAttribute; +[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Field)] +public sealed class SerializePropertyAttribute : Attribute{} +#endif + namespace SpoiledCat.SimpleIO { using System.Globalization; @@ -59,33 +69,12 @@ struct SPath : IEquatable, IComparable { public static SPath Default; -#if UNITY_5_3_OR_NEWER - [UnityEngine.SerializeField] -#else - [NonSerialized] -#endif - private string[] elements; -#if UNITY_5_3_OR_NEWER - [UnityEngine.SerializeField] -#else - [NonSerialized] -#endif - private string driveLetter; - -#if UNITY_5_3_OR_NEWER - [UnityEngine.SerializeField] -#else - [NonSerialized] -#endif - private bool isInitialized; - -#if UNITY_5_3_OR_NEWER - [UnityEngine.SerializeField] -#else - [NonSerialized] -#endif - private bool isRelative; + [SerializeField] private string[] elements; + [SerializeField] private string driveLetter; + [SerializeField] private bool isInitialized; + [SerializeField] private bool isRelative; + [NonSerialized] private bool driveLetterInitialized; #region construction public SPath(string path) @@ -93,6 +82,7 @@ public SPath(string path) EnsureNotNull(path, "path"); isInitialized = true; + driveLetterInitialized = true; path = ParseDriveLetter(path, out driveLetter); @@ -122,8 +112,9 @@ private SPath(string[] elements, bool isRelative, string driveLetter) { this.elements = elements; this.isRelative = isRelative; - this.driveLetter = driveLetter; - this.isInitialized = true; + this.driveLetter = driveLetter?.Length == 0 ? null : driveLetter; + driveLetterInitialized = true; + isInitialized = true; } private static string[] ParseSplitStringIntoElements(IEnumerable inputs, bool isRelative) @@ -213,7 +204,7 @@ public SPath RelativeTo(SPath path) if (!IsChildOf(path)) { - if (!IsRelative && !path.IsRelative && driveLetter != path.driveLetter) + if (!IsRelative && !path.IsRelative && DriveLetter != path.DriveLetter) throw new ArgumentException( "Path.RelativeTo() was invoked with two paths that are on different volumes. invoked on: " + ToString() + " asked to be made relative to: " + path); @@ -251,7 +242,7 @@ public SPath GetCommonParent(SPath path) if (!IsChildOf(path)) { - if (!IsRelative && !path.IsRelative && driveLetter != path.driveLetter) + if (!IsRelative && !path.IsRelative && DriveLetter != path.DriveLetter) return Default; SPath commonParent = Default; @@ -289,6 +280,16 @@ public SPath ChangeExtension(string extension) public bool IsRelative => isRelative; public bool IsInitialized => isInitialized; + private string DriveLetter { + get { + if (!driveLetterInitialized) + { + driveLetter = driveLetter?.Length == 0 ? null : driveLetter; + driveLetterInitialized = true; + } + return driveLetter; + } + } public string FileName { get { @@ -330,10 +331,8 @@ public bool Exists() public bool Exists(string append) { ThrowIfNotInitialized(); - if (String.IsNullOrEmpty(append)) - { + if (string.IsNullOrEmpty(append)) return Exists(); - } return Exists(new SPath(append)); } @@ -354,7 +353,7 @@ public bool DirectoryExists() public bool DirectoryExists(string append) { ThrowIfNotInitialized(); - if (String.IsNullOrEmpty(append)) + if (string.IsNullOrEmpty(append)) return DirectoryExists(); return DirectoryExists(new SPath(append)); } @@ -376,7 +375,7 @@ public bool FileExists() public bool FileExists(string append) { ThrowIfNotInitialized(); - if (String.IsNullOrEmpty(append)) + if (string.IsNullOrEmpty(append)) return FileExists(); return FileExists(new SPath(append)); } @@ -396,8 +395,8 @@ public string ExtensionWithDot { throw new ArgumentException("A root directory does not have an extension"); var last = elements.Last(); - var index = last.LastIndexOf("."); - if (index < 0) return String.Empty; + var index = last.LastIndexOf(".", StringComparison.InvariantCulture); + if (index < 0) return string.Empty; return last.Substring(index); } } @@ -420,17 +419,17 @@ public override string ToString() public string ToString(SlashMode slashMode) { if (!IsInitialized) - return String.Empty; + return string.Empty; // Check if it's linux root / - if (IsRoot && string.IsNullOrEmpty(driveLetter)) + if (IsRoot && DriveLetter == null) return Slash(slashMode).ToString(); if (IsRelative && elements.Length == 0) return "."; var sb = new StringBuilder(); - if (driveLetter != null) + if (DriveLetter != null) { sb.Append(driveLetter); sb.Append(":"); @@ -488,7 +487,7 @@ public bool Equals(SPath p) if (p.IsRelative != IsRelative) return false; - if (!string.Equals(p.driveLetter, driveLetter, PathStringComparison)) + if (!string.Equals(p.DriveLetter, DriveLetter, PathStringComparison)) return false; if (p.elements.Length != elements.Length) @@ -510,16 +509,14 @@ public override int GetHashCode() { unchecked { - int hash = 17; + int hash = (int) 2166136261; // Suitable nullity checks etc, of course :) - hash = hash * 23 + IsInitialized.GetHashCode(); - if (!IsInitialized) + if (!isInitialized) return hash; - hash = hash * 23 + IsRelative.GetHashCode(); + hash = hash * 16777619 + isRelative.GetHashCode(); + hash = hash * 16777619 + DriveLetter?.ToUpperInvariant().GetHashCode() ?? 0; foreach (var element in elements) - hash = hash * 23 + (IsUnix ? element : element.ToUpperInvariant()).GetHashCode(); - if (driveLetter != null) - hash = hash * 23 + (IsUnix ? driveLetter : driveLetter.ToUpperInvariant()).GetHashCode(); + hash = hash * 16777619 + (IsUnix ? element : element.ToUpperInvariant()).GetHashCode(); return hash; } } @@ -699,17 +696,7 @@ public SPath MakeRelative() if (IsRelative) return this; - var sb = new StringBuilder(); - var first = true; - foreach (var element in elements) - { - if (!first) - sb.Append('/'); - first = false; - sb.Append(element); - } - - return new SPath(sb.ToString()); + return new SPath(elements, true, null); } SPath CopyWithDeterminedDestination(SPath absoluteDestination, Func fileFilter) @@ -824,7 +811,7 @@ public static SPath CreateTempDirectory(string myprefix) public static SPath GetTempFilename(string myprefix = "") { var random = new Random(); - var prefix = FileSystem.TempPath+ "/" + (String.IsNullOrEmpty(myprefix) ? "" : myprefix + "_"); + var prefix = FileSystem.TempPath+ "/" + (string.IsNullOrEmpty(myprefix) ? "" : myprefix + "_"); while (true) { var candidate = new SPath(prefix + random.Next()); @@ -1063,7 +1050,7 @@ public SPath EnsureDirectoryExists(string append = "") { ThrowIfNotInitialized(); - if (String.IsNullOrEmpty(append)) + if (string.IsNullOrEmpty(append)) { if (IsRoot) return this; @@ -1134,7 +1121,7 @@ public bool IsChildOf(SPath potentialBasePath) // If the other path is the root directory, then anything is a child of it as long as it's not a Windows path if (potentialBasePath.IsRoot) { - if (driveLetter != potentialBasePath.driveLetter) + if (DriveLetter != potentialBasePath.DriveLetter) return false; return true; } @@ -1223,7 +1210,7 @@ private static T EnsureNotNull(T value, string name, string caller = "") { if (value != null) return value; - string message = String.Format(CultureInfo.InvariantCulture, "In {0}, '{1}' must not be null", caller, name); + var message = string.Format(CultureInfo.InvariantCulture, "In {0}, '{1}' must not be null", caller, name); throw new ArgumentNullException(name, message); } @@ -1448,36 +1435,29 @@ public string GetFolderPath(Environment.SpecialFolder folder) public bool FileExists(string filename) { if (!Path.IsPathRooted(filename)) - throw new ArgumentException("FileExists requires a rooted path", "filename"); + throw new ArgumentException("FileExists requires a rooted path", nameof(filename)); return File.Exists(filename); } public IEnumerable GetDirectories(string path) { if (!Path.IsPathRooted(path)) - throw new ArgumentException("GetDirectories requires a rooted path", "path"); + throw new ArgumentException("GetDirectories requires a rooted path", nameof(path)); return Directory.GetDirectories(path); } - public string Combine(string path1, string path2) - { - return Path.Combine(path1, path2); - } + public string Combine(string path1, string path2) => Path.Combine(path1, path2); - public string Combine(string path1, string path2, string path3) - { - return Path.Combine(Path.Combine(path1, path2), path3); - } + public string Combine(string path1, string path2, string path3) => Path.Combine(Path.Combine(path1, path2), path3); - public string GetFullPath(string path) - { - return Path.GetFullPath(path); - } + public string GetFullPath(string path) => Path.GetFullPath(path); + public string ChangeExtension(string path, string extension) => Path.ChangeExtension(path, extension); + public string GetFileNameWithoutExtension(string fileName) => Path.GetFileNameWithoutExtension(fileName); public bool DirectoryExists(string path) { if (!Path.IsPathRooted(path)) - throw new ArgumentException("DirectoryExists requires a rooted path", "path"); + throw new ArgumentException("DirectoryExists requires a rooted path", nameof(path)); return Directory.Exists(path); } @@ -1490,25 +1470,17 @@ public bool ExistingPathIsDirectory(string path) public IEnumerable GetDirectories(string path, string pattern) { if (!Path.IsPathRooted(path)) - throw new ArgumentException("GetDirectories requires a rooted path", "path"); + throw new ArgumentException("GetDirectories requires a rooted path", nameof(path)); return Directory.GetDirectories(path, pattern); } public IEnumerable GetDirectories(string path, string pattern, SearchOption searchOption) { if (!Path.IsPathRooted(path)) - throw new ArgumentException("GetDirectories requires a rooted path", "path"); + throw new ArgumentException("GetDirectories requires a rooted path", nameof(path)); return Directory.GetDirectories(path, pattern, searchOption); - } - public string ChangeExtension(string path, string extension) - { - return Path.ChangeExtension(path, extension); - } - public string GetFileNameWithoutExtension(string fileName) - { - return Path.GetFileNameWithoutExtension(fileName); } public IEnumerable GetFiles(string path) @@ -1519,7 +1491,7 @@ public IEnumerable GetFiles(string path) public IEnumerable GetFiles(string path, string pattern) { if (!Path.IsPathRooted(path)) - throw new ArgumentException("GetFiles requires a rooted path", "path"); + throw new ArgumentException("GetFiles requires a rooted path", nameof(path)); return Directory.GetFiles(path, pattern); } @@ -1569,114 +1541,101 @@ public IEnumerable GetFiles(string path, string pattern, SearchOption se } } + internal static void ValidatePath(string value, string argName, [CallerMemberName] string caller = null) + { + if (!Path.IsPathRooted(value)) + throw new ArgumentException($"{caller} requires a rooted path", argName); + } public byte[] ReadAllBytes(string path) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("ReadAllBytes requires a rooted path", "path"); + ValidatePath(path, nameof(path)); return File.ReadAllBytes(path); } public void WriteAllBytes(string path, byte[] bytes) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("WriteAllBytes requires a rooted path", "path"); + ValidatePath(path, nameof(path)); File.WriteAllBytes(path, bytes); } public void DirectoryCreate(string path) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("DirectoryCreate requires a rooted path", "path"); + ValidatePath(path, nameof(path)); Directory.CreateDirectory(path); } public void FileCopy(string sourceFileName, string destFileName, bool overwrite) { - if (!Path.IsPathRooted(sourceFileName)) - throw new ArgumentException("FileCopy requires a rooted path", "sourceFileName"); - if (!Path.IsPathRooted(destFileName)) - throw new ArgumentException("FileCopy requires a rooted path", "destFileName"); + ValidatePath(sourceFileName, nameof(sourceFileName)); + ValidatePath(destFileName, nameof(destFileName)); File.Copy(sourceFileName, destFileName, overwrite); } public void FileDelete(string path) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("FileDelete requires a rooted path", "path"); + ValidatePath(path, nameof(path)); File.Delete(path); } public void DirectoryDelete(string path, bool recursive) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("DirectoryDelete requires a rooted path", "path"); + ValidatePath(path, nameof(path)); Directory.Delete(path, recursive); } public void FileMove(string sourceFileName, string destFileName) { - if (!Path.IsPathRooted(sourceFileName)) - throw new ArgumentException("FileMove requires a rooted path", "sourceFileName"); - if (!Path.IsPathRooted(destFileName)) - throw new ArgumentException("FileMove requires a rooted path", "destFileName"); + ValidatePath(sourceFileName, nameof(sourceFileName)); + ValidatePath(destFileName, nameof(destFileName)); File.Move(sourceFileName, destFileName); } public void DirectoryMove(string source, string dest) { - if (!Path.IsPathRooted(source)) - throw new ArgumentException("DirectoryMove requires a rooted path", "source"); - if (!Path.IsPathRooted(dest)) - throw new ArgumentException("DirectoryMove requires a rooted path", "dest"); + ValidatePath(source, nameof(source)); + ValidatePath(dest, nameof(dest)); Directory.Move(source, dest); } public void WriteAllText(string path, string contents) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("WriteAllText requires a rooted path", "path"); + ValidatePath(path, nameof(path)); File.WriteAllText(path, contents); } public void WriteAllText(string path, string contents, Encoding encoding) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("WriteAllText requires a rooted path", "path"); + ValidatePath(path, nameof(path)); File.WriteAllText(path, contents, encoding); } public string ReadAllText(string path) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("ReadAllText requires a rooted path", "path"); + ValidatePath(path, nameof(path)); return File.ReadAllText(path); } public string ReadAllText(string path, Encoding encoding) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("ReadAllText requires a rooted path", "path"); + ValidatePath(path, nameof(path)); return File.ReadAllText(path, encoding); } public void WriteAllLines(string path, string[] contents) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("WriteAllLines requires a rooted path", "path"); + ValidatePath(path, nameof(path)); File.WriteAllLines(path, contents); } public string[] ReadAllLines(string path) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("ReadAllLines requires a rooted path", "path"); + ValidatePath(path, nameof(path)); return File.ReadAllLines(path); } public void WriteLines(string path, string[] contents) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("WriteLines requires a rooted path", "path"); + ValidatePath(path, nameof(path)); using (var fs = File.AppendText(path)) { foreach (var line in contents) @@ -1684,22 +1643,17 @@ public void WriteLines(string path, string[] contents) } } - public string GetRandomFileName() - { - return Path.GetRandomFileName(); - } + public string GetRandomFileName() => Path.GetRandomFileName(); public Stream OpenRead(string path) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("OpenRead requires a rooted path", "path"); + ValidatePath(path, nameof(path)); return File.OpenRead(path); } public Stream OpenWrite(string path, FileMode mode) { - if (!Path.IsPathRooted(path)) - throw new ArgumentException("OpenWrite requires a rooted path", "path"); + ValidatePath(path, nameof(path)); return new FileStream(path, mode); } @@ -1708,8 +1662,7 @@ public string CurrentDirectory get => currentDirectory ?? Directory.GetCurrentDirectory(); set { - if (!Path.IsPathRooted(value)) - throw new ArgumentException("SetCurrentDirectory requires a rooted path", "directory"); + ValidatePath(value, nameof(value)); currentDirectory = value; } } @@ -1813,8 +1766,6 @@ private static Func GetCompleteRealPath } } - public char DirectorySeparatorChar { - get { return Path.DirectorySeparatorChar; } - } + public char DirectorySeparatorChar => Path.DirectorySeparatorChar; } } diff --git a/src/com.spoiledcat.threading/Tests/Editor/BaseTest_Shared.cs b/src/com.spoiledcat.threading/Tests/Editor/BaseTest_Shared.cs index e748e933..9c583eb6 100644 --- a/src/com.spoiledcat.threading/Tests/Editor/BaseTest_Shared.cs +++ b/src/com.spoiledcat.threading/Tests/Editor/BaseTest_Shared.cs @@ -84,12 +84,11 @@ private void InitializeEnvironment() var projectPath = TestPath.Combine("project").EnsureDirectoryExists(); #if UNITY_EDITOR - Environment.Initialize(projectPath, TheEnvironment.instance.Environment.UnityVersion, TheEnvironment.instance.Environment.UnityApplication, TheEnvironment.instance.Environment.UnityApplicationContents); + Environment.Initialize(projectPath, projectPath, TheEnvironment.instance.Environment.UnityVersion, TheEnvironment.instance.Environment.UnityApplication, TheEnvironment.instance.Environment.UnityApplicationContents); return; #endif - SPath unityPath, unityContentsPath; - unityPath = CurrentExecutionDirectory; + (SPath unityPath, SPath unityContentsPath) = (CurrentExecutionDirectory, SPath.Default); while (!unityPath.IsEmpty && !unityPath.DirectoryExists(".Editor")) unityPath = unityPath.Parent; @@ -97,14 +96,17 @@ private void InitializeEnvironment() if (!unityPath.IsEmpty) { unityPath = unityPath.Combine(".Editor"); - unityContentsPath = unityPath.Combine("Data"); + if (unityPath.DirectoryExists("Data")) + unityContentsPath = unityPath.Combine("Data"); + else if (unityPath.DirectoryExists("Contents")) + unityContentsPath = unityPath.Combine("Contents"); } else { unityPath = unityContentsPath = SPath.Default; } - Environment.Initialize(projectPath, "2019.2", unityPath, unityContentsPath); + Environment.Initialize(projectPath, projectPath, "2019.2", unityPath, unityContentsPath); } public void Dispose() diff --git a/src/com.spoiledcat.threading/Tests/Editor/Unity.ProcessTests/ProcessTaskTests.cs b/src/com.spoiledcat.threading/Tests/Editor/Unity.ProcessTests/ProcessTaskTests.cs index 2dc1810e..a350c154 100644 --- a/src/com.spoiledcat.threading/Tests/Editor/Unity.ProcessTests/ProcessTaskTests.cs +++ b/src/com.spoiledcat.threading/Tests/Editor/Unity.ProcessTests/ProcessTaskTests.cs @@ -226,7 +226,7 @@ public IEnumerator CanRunProcessOnMono() { monoPath = test.Environment.UnityApplicationContents.Combine(monoPath); var task = new MonoProcessTask(test.TaskManager, test.ProcessManager, TestApp, "-d 1"); - Assert.AreEqual(monoPath, task.ProcessName.ToSPath()); + Assert.AreEqual(monoPath.ToSPath(), task.ProcessName.ToSPath()); Assert.AreEqual($"{TestApp} -d 1", task.ProcessArguments); foreach (var frame in StartAndWaitForCompletion(task)) yield return frame; Assert.AreEqual($"1{test.Environment.NewLine}", task.Result); diff --git a/test.sh b/test.sh old mode 100644 new mode 100755