private async Task <DirectoryTreeNode> GetVpkInventoryFileTreeAsync(VpkInventory vpkInventory, CancellationToken cancellationToken = default) { var rootNode = new DirectoryTreeNode() { Name = "Root" }; foreach (var package in vpkInventory.Packages) { cancellationToken.ThrowIfCancellationRequested(); var packageNode = new DirectoryTreeNode() { Name = package.Filename }; foreach (var entry in package.Entries) { cancellationToken.ThrowIfCancellationRequested(); var currentDirectory = packageNode; var pathParts = entry.Filename.Split('/'); // Last part is always filename for (int i = 0; i < pathParts.Length - 1; i++) { var childDirectory = currentDirectory.Directories.SingleOrDefault(d => d.Name == pathParts[i]); if (childDirectory == null) { childDirectory = new DirectoryTreeNode() { Name = pathParts[i] }; currentDirectory.Directories.Add(childDirectory); } currentDirectory = childDirectory; } currentDirectory.Files.Add(new FileTreeNode() { Name = pathParts.Last(), Hash = entry.Sha256, }); } rootNode.Directories.Add(packageNode); } return(rootNode); }
public async Task <DirectoryTreeNode> CalculateFileTreeDiffAsync(DirectoryTreeNode sourceTree, DirectoryTreeNode targetTree, CancellationToken cancellationToken = default) { var directoryName = sourceTree != null ? sourceTree.Name : targetTree.Name; var diffDirectory = new DirectoryTreeNode() { Name = directoryName, }; if (sourceTree == null) { foreach (var file in targetTree.Files) { cancellationToken.ThrowIfCancellationRequested(); diffDirectory.Files.Add(new FileTreeNode() { Name = file.Name, DiffState = DiffState.Added }); } foreach (var directory in targetTree.Directories) { cancellationToken.ThrowIfCancellationRequested(); diffDirectory.Directories.Add(await CalculateFileTreeDiffAsync(null, directory, cancellationToken)); } } else if (targetTree == null) { foreach (var file in sourceTree.Files) { cancellationToken.ThrowIfCancellationRequested(); diffDirectory.Files.Add(new FileTreeNode() { Name = file.Name, DiffState = DiffState.Deleted }); } foreach (var directory in sourceTree.Directories) { cancellationToken.ThrowIfCancellationRequested(); diffDirectory.Directories.Add(await CalculateFileTreeDiffAsync(directory, null, cancellationToken)); } } else { foreach (var targetFile in targetTree.Files) { cancellationToken.ThrowIfCancellationRequested(); var fileDiffStatus = DiffState.None; var sourceFile = sourceTree.Files.SingleOrDefault(c => c.Name == targetFile.Name); if (sourceFile == null) { fileDiffStatus = DiffState.Added; } else if (sourceFile.Hash != targetFile.Hash) { fileDiffStatus = DiffState.Modified; } diffDirectory.Files.Add(new FileTreeNode() { Name = targetFile.Name, DiffState = fileDiffStatus }); } foreach (var targetDirectory in targetTree.Directories) { cancellationToken.ThrowIfCancellationRequested(); var sourceDirectory = sourceTree.Directories.SingleOrDefault(c => c.Name == targetDirectory.Name); diffDirectory.Directories.Add(await CalculateFileTreeDiffAsync(sourceDirectory, targetDirectory, cancellationToken)); } } return(diffDirectory); }