From 097151b87f7723119ef3d421d21c009d2e228da7 Mon Sep 17 00:00:00 2001 From: hlotyaks Date: Thu, 2 Jan 2020 20:08:07 -0500 Subject: [PATCH] add package hasher - working hash --- .github/workflows/dotnetcore.yml | 8 +++- .vscode/tasks.json | 2 +- GraphBuilder/tests/Graph.Tests.cs | 2 +- GraphBuilder/tests/GraphBuilder.Tests.cs | 2 +- GraphBuilder/tests/GraphUtilities.Tests.cs | 2 +- PackageHasher/PackageHasher.sln | 48 +++++++++++++++++++ PackageHasher/src/PackageHasher.cs | 41 +++++++++++----- PackageHasher/tests/PackageHaser.Tests.cs | 43 ++++++++++++++++- .../testcases/simple1/package1/file1.txt | 1 + .../testcases/simple2/package1/file1.txt | 1 + .../testcases/simple2/package2/file1.txt | 1 + PackageHasher/tests/tests.csproj | 8 ++++ README.md | 4 +- 13 files changed, 140 insertions(+), 23 deletions(-) create mode 100644 PackageHasher/PackageHasher.sln create mode 100644 PackageHasher/tests/testcases/simple1/package1/file1.txt create mode 100644 PackageHasher/tests/testcases/simple2/package1/file1.txt create mode 100644 PackageHasher/tests/testcases/simple2/package2/file1.txt diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index acad0ba..39b0713 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -13,7 +13,11 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: 2.2.108 - - name: Build with dotnet + - name: Build - GraphBuilder run: dotnet build GraphBuilder/GraphBuilder.sln -c Release - - name: Run tests + - name: Build - PackageHasher + run: dotnet build PackageHasher/PackageHasher.sln -c Release + - name: Test - GraphBuilder run: dotnet test GraphBuilder/tests/tests.csproj -c Release -v m + - name: Test - PackageHasher + run: dotnet test PackageHasher/tests/tests.csproj -c Release -v m diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d8d8a61..1302f14 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -10,7 +10,7 @@ "args": [ "build", // project - "${workspaceFolder}\\GraphBuilder\\src\\GraphBuilder.csproj" + "${workspaceFolder}\\GraphBuilder\\src\\GraphBuilder.csproj", // Ask dotnet build to generate full paths for file names. "/property:GenerateFullPaths=true", // Do not generate summary otherwise it leads to duplicate errors in Problems panel diff --git a/GraphBuilder/tests/Graph.Tests.cs b/GraphBuilder/tests/Graph.Tests.cs index 2fb41ba..6bdbbb7 100644 --- a/GraphBuilder/tests/Graph.Tests.cs +++ b/GraphBuilder/tests/Graph.Tests.cs @@ -1,6 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace PackageAnalyzer.Graph.Tests +namespace PackageAnalyzer.Tests { [TestClass] public class GraphTests diff --git a/GraphBuilder/tests/GraphBuilder.Tests.cs b/GraphBuilder/tests/GraphBuilder.Tests.cs index 954ab19..a7209fb 100644 --- a/GraphBuilder/tests/GraphBuilder.Tests.cs +++ b/GraphBuilder/tests/GraphBuilder.Tests.cs @@ -2,7 +2,7 @@ using PackageAnalyzer; using System.IO; -namespace PackageAnalyzer.Graph.Tests +namespace PackageAnalyzer.Tests { [TestClass] public class GraphBuilderTests diff --git a/GraphBuilder/tests/GraphUtilities.Tests.cs b/GraphBuilder/tests/GraphUtilities.Tests.cs index 838b09a..46441b6 100644 --- a/GraphBuilder/tests/GraphUtilities.Tests.cs +++ b/GraphBuilder/tests/GraphUtilities.Tests.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.IO; -namespace PackageAnalyzer.Graph.Tests +namespace PackageAnalyzer.Tests { public class GraphTestUtilities { diff --git a/PackageHasher/PackageHasher.sln b/PackageHasher/PackageHasher.sln new file mode 100644 index 0000000..79b2f70 --- /dev/null +++ b/PackageHasher/PackageHasher.sln @@ -0,0 +1,48 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackageHasher", "src\PackageHasher.csproj", "{E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tests", "tests\tests.csproj", "{3679A64B-8D42-400B-996B-8735D9A9C16C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Debug|x64.ActiveCfg = Debug|Any CPU + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Debug|x64.Build.0 = Debug|Any CPU + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Debug|x86.ActiveCfg = Debug|Any CPU + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Debug|x86.Build.0 = Debug|Any CPU + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Release|Any CPU.Build.0 = Release|Any CPU + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Release|x64.ActiveCfg = Release|Any CPU + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Release|x64.Build.0 = Release|Any CPU + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Release|x86.ActiveCfg = Release|Any CPU + {E5CCDC89-EE49-4FE6-8AAC-81E8996712FA}.Release|x86.Build.0 = Release|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Debug|x64.ActiveCfg = Debug|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Debug|x64.Build.0 = Debug|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Debug|x86.ActiveCfg = Debug|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Debug|x86.Build.0 = Debug|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Release|Any CPU.Build.0 = Release|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Release|x64.ActiveCfg = Release|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Release|x64.Build.0 = Release|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Release|x86.ActiveCfg = Release|Any CPU + {3679A64B-8D42-400B-996B-8735D9A9C16C}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/PackageHasher/src/PackageHasher.cs b/PackageHasher/src/PackageHasher.cs index cf13fbb..87ea1c3 100644 --- a/PackageHasher/src/PackageHasher.cs +++ b/PackageHasher/src/PackageHasher.cs @@ -4,42 +4,57 @@ using System.Threading.Tasks; using System.Security.Cryptography; using System.Linq; +using System.Collections.Generic; namespace PackageAnalyzer { public class PackageHasher { - public Dictionary HashFolders(List folders) + public async Task> HashFoldersAsync(List folders, string rootPath) { - Dictionary hasedFolders = new Dictionary(); + Dictionary hashedFolders = new Dictionary(); + IEnumerable> hashFolderTasksQuery = + folders.Select( f => HashFolderAsync(new DirectoryInfo(f), rootPath)); - return hasedFolders; - } - async Task HashFolder(DirectoryInfo folder, bool excludeRoot, string searchPattern = "*", SearchOption searchOption = SearchOption.AllDirectories) - { - string rootPath = String.Empty; + List> hashFolderTasks = hashFolderTasksQuery.ToList(); - if(excludeRoot) + while (hashFolderTasks.Count > 0) { - rootPath = folder.FullName.Substring(0, folder.FullName.Length - folder.FullName.Split('\\').Last().Length ); - } + Task<(string folder, string folderwithhash)> firstTask = await Task.WhenAny(hashFolderTasks); + + hashFolderTasks.Remove(firstTask); + + (string folder, string folderwithhash) HashFolderValue = await firstTask; + + hashedFolders.Add(HashFolderValue.folder, HashFolderValue.folderwithhash); + } + + return hashedFolders; + } + + async Task<(string folder, string folderwithhash)> HashFolderAsync(DirectoryInfo folder, string rootPath = "", string searchPattern = "*", SearchOption searchOption = SearchOption.AllDirectories) + { using(var alg = MD5.Create()) { - var result = await alg.ComputeHashAsync(folder.EnumerateFiles(searchPattern, searchOption), rootPath); + // Folder has starts with folder name. + // Format - name.hash + StringBuilder sb = new StringBuilder(); + sb.Append(folder.Name); + sb.Append("."); + // Build the final string by converting each byte // into hex and appending it to a StringBuilder - StringBuilder sb = new StringBuilder(); for (int i = 0; i < result.Length; i++) { sb.Append(result[i].ToString("X2")); } // And return it - return sb.ToString(); + return (folder: folder.Name, folderwithhash: sb.ToString()); } } diff --git a/PackageHasher/tests/PackageHaser.Tests.cs b/PackageHasher/tests/PackageHaser.Tests.cs index 60121c7..ce3356a 100644 --- a/PackageHasher/tests/PackageHaser.Tests.cs +++ b/PackageHasher/tests/PackageHaser.Tests.cs @@ -1,14 +1,53 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; +using PackageAnalyzer; +using System.IO; +using System.Collections.Generic; +using System.Threading.Tasks; -namespace PackageAnalyzer.PackageHasher.Tests +namespace PackageAnalyzer.Tests { [TestClass] public class PackageHasherTests { [TestMethod] - public void TestMethod1() + public void SimpleTest1() { + PackageHasher ph = new PackageHasher(); + + string cwd = Directory.GetCurrentDirectory(); + string root = $"{cwd}\\testcases\\simple2"; + + List paths = new List(); + paths.Add($"{root}\\package1"); + + var task = Task.Run(async () => await ph.HashFoldersAsync(paths, root)); + + var result = task.Result; + + Assert.AreEqual(1, result.Keys.Count); + Assert.IsTrue(result.ContainsKey("package1")); + } + + [TestMethod] + public void SimpleTest2() + { + PackageHasher ph = new PackageHasher(); + + string cwd = Directory.GetCurrentDirectory(); + string root = $"{cwd}\\testcases\\simple2"; + + List paths = new List(); + paths.Add($"{root}\\package1"); + paths.Add($"{root}\\package2"); + + var task = Task.Run(async () => await ph.HashFoldersAsync(paths, root)); + + var result = task.Result; + + Assert.AreEqual(2, result.Keys.Count); + Assert.IsTrue(result.ContainsKey("package1")); + Assert.IsTrue(result.ContainsKey("package2")); } } diff --git a/PackageHasher/tests/testcases/simple1/package1/file1.txt b/PackageHasher/tests/testcases/simple1/package1/file1.txt new file mode 100644 index 0000000..86fc6b2 --- /dev/null +++ b/PackageHasher/tests/testcases/simple1/package1/file1.txt @@ -0,0 +1 @@ +test data for file1. Just needed to get a hash value. \ No newline at end of file diff --git a/PackageHasher/tests/testcases/simple2/package1/file1.txt b/PackageHasher/tests/testcases/simple2/package1/file1.txt new file mode 100644 index 0000000..86fc6b2 --- /dev/null +++ b/PackageHasher/tests/testcases/simple2/package1/file1.txt @@ -0,0 +1 @@ +test data for file1. Just needed to get a hash value. \ No newline at end of file diff --git a/PackageHasher/tests/testcases/simple2/package2/file1.txt b/PackageHasher/tests/testcases/simple2/package2/file1.txt new file mode 100644 index 0000000..86fc6b2 --- /dev/null +++ b/PackageHasher/tests/testcases/simple2/package2/file1.txt @@ -0,0 +1 @@ +test data for file1. Just needed to get a hash value. \ No newline at end of file diff --git a/PackageHasher/tests/tests.csproj b/PackageHasher/tests/tests.csproj index 8ae4c5b..be68d11 100644 --- a/PackageHasher/tests/tests.csproj +++ b/PackageHasher/tests/tests.csproj @@ -13,4 +13,12 @@ + + + + + + + + diff --git a/README.md b/README.md index 365747b..acd0c1f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Welcome to the Package Analyzer Project This repository contains the source code for: * GraphBuilder - constructs a directed graph from xml files. Identifies cycles in the graph. - +* PackageHasher - Hashes contents of folders to be used in identifying changes. ## Project Build Status Project|Build Status ---|--- -GraphBuilder|![Build Status](https://github.com/hlotyaks/PackageAnalyzer/workflows/.NET%20Core/badge.svg) +PackageAnalyzer|![Build Status](https://github.com/hlotyaks/PackageAnalyzer/workflows/.NET%20Core/badge.svg) \ No newline at end of file