public Path Combine(Path child) { var parent = this; if (string.IsNullOrEmpty(parent) && string.IsNullOrEmpty(child)) { return(CorrectSlash); // root } if (string.IsNullOrEmpty(parent) && !string.IsNullOrEmpty(child)) { return(child.NormalizeSlashes()); } parent = parent.NormalizeSlashes(); if (!string.IsNullOrEmpty(parent) && string.IsNullOrEmpty(child)) { if (parent.EndsWithSlash()) { return(parent); } else { return(parent.AppendSlashAtEnd()); } } child = child.NormalizeSlashes(); var builder = new System.Text.StringBuilder(parent); if (!parent.EndsWithSlash()) { builder.Append(CorrectSlash); } // Make sure we do not add two \ if (child.StartsWithSlash()) { builder.Append(child, 1, child.Length - 1); } else { builder.Append(child); } return(new Path(CorrectSlash, WrongSlash, builder.ToString())); }
public Path GetParentPath(Path root) { var path = this; // normalize first path = path.NormalizeSlashes().TrimEndSlash(); if (root != null) { root = root.NormalizeSlashes().TrimEndSlash(); if (string.Equals(path, root, StringComparison.CurrentCultureIgnoreCase)) { return(new Path(CorrectSlash, WrongSlash, string.Empty)); } } int iLastSlash = path._rawPath.LastIndexOf(CorrectSlash); string newPath = root; if (iLastSlash > 0) { newPath = path._rawPath.Substring(0, iLastSlash); } else if (iLastSlash == 0) { newPath = new Path(CorrectSlash, WrongSlash, CorrectSlash); } Path resultPath = new Path(CorrectSlash, WrongSlash, newPath); return(resultPath.ApplyDriveSlash()); }
public static string CalculateFullPath(Path curLocation, Path changeCommandStr) { // TODO: sburnicki rewrite that stuff with pathintrinsics var changeCommand = (changeCommandStr ?? string.Empty).NormalizeSlashes(); var currentLocation = curLocation.NormalizeSlashes(); bool applyParts = false; Path resultPath; // use the input 'changeCommand' path if it's // 'rooted' otherwise we go from the currentLocation if (changeCommand.HasDrive()) { // windows case where changeCommand == "/" or "\" but the currentLocation has a "C:" drive string currentLocationDrive = currentLocation.GetDrive(); if (changeCommand.StartsWithSlash() && !changeCommand.GetDrive().Equals(currentLocationDrive, StringComparison.InvariantCultureIgnoreCase)) { resultPath = new Path(currentLocation.CorrectSlash, currentLocation.WrongSlash, string.Format("{0}:{1}", currentLocationDrive, changeCommand)); } else { resultPath = changeCommand; } } else { applyParts = true; resultPath = currentLocation; } var correctSeparator = Char.Parse(currentLocation.CorrectSlash); var changeParts = changeCommand.ToString().Split(correctSeparator).Where(s => !string.IsNullOrEmpty(s)); foreach (var part in changeParts) { // ignore single dot as it does nothing... if (part == ".") { continue; } // ignore trying to go up a dir from the root dir if (part == ".." && resultPath.IsRootPath()) { continue; } if (part == "..") { resultPath = resultPath.GetParentPath(currentLocation.GetDrive()); } else if (applyParts) { resultPath = resultPath.Combine(part); } } return(resultPath.ApplyDriveSlash()); }
public static string CalculateFullPath(Path curLocation, Path changeCommandStr) { // TODO: sburnicki rewrite that stuff with pathintrinsics var changeCommand = (changeCommandStr ?? string.Empty).NormalizeSlashes(); var currentLocation = curLocation.NormalizeSlashes(); bool applyParts = false; Path resultPath; // use the input 'changeCommand' path if it's // 'rooted' otherwise we go from the currentLocation if (changeCommand.HasDrive()) { // windows case where changeCommand == "/" or "\" but the currentLocation has a "C:" drive string currentLocationDrive = currentLocation.GetDrive(); if (changeCommand.StartsWithSlash() && !changeCommand.GetDrive().Equals(currentLocationDrive, StringComparison.InvariantCultureIgnoreCase)) { resultPath = new Path(currentLocation.CorrectSlash, currentLocation.WrongSlash, string.Format("{0}:{1}", currentLocationDrive, changeCommand)); } else { resultPath = changeCommand; } } else { applyParts = true; resultPath = currentLocation; } var correctSeparator = Char.Parse(currentLocation.CorrectSlash); var changeParts = changeCommand.ToString().Split(correctSeparator).Where(s => !string.IsNullOrEmpty(s)); foreach (var part in changeParts) { // ignore single dot as it does nothing... if (part == ".") { continue; } // ignore trying to go up a dir from the root dir if (part == ".." && resultPath.IsRootPath()) { continue; } if (part == "..") { resultPath = resultPath.GetParentPath(currentLocation.GetDrive()); } else if (applyParts) { resultPath = resultPath.Combine(part); } } return resultPath.ApplyDriveSlash(); }
public Path Combine(Path child) { var parent = this; if (string.IsNullOrEmpty(parent) && string.IsNullOrEmpty(child)) { return child; } if (string.IsNullOrEmpty(parent) && !string.IsNullOrEmpty(child)) { return child.NormalizeSlashes(); } parent = parent.NormalizeSlashes(); if (!string.IsNullOrEmpty(parent) && string.IsNullOrEmpty(child)) { if (parent.EndsWithSlash()) { return parent; } else { return parent.AppendSlashAtEnd(); } } child = child.NormalizeSlashes(); var builder = new System.Text.StringBuilder(parent); if (!parent.EndsWithSlash()) builder.Append(CorrectSlash); // Make sure we do not add two \ if (child.StartsWithSlash()) { builder.Append(child, 1, child.Length - 1); } else { builder.Append(child); } return new Path(CorrectSlash, WrongSlash, builder.ToString()); }
internal PathInfo SetLocation(Path path, ProviderRuntime providerRuntime) { // TODO: deal with paths starting with ".\" if (path == null) { throw new NullReferenceException("Path can't be null"); } if (path == "~") { // Older Mono versions (sadly the one that's currently still // available) have a bug where GetFolderPath returns an empty // string for most SpecialFolder values, but only on // non-Windows. // See: https://bugzilla.xamarin.com/show_bug.cgi?id=2873 path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); // HACK: Use $Env:HOME until Mono 2.10 dies out. if (path == "") path = Environment.GetEnvironmentVariable("HOME"); } PSDriveInfo nextDrive = CurrentDrive; path = path.NormalizeSlashes(); string driveName = null; if (path.TryGetDriveName(out driveName)) { try { nextDrive = _executionContext.SessionState.Drive.Get(driveName); } catch (MethodInvocationException) //didn't find a drive (maybe it's "\" on Windows) { nextDrive = CurrentDrive; } } Path newLocation = PathNavigation.CalculateFullPath(nextDrive.CurrentLocation, path); // I'm not a fan of this block of code. // The goal here is to throw an exception if trying to "CD" into an invalid location // // Not sure why the providerInstances are returned as a collection. Feels like given a // path we should have one provider we're talking to. if (_providerInstances.ContainsKey(nextDrive.Provider.Name)) { bool pathExists = false; IEnumerable<ItemCmdletProvider> cmdletProviders = _providerInstances[nextDrive.Provider.Name].Where(x => x is ItemCmdletProvider).Cast<ItemCmdletProvider>(); ItemCmdletProvider currentProvider = null; foreach (var provider in cmdletProviders) { if (provider.ItemExists(newLocation, providerRuntime)) { pathExists = true; currentProvider = provider; break; } } if (!pathExists) { throw new Exception(string.Format("Cannot find path '{0}' because it does not exist.", newLocation)); } else { if (currentProvider is FileSystemProvider) { System.Environment.CurrentDirectory = newLocation; } } } else { throw new NotImplementedException("Unsure how to set location with provider:" + nextDrive.Provider.Name); } nextDrive.CurrentLocation = newLocation; CurrentDrive = nextDrive; _providersCurrentDrive[CurrentDrive.Provider] = CurrentDrive; return CurrentLocation; }
public Path GetParentPath(Path root) { var path = this; // normalize first path = path.NormalizeSlashes().TrimEndSlash(); if (root != null) { root = root.NormalizeSlashes().TrimEndSlash(); if (string.Equals(path, root, StringComparison.CurrentCultureIgnoreCase)) { return new Path(CorrectSlash, WrongSlash, string.Empty); } } int iLastSlash = path._rawPath.LastIndexOf(CorrectSlash); string newPath = root; if (iLastSlash > 0) { newPath = path._rawPath.Substring(0, iLastSlash); } else if (iLastSlash == 0) { newPath = new Path(CorrectSlash, WrongSlash, CorrectSlash); } Path resultPath = new Path(CorrectSlash, WrongSlash, newPath); return resultPath.ApplyDriveSlash(); }
internal PathInfo SetLocation(Path path, ProviderRuntime providerRuntime) { // TODO: deal with paths starting with ".\" if (path == null) { throw new NullReferenceException("Path can't be null"); } PSDriveInfo nextDrive = CurrentDrive; path = path.NormalizeSlashes(); string driveName = null; if (path.TryGetDriveName(out driveName)) { nextDrive = GetDrive(driveName); } if (nextDrive == null) { nextDrive = CurrentDrive; } Path newLocation = PathNavigation.CalculateFullPath(nextDrive.CurrentLocation, path); // I'm not a fan of this block of code. // The goal here is to throw an exception if trying to "CD" into an invalid location // // Not sure why the providerInstances are returned as a collection. Feels like given a // path we should have one provider we're talking to. if (_providerInstances.ContainsKey(nextDrive.Provider.Name)) { bool pathExists = false; IEnumerable<ItemCmdletProvider> cmdletProviders = _providerInstances[nextDrive.Provider.Name].Where(x => x is ItemCmdletProvider).Cast<ItemCmdletProvider>(); ItemCmdletProvider currentProvider = null; foreach (var provider in cmdletProviders) { if (provider.ItemExists(newLocation, providerRuntime)) { pathExists = true; currentProvider = provider; break; } } if (!pathExists) { throw new Exception(string.Format("Cannot find path '{0}' because it does not exist.", newLocation)); } else { if (currentProvider is FileSystemProvider) { System.Environment.CurrentDirectory = newLocation; } } } else { throw new NotImplementedException("Unsure how to set location with provider:" + nextDrive.Provider.Name); } nextDrive.CurrentLocation = newLocation; CurrentDrive = nextDrive; _providersCurrentDrive[CurrentDrive.Provider] = CurrentDrive; return CurrentLocation; }