Skip to content

Fix bugs, remove dead code, upgrade to net8.0, add unit tests#1

Draft
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-assembly-crawler-bugs
Draft

Fix bugs, remove dead code, upgrade to net8.0, add unit tests#1
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-assembly-crawler-bugs

Conversation

Copilot AI commented Feb 21, 2026

Copy link
Copy Markdown

Multiple bugs and code quality issues identified in code review across Program.cs, Crawler.cs, Assembly.cs, and AssemblyExtension.cs. Also upgrades the project from EOL net6.0 to net8.0 and adds a unit test suite.

Bugs

  • Program.cs: Fixed misleading error message for unexpected args; wired up unused path param in InnerLoop() to auto-parse on startup; fixed "itemsfound" typo; removed dead "s" menu case and its no-op CreateSymLinkForAssembly() body; changed FileMode.OpenOrCreateFileMode.Create to prevent stale file content
  • Crawler.cs: Fixed shallow dict copy losing OrdinalIgnoreCase comparer — new Dictionary<...>(sortedAssemblies_all, StringComparer.OrdinalIgnoreCase); added break after Remove(key) in inner loop to prevent KeyNotFoundException on continued iteration

Code Quality

  • Assembly.cs: Added readonly to FileSize, PublicKeyToken, FrameworkVersion, IsManaged; removed unused using System.Security.Cryptography; removed dead /* NOTES */ C/C++ block; added Debug.WriteLine to swallowed catch in GetAssemblyName(); removed dead IsReadyToRun() (always false) and unreachable GetPublicKey()
  • Crawler.cs / AssemblyExtension.cs: Removed unused using System.Text / using System.Threading.Tasks; use .Count property on materialized List<T> instead of .Count() LINQ; removed all dead commented-out CreateSymlinks, constants, and helper methods
  • AssemblyCrawler.csproj: Upgraded TargetFramework from net6.0net8.0; bumped System.Reflection.Metadata to 8.0.0

Unit Tests

Added src/AssemblyCrawler.Tests (xUnit, net8.0) covering:

  • StringExtension.GetStableHashCode() — stability and collision avoidance
  • AssemblyInfo — managed vs. non-managed construction, GetHashCode() consistency
  • AssemblyExtensionIsManagedAssembly(), SortByHashCode() grouping
  • CrawlerCrawl() populates counts, double-crawl guard, Sort() before crawl, .resources.dll exclusion
Original prompt

Code Review Fixes

Address the following issues found during code review of the assembly crawling code in pieandcakes/AssemblyCrawler. The source code lives under src/AssemblyCrawler/.

🔴 Bugs to Fix

  1. Program.cs line 16 — Inverted argument check: if (args.Length > 0) rejects all arguments. The program takes no arguments and uses an interactive loop, so the check is backwards — it should reject when arguments are passed unexpectedly. Actually, since the program is fully interactive (no args needed), the error message "Argument count not correct" is misleading. Fix: if the intent is to accept zero arguments, keep the > 0 check but fix the error message to say something like "This program does not accept command-line arguments.". Alternatively, if a path argument should be supported, wire it up to InnerLoop.

  2. Program.cs line 26 — path parameter in InnerLoop is unused: InnerLoop(string? path = null) accepts a path but never uses it. Either remove the parameter or wire it up so that if a path is provided, it auto-parses that directory.

  3. Program.cs line 253 — Missing space in output: $"{keyItemCount} itemsfound..." should be $"{keyItemCount} items found...".

  4. Program.cs line 133 — Hidden menu option "s": The "s" case for CreateSymLinkForAssembly() is handled in the switch but is not listed in the printed menu options. Since CreateSymLinkForAssembly() is entirely commented out (no-op), remove the dead "s" case from the switch.

  5. Crawler.cs line 125 — Shallow copy of dictionary loses case-insensitive comparer: sortedAssemblies_managed = new Dictionary<...>(sortedAssemblies_all) creates a new dictionary using the default comparer instead of StringComparer.OrdinalIgnoreCase. Fix: pass the comparer explicitly, e.g. new Dictionary<string, Dictionary<string, List<AssemblyInfo>>>(sortedAssemblies_all, StringComparer.OrdinalIgnoreCase).

  6. Crawler.cs lines 130-136 — Potential InvalidOperationException / KeyNotFoundException: When iterating sortedAssemblies_managed inner keys, if the first entry's IsManaged is false, the outer key is removed mid-iteration. But the inner foreach loop continues to access sortedAssemblies_managed[key] which was just removed. Fix: add a break after sortedAssemblies_managed.Remove(key) to exit the inner loop after removing the outer key.

🟡 Code Quality / Maintainability Fixes

  1. Assembly.cs lines 47-51 — Inconsistent readonly on Lazy fields: FName, AName, AssemblyVersion, FileVersion are readonly, but FileSize, PublicKeyToken, FrameworkVersion, IsManaged are not, even though none are reassigned after construction. Add readonly to FileSize, PublicKeyToken, FrameworkVersion, and IsManaged.

  2. Assembly.cs line 9 — Unused using: Remove using System.Security.Cryptography;.

  3. Assembly.cs lines 12-37 — Large dead block comment: Remove the /* NOTES ... */ block of C/C++ pseudocode.

  4. Assembly.cs line 95 — Empty catch block silently swallows exceptions: In GetAssemblyName(), add at minimum a Debug.WriteLine or similar so failures are not silently lost.

  5. Assembly.cs line 186 — GetPublicKey() is never called: Remove the unused GetPublicKey() method.

  6. Assembly.cs lines 166-183 — IsReadyToRun() always returns false: The body is entirely commented out. Remove this dead method.

  7. Crawler.cs lines 61-62 — Unnecessary LINQ .Count() on materialized list: files is already a List<T>, so use .Count property instead of .Count() LINQ extension. For assemblyFiles, enumerate it once into a list first, then use .Count.

  8. Crawler.cs lines 142-246 — Large blocks of commented-out code: Remove dead CreateSymlinks method, unused AssemblyCacheFolderName and PreCacheFileName constants, and unused CreateDirectoryIfNotExists and MakeSymLink methods (they are only used by the commented-out code).

  9. Program.cs line 181 — FileMode.OpenOrCreate may leave stale data: Change to FileMode.Create so old content is truncated.

  10. AssemblyExtension.cs lines 7-8 — Unused using statements: Remove using System.Text; and using System.Threading.Tasks;.

  11. Crawler.cs lines 7-8 — Unused using statements: Remove using System.Text; and using System.Threading.Tasks;.

  12. AssemblyCrawler.csproj — Targets outdated net6.0: .NET 6 is end-of-life. Update TargetFramework to net8.0 and update System.Reflection.Metadata package to the latest stable version compatible with net8.0.

🧪 Unit Tests

Add a new test project (e.g. src/AssemblyCrawler.Tests/AssemblyCrawler.Tests.csproj) using xUnit or MSTest. Add it to the solution file src/AssemblyCrawler.sln. Write tests covering the following:

  • Crawler class:
    • Test that Crawl() on a valid directory populates AssemblyList, TotalFileCount, and TotalAssemblyCount.
    • Te...

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 21, 2026 20:27
Co-authored-by: pieandcakes <17558378+pieandcakes@users.noreply.github.com>
Co-authored-by: pieandcakes <17558378+pieandcakes@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix bugs in assembly crawling code Fix bugs, remove dead code, upgrade to net8.0, add unit tests Feb 21, 2026
Copilot AI requested a review from pieandcakes February 21, 2026 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants