/// <summary>
        /// Gets the absolute input path that contains the specified file or directory. If the provided
        /// file or directory path is absolute, this returns the input path that contains the specified
        /// path (note that the specified file or directory does not need to exist and this just returns
        /// the input path that would contain the file or directory based only on path information). If
        /// the provided path is relative, this checks all input paths for the existence of the file
        /// or directory and returns the first one where it exists.
        /// </summary>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="path">The file path.</param>
        /// <returns>The input path that contains the specified file,
        /// or <c>null</c> if no input path does.</returns>
        public static NormalizedPath GetContainingInputPath(this IReadOnlyFileSystem fileSystem, NormalizedPath path)
        {
            _ = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
            path.ThrowIfNull(nameof(path));

            if (path.IsAbsolute)
            {
                return(fileSystem.GetContainingInputPathForAbsolutePath(path));
            }

            // Try to find a file first
            IFile file = fileSystem.GetInputFile(path);

            if (file.Exists)
            {
                return(fileSystem.GetContainingInputPath(file.Path));
            }

            // Then try to find a directory
            IEnumerable <(NormalizedPath x, IDirectory)> rootDirectories =
                fileSystem.InputPaths
                .Reverse()
                .Select(x => (x, fileSystem.GetRootDirectory(x.Combine(path))));
            IEnumerable <(NormalizedPath x, IDirectory)> existingRootDirectories = rootDirectories.Where(x => x.Item2.Exists);

            return(existingRootDirectories.Select(x => fileSystem.RootPath.Combine(x.Item1)).FirstOrDefault());
        }
        /// <summary>
        /// Gets a file representing an input.
        /// </summary>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="path">
        /// The path of the input file. If this is an absolute path,
        /// then a file representing the specified path is returned.
        /// If it's a relative path, then operations will search all
        /// current input paths.
        /// </param>
        /// <returns>An input file.</returns>
        public static IFile GetInputFile(this IReadOnlyFileSystem fileSystem, NormalizedPath path)
        {
            _ = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
            path.ThrowIfNull(nameof(path));

            if (path.IsRelative)
            {
                IFile notFound = null;
                foreach (NormalizedPath inputPath in fileSystem.InputPaths.Reverse())
                {
                    IFile file = fileSystem.GetFile(fileSystem.RootPath.Combine(inputPath).Combine(path));
                    if (notFound == null)
                    {
                        notFound = file;
                    }
                    if (file.Exists)
                    {
                        return(file);
                    }
                }
                if (notFound == null)
                {
                    throw new InvalidOperationException("The input paths collection must have at least one path");
                }
                return(notFound);
            }
            return(fileSystem.GetFile(path));
        }
 internal DocumentFile(DocumentFileProvider fileProvider, NormalizedPath path)
 {
     _fileProvider = fileProvider ?? throw new ArgumentNullException(nameof(fileProvider));
     path.ThrowIfNull(nameof(path));
     if (!fileProvider.Files.TryGetValue(path, out _document))
     {
         _document = null;
     }
     Path = path;
 }
        /// <inheritdoc/>
        public IDirectory GetDirectory(NormalizedPath path)
        {
            path.ThrowIfNull(nameof(path));

            if (!path.IsRelative)
            {
                throw new ArgumentException("Path must be relative", nameof(path));
            }

            return(new VirtualInputDirectory(_fileSystem, Path.Combine(path)));
        }
        /// <inheritdoc/>
        public IFile GetFile(NormalizedPath path)
        {
            path.ThrowIfNull(nameof(path));

            if (!path.IsRelative)
            {
                throw new ArgumentException("Path must be relative", nameof(path));
            }

            return(_fileSystem.GetInputFile(Path.Combine(path)));
        }
        public IFile GetFile(NormalizedPath path)
        {
            path.ThrowIfNull(nameof(path));

            if (!path.IsRelative)
            {
                throw new ArgumentException("Path must be relative", nameof(path));
            }

            return(new DocumentFile(_fileProvider, Path.Combine(path)));
        }
        public IDirectory GetDirectory(NormalizedPath directory)
        {
            directory.ThrowIfNull(nameof(directory));

            if (!directory.IsRelative)
            {
                throw new ArgumentException("Path must be relative", nameof(directory));
            }

            return(new DocumentDirectory(_fileProvider, Path.Combine(directory)));
        }
        public VirtualInputDirectory(IReadOnlyFileSystem fileSystem, NormalizedPath path)
        {
            path.ThrowIfNull(nameof(path));

            if (!path.IsRelative)
            {
                throw new ArgumentException("Virtual input paths should always be relative", nameof(path));
            }

            _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
            Path        = path;
        }
        internal static NormalizedPath GetContainingInputPathForAbsolutePath(this IReadOnlyFileSystem fileSystem, NormalizedPath path)
        {
            _ = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
            path.ThrowIfNull(nameof(path));

            if (!path.IsAbsolute)
            {
                throw new ArgumentException("Path must be absolute");
            }

            return(fileSystem.InputPaths
                   .Reverse()
                   .Select(x => fileSystem.RootPath.Combine(x))
                   .FirstOrDefault(x => path.Segments.StartsWith(x.Segments)));
        }
