예제 #1
0
        private static void AssertSeparatorChoice(string path, char?separator)
        {
            if (separator == null)
            {
                return;
            }

            var root = GetPathRoot(path);

            if (root == null)
            {
                return;
            }

            ControlFlow.Assert(!IsWinRoot(root) || separator == WinSeparator, $"For Windows-rooted paths the separator must be '{WinSeparator}'.");
            ControlFlow.Assert(!IsUncRoot(root) || separator == UncSeparator, $"For UNC-rooted paths the separator must be '{UncSeparator}'.");
            ControlFlow.Assert(!IsUnixRoot(root) || separator == UnixSeparator, $"For Unix-rooted paths the separator must be '{UnixSeparator}'.");
        }
예제 #2
0
        // TODO: check usages

        public static string GetRelativePath(string basePath, string destinationPath, bool normalize = true)
        {
            basePath        = NormalizePath(basePath);
            destinationPath = NormalizePath(destinationPath);

            var separator = GetSeparator(basePath);

            ControlFlow.Assert(separator == GetSeparator(destinationPath), "Separators do not match.");
            ControlFlow.Assert(!IsWinRoot(basePath) || Path.GetPathRoot(basePath) == Path.GetPathRoot(destinationPath), "Root must be same.");

            var baseParts        = basePath.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries);
            var destinationParts = destinationPath.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries);

            var sameParts = baseParts.Zip(destinationParts, (a, b) => new { Base = a, Destination = b })
                            .Count(x => x.Base.Equals(x.Destination, StringComparison.OrdinalIgnoreCase));

            return(Enumerable.Repeat("..", baseParts.Length - sameParts).ToList()
                   .Concat(destinationParts.Skip(sameParts).ToList()).Join(separator));
        }
예제 #3
0
        // ReSharper disable once CyclomaticComplexity
        public static string NormalizePath(string path, char?separator = null)
        {
            AssertSeparatorChoice(path, separator);

            path      = path ?? string.Empty;
            separator = separator ?? GetSeparator(path);
            var root = GetPathRoot(path);

            var tail      = root == null ? path : path.Substring(root.Length);
            var tailParts = tail.Split(s_allSeparators, StringSplitOptions.RemoveEmptyEntries).ToList();

            for (var i = 0; i < tailParts.Count;)
            {
                var part = tailParts[i];
                if (IsUpwardsDirectory(part))
                {
                    if (tailParts.Take(i).All(IsUpwardsDirectory))
                    {
                        ControlFlow.Assert(i > 0 || root == null, $"Cannot normalize '{path}' beyond path root.");
                        i++;
                        continue;
                    }

                    tailParts.RemoveAt(i);
                    tailParts.RemoveAt(i - 1);
                    i--;
                    continue;
                }

                if (IsSameDirectory(part))
                {
                    tailParts.RemoveAt(i);
                    continue;
                }

                i++;
            }

            return(Combine(root, tailParts.Join(separator.ToString()), separator));
        }