Esempio n. 10
0
        public static IFile CreateZipFile(IExecutionContext context, NormalizedPath directory)
        {
            directory.ThrowIfNull(nameof(directory));

            IDirectory sourceDirectory = context.FileSystem.GetRootDirectory(directory);

            if (!sourceDirectory.Exists)
            {
                throw new DirectoryNotFoundException("Source zip directory does not exist");
            }
            IFile zipFile = context.FileSystem.GetTempFile();

            context.LogDebug($"Creating zip file from {sourceDirectory.Path.FullPath} at {zipFile.Path.FullPath}");
            ZipFile.CreateFromDirectory(sourceDirectory.Path.FullPath, zipFile.Path.FullPath);
            return(zipFile);
        }
        public static NormalizedPath Resolve(NormalizedPath source, NormalizedPath target)
        {
            source.ThrowIfNull(nameof(source));
            target.ThrowIfNull(nameof(target));

            // Make sure they're both either relative or absolute
            if (source.IsAbsolute != target.IsAbsolute)
            {
                throw new ArgumentException("Paths must both be relative or both be absolute");
            }

            // Check if they're the same path
            if (source.FullPath == target.FullPath)
            {
                return(NormalizedPath.Empty);
            }

            // Special case if source is just root
            if (source.IsAbsolute && source == NormalizedPath.AbsoluteRoot)
            {
                return(new NormalizedPath(string.Join(NormalizedPath.Slash, target.Segments)));
            }

            // Check if they share the same root
            if (target.Segments.Length == 0 || !source.Segments[0].SequenceEqual(target.Segments[0]))
            {
                return(target);
            }

            int minimumSegmentsLength = Math.Min(source.Segments.Length, target.Segments.Length);

            int lastCommonRoot = -1;

            // Find common root
            for (int x = 0; x < minimumSegmentsLength; x++)
            {
                if (!source.Segments[x].SequenceEqual(target.Segments[x]))
                {
                    break;
                }

                lastCommonRoot = x;
            }

            if (lastCommonRoot == -1)
            {
                return(target);
            }

            // Add relative folders in from path
            List <ReadOnlyMemory <char> > relativeSegments = new List <ReadOnlyMemory <char> >();

            for (int x = lastCommonRoot + 1; x < source.Segments.Length; x++)
            {
                if (source.Segments[x].Length > 0)
                {
                    relativeSegments.Add(NormalizedPath.DotDot.AsMemory());
                }
            }

            // Add to folders to path
            for (int x = lastCommonRoot + 1; x < target.Segments.Length; x++)
            {
                relativeSegments.Add(target.Segments[x]);
            }

            // Create relative path
            return(new NormalizedPath(string.Join("/", relativeSegments)));
        }
 internal DocumentDirectory(DocumentFileProvider fileProvider, NormalizedPath path)
 {
     _fileProvider = fileProvider ?? throw new ArgumentNullException(nameof(fileProvider));
     path.ThrowIfNull(nameof(path));
     Path = path;
 }