refactor: reverse Core↔Differential dependency, make all components independent - #446
Merged
Merged
Conversation
…s independent - GeneralUpdate.Differential: remove Core dependency, keep only binary diff algorithms (IBinaryDiffer, StreamingHdiffDiffer, BinaryHandler, compressors) - GeneralUpdate.Core: add Differential reference, absorb orchestration types (DefaultCleanStrategy, DefaultDirtyStrategy, DiffPipeline, DifferentialCore) - GeneralUpdate.Bowl: remove Core dependency, self-contain GeneralTracer, StorageHelper, IpcEncryption, Environments, ProcessInfo - GeneralUpdate.Drivelution: remove Core dependency, self-contain GeneralTracer - GeneralUpdate.Extension: remove Core dependency, self-contain GeneralTracer - Remove ICleanStrategy/IDirtyStrategy/IBinaryDiffer from Core.Differential namespace; they live in Core.Differential (strategies) and Differential.Abstractions (IBinaryDiffer) respectively - Update all test projects for new namespaces Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR restructures the C# projects to invert the Core↔Differential dependency (Core becomes the orchestration layer that depends on Differential’s algorithms) and to make Bowl, Drivelution, and Extension standalone components with no project references.
Changes:
- Moved directory-level differential orchestration (pipeline, strategies, matchers, progress model,
DifferentialCore) fromGeneralUpdate.DifferentialintoGeneralUpdate.Core. - Removed
GeneralUpdate.Coreproject references fromGeneralUpdate.Bowl,GeneralUpdate.Drivelution, andGeneralUpdate.Extensionby copying in tracer/IPC/filesystem helpers. - Updated Differential tests and integration tests to use the new
GeneralUpdate.Core.*namespaces and references.
Reviewed changes
Copilot reviewed 88 out of 88 changed files in this pull request and generated 20 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/DifferentialTest/Pipeline/DiffPipelineTests.cs | Update test imports to Core pipeline/models. |
| tests/DifferentialTest/Matchers/MatcherTests.cs | Update test imports to Core + adjust comments/regions. |
| tests/DifferentialTest/DifferentialUpgradeIntegrationTests.cs | Update integration test imports to Core pipeline/models. |
| tests/DifferentialTest/DifferentialTest.csproj | Add Core project reference for moved orchestration APIs. |
| src/c#/GeneralUpdate.Extension/Tracer/WindowsOutputDebugListener.cs | Add Extension-local debug-view trace listener. |
| src/c#/GeneralUpdate.Extension/Tracer/TextTraceListener.cs | Add Extension-local file-backed trace listener. |
| src/c#/GeneralUpdate.Extension/Tracer/GeneralTracer.cs | Add Extension-local tracer implementation. |
| src/c#/GeneralUpdate.Extension/GeneralUpdate.Extension.csproj | Remove Core project reference to make Extension standalone. |
| src/c#/GeneralUpdate.Extension/Download/DownloadQueueManager.cs | Swap Core tracer dependency to Extension-local tracer. |
| src/c#/GeneralUpdate.Extension/Core/GeneralExtensionHost.cs | Swap Core tracer dependency to Extension-local tracer. |
| src/c#/GeneralUpdate.Drivelution/Windows/Implementation/WindowsGeneralDrivelution.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Drivelution/Windows/Implementation/WindowsDriverValidator.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Drivelution/Windows/Implementation/WindowsDriverBackup.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Drivelution/Tracer/WindowsOutputDebugListener.cs | Add Drivelution-local debug-view trace listener. |
| src/c#/GeneralUpdate.Drivelution/Tracer/TextTraceListener.cs | Add Drivelution-local file-backed trace listener. |
| src/c#/GeneralUpdate.Drivelution/Tracer/GeneralTracer.cs | Add Drivelution-local tracer implementation. |
| src/c#/GeneralUpdate.Drivelution/MacOS/Implementation/MacOsGeneralDrivelution.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Drivelution/Linux/Implementation/LinuxGeneralDrivelution.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Drivelution/Linux/Implementation/LinuxDriverValidator.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Drivelution/Linux/Implementation/LinuxDriverBackup.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Drivelution/GeneralUpdate.Drivelution.csproj | Remove Core project reference to make Drivelution standalone. |
| src/c#/GeneralUpdate.Drivelution/GeneralDrivelution.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Drivelution/Core/Pipeline/DefaultPipelineSteps.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Drivelution/Core/Pipeline/BaseDriverUpdater.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Drivelution/Core/Execution/CommandRunner.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Drivelution/Core/DriverUpdaterFactory.cs | Swap Core tracer dependency to Drivelution-local tracer. |
| src/c#/GeneralUpdate.Differential/Pipeline/DiffPipelineOptions.cs | Remove orchestration from Differential. |
| src/c#/GeneralUpdate.Differential/Pipeline/DiffPipelineBuilder.cs | Remove orchestration from Differential. |
| src/c#/GeneralUpdate.Differential/Pipeline/DiffPipeline.cs | Remove orchestration from Differential. |
| src/c#/GeneralUpdate.Differential/Models/DiffProgress.cs | Remove orchestration model from Differential. |
| src/c#/GeneralUpdate.Differential/Matchers/IDirtyStrategy.cs | Remove orchestration API from Differential. |
| src/c#/GeneralUpdate.Differential/Matchers/IDirtyMatcher.cs | Remove orchestration API from Differential. |
| src/c#/GeneralUpdate.Differential/Matchers/ICleanStrategy.cs | Remove orchestration API from Differential. |
| src/c#/GeneralUpdate.Differential/Matchers/ICleanMatcher.cs | Remove orchestration API from Differential. |
| src/c#/GeneralUpdate.Differential/Matchers/DefaultDirtyStrategy.cs | Remove orchestration impl from Differential. |
| src/c#/GeneralUpdate.Differential/Matchers/DefaultDirtyMatcher.cs | Remove orchestration impl from Differential. |
| src/c#/GeneralUpdate.Differential/Matchers/DefaultCleanStrategy.cs | Remove orchestration impl from Differential. |
| src/c#/GeneralUpdate.Differential/Matchers/DefaultCleanMatcher.cs | Remove orchestration impl from Differential. |
| src/c#/GeneralUpdate.Differential/GeneralUpdate.Differential.csproj | Remove Core reference to keep Differential standalone. |
| src/c#/GeneralUpdate.Differential/DifferentialCore.cs | Move orchestration entrypoint out of Differential. |
| src/c#/GeneralUpdate.Differential/Abstractions/IBinaryDiffer.cs | Make IBinaryDiffer independent of Core and include both Clean/Dirty. |
| src/c#/GeneralUpdate.Core/Strategy/UpgradeUpdateStrategy.cs | Update to use Differential’s IBinaryDiffer abstraction. |
| src/c#/GeneralUpdate.Core/Strategy/ClientUpdateStrategy.cs | Update to use Differential’s IBinaryDiffer abstraction. |
| src/c#/GeneralUpdate.Core/Strategy/AbstractStrategy.cs | Update to use Differential’s IBinaryDiffer abstraction. |
| src/c#/GeneralUpdate.Core/Pipeline/DiffPipelineOptions.cs | Add pipeline options into Core. |
| src/c#/GeneralUpdate.Core/Pipeline/DiffPipelineBuilder.cs | Add pipeline builder into Core. |
| src/c#/GeneralUpdate.Core/Pipeline/DiffPipeline.cs | Add orchestrating pipeline into Core. |
| src/c#/GeneralUpdate.Core/Models/DiffProgress.cs | Add progress model into Core. |
| src/c#/GeneralUpdate.Core/GeneralUpdate.Core.csproj | Add project reference from Core → Differential. |
| src/c#/GeneralUpdate.Core/DifferentialCore.cs | Add orchestration entrypoint into Core. |
| src/c#/GeneralUpdate.Core/Differential/IDirtyMatcher.cs | Add dirty matcher interface into Core. |
| src/c#/GeneralUpdate.Core/Differential/ICleanMatcher.cs | Add clean matcher interface into Core. |
| src/c#/GeneralUpdate.Core/Differential/IBinaryDiffer.cs | Remove Core-owned IBinaryDiffer (moved to Differential.Abstractions). |
| src/c#/GeneralUpdate.Core/Differential/DefaultDirtyStrategy.cs | Add default dirty strategy into Core. |
| src/c#/GeneralUpdate.Core/Differential/DefaultDirtyMatcher.cs | Add default dirty matcher into Core. |
| src/c#/GeneralUpdate.Core/Differential/DefaultCleanStrategy.cs | Add default clean strategy into Core. |
| src/c#/GeneralUpdate.Core/Differential/DefaultCleanMatcher.cs | Add default clean matcher into Core. |
| src/c#/GeneralUpdate.Core/Configuration/AbstractBootstrap.cs | Update bootstrap extension registration to Differential’s IBinaryDiffer. |
| src/c#/GeneralUpdate.Core/Bootstrap/GeneralUpdateBootstrap.cs | Update bootstrap wiring to Differential’s IBinaryDiffer. |
| src/c#/GeneralUpdate.Bowl/Tracer/WindowsOutputDebugListener.cs | Add Bowl-local debug-view trace listener. |
| src/c#/GeneralUpdate.Bowl/Tracer/TextTraceListener.cs | Add Bowl-local file-backed trace listener. |
| src/c#/GeneralUpdate.Bowl/Tracer/GeneralTracer.cs | Add Bowl-local tracer implementation. |
| src/c#/GeneralUpdate.Bowl/Strategys/WindowStrategy.cs | Replace Core filesystem/json/env usage with Bowl-local helpers. |
| src/c#/GeneralUpdate.Bowl/Strategys/LinuxStrategy.cs | Swap Core tracer dependency to Bowl-local tracer. |
| src/c#/GeneralUpdate.Bowl/Strategys/AbstractStrategy.cs | Replace Core filesystem usage with Bowl-local helper. |
| src/c#/GeneralUpdate.Bowl/Strategies/WindowsBowlStrategy.cs | Replace Core filesystem usage with Bowl-local helper. |
| src/c#/GeneralUpdate.Bowl/Strategies/ProcessRunner.cs | Swap Core tracer dependency to Bowl-local tracer. |
| src/c#/GeneralUpdate.Bowl/Strategies/MacBowlStrategy.cs | Swap Core tracer dependency to Bowl-local tracer. |
| src/c#/GeneralUpdate.Bowl/Strategies/LinuxBowlStrategy.cs | Swap Core tracer dependency to Bowl-local tracer. |
| src/c#/GeneralUpdate.Bowl/Ipc/IpcEncryption.cs | Add Bowl-local IPC crypto helper. |
| src/c#/GeneralUpdate.Bowl/Ipc/Environments.cs | Add Bowl-local IPC environment provider using encrypted temp files. |
| src/c#/GeneralUpdate.Bowl/Internal/WindowsSystemInfoProvider.cs | Swap Core tracer dependency to Bowl-local tracer. |
| src/c#/GeneralUpdate.Bowl/Internal/EnvironmentProvider.cs | Swap Core config/env dependency to Bowl-local implementations. |
| src/c#/GeneralUpdate.Bowl/Internal/CrashReporter.cs | Replace Core serialization usage with Bowl-local helper. |
| src/c#/GeneralUpdate.Bowl/GeneralUpdate.Bowl.csproj | Remove Core project reference to make Bowl standalone. |
| src/c#/GeneralUpdate.Bowl/FileSystem/StorageHelper.cs | Add Bowl-local filesystem + JSON utilities. |
| src/c#/GeneralUpdate.Bowl/Configuration/ProcessInfo.cs | Add Bowl-local minimal ProcessInfo model. |
| src/c#/GeneralUpdate.Bowl/Bowl.cs | Update Bowl implementation to use Bowl-local helpers/types. |
| src/c#/DifferentialTest/Pipeline/DiffPipelineTests.cs | Update test imports to Core pipeline/models. |
| src/c#/DifferentialTest/Pipeline/DiffPipelineOptionsTests.cs | Update test imports to Core pipeline options. |
| src/c#/DifferentialTest/Pipeline/DiffPipelineIntegrationTests.cs | Update test imports to Core pipeline/models. |
| src/c#/DifferentialTest/Pipeline/DiffPipelineBuilderTests.cs | Update test imports to Core pipeline/models. |
| src/c#/DifferentialTest/Models/DiffProgressTests.cs | Update test imports to Core progress model. |
| src/c#/DifferentialTest/Matchers/DefaultDirtyStrategyTests.cs | Update test imports to Core differential strategy. |
| src/c#/DifferentialTest/Matchers/DefaultDirtyMatcherTests.cs | Update test imports to Core matcher. |
| src/c#/DifferentialTest/Matchers/DefaultCleanStrategyTests.cs | Update test imports to Core differential strategy. |
| src/c#/DifferentialTest/Matchers/DefaultCleanMatcherTests.cs | Update test imports to Core matcher. |
| src/c#/DifferentialTest/DifferentialCoreTests.cs | Update tests to use Core’s DifferentialCore. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+275
to
+296
| private static Task CopyUnknownFiles(string appPath, string patchPath) | ||
| { | ||
| return Task.Run(() => | ||
| { | ||
| var fileManager = new StorageManager(); | ||
| var comparisonResult = fileManager.Compare(appPath, patchPath); | ||
| foreach (var file in comparisonResult.DifferentNodes) | ||
| { | ||
| var extensionName = Path.GetExtension(file.FullName); | ||
| if (BlackListDefaults.DefaultBlackFormats.Contains(extensionName)) continue; | ||
|
|
||
| var targetFileName = file.FullName.Replace(patchPath, "").TrimStart(Path.DirectorySeparatorChar); | ||
| var targetPath = Path.Combine(appPath, targetFileName); | ||
| var parentFolder = Directory.GetParent(targetPath); | ||
| if (parentFolder?.Exists == false) | ||
| parentFolder.Create(); | ||
|
|
||
| File.Copy(file.FullName, targetPath, true); | ||
| } | ||
|
|
||
| if (Directory.Exists(patchPath)) | ||
| StorageManager.DeleteDirectory(patchPath); |
Comment on lines
+14
to
+33
| private static readonly byte[] _aesKey = SHA256.Create() | ||
| .ComputeHash(Encoding.UTF8.GetBytes("GeneralUpdate.IPC.EnvironmentProvider.v1")); | ||
| private static readonly byte[] _aesIV = new byte[16] { 0x47, 0x55, 0x50, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
|
|
||
| private static string IpcDir | ||
| { | ||
| get | ||
| { | ||
| var dir = Path.Combine(Path.GetTempPath(), "GeneralUpdate", "ipc"); | ||
| Directory.CreateDirectory(dir); | ||
| return dir; | ||
| } | ||
| } | ||
|
|
||
| public static void SetEnvironmentVariable(string key, string value) | ||
| { | ||
| var filePath = Path.Combine(IpcDir, $"{key}.enc"); | ||
| var plainBytes = Encoding.UTF8.GetBytes(value); | ||
| IpcEncryption.EncryptToFile(plainBytes, filePath, _aesKey, _aesIV); | ||
| } |
Comment on lines
+28
to
+33
| public static void SetEnvironmentVariable(string key, string value) | ||
| { | ||
| var filePath = Path.Combine(IpcDir, $"{key}.enc"); | ||
| var plainBytes = Encoding.UTF8.GetBytes(value); | ||
| IpcEncryption.EncryptToFile(plainBytes, filePath, _aesKey, _aesIV); | ||
| } |
Comment on lines
+7
to
+8
| public class TextTraceListener : TraceListener, IDisposable | ||
| { |
Comment on lines
+41
to
+50
| private void ProcessQueue() | ||
| { | ||
| foreach (var message in _messageQueue.GetConsumingEnumerable()) | ||
| { | ||
| using (var fileStream = new FileStream(_filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) | ||
| using (var writer = new StreamWriter(fileStream)) | ||
| { | ||
| writer.Write(message); | ||
| } | ||
| } |
Comment on lines
+19
to
+30
| public override void Write(string message) | ||
| { | ||
| if (!string.IsNullOrEmpty(message)) | ||
| { | ||
| OutputDebugString(message); | ||
| } | ||
| } | ||
|
|
||
| public override void WriteLine(string message) | ||
| { | ||
| Write($"{message}{Environment.NewLine}"); | ||
| } |
Comment on lines
+15
to
+33
| static GeneralTracer() | ||
| { | ||
| Trace.Listeners.Clear(); | ||
|
|
||
| if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||
| { | ||
| Trace.Listeners.Add(new WindowsOutputDebugListener()); | ||
| } | ||
|
|
||
| Trace.Listeners.Add(new TextWriterTraceListener(Console.Out) { Name = "ConsoleListener" }); | ||
|
|
||
| InitializeFileListener(); | ||
|
|
||
| if (Debugger.IsAttached) | ||
| Trace.Listeners.Add(new DefaultTraceListener()); | ||
|
|
||
| Trace.AutoFlush = true; | ||
| _isTracingEnabled = true; | ||
| } |
Comment on lines
+35
to
+58
| private static void InitializeFileListener() | ||
| { | ||
| //Ensure that log files are rotated on a daily basis | ||
| var today = DateTime.Now.ToString("yyyy-MM-dd"); | ||
| if (today == _currentLogDate && _fileListener != null) | ||
| return; | ||
|
|
||
| if (_fileListener != null) | ||
| { | ||
| Trace.Listeners.Remove(_fileListener); | ||
| _fileListener.Flush(); | ||
| _fileListener.Close(); | ||
| _fileListener.Dispose(); | ||
| } | ||
|
|
||
| var logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"); | ||
| Directory.CreateDirectory(logDir); | ||
|
|
||
| var logFileName = Path.Combine(logDir, $"generalupdate-trace {today}.log"); | ||
| _fileListener = new TextTraceListener(logFileName); | ||
|
|
||
| Trace.Listeners.Add(_fileListener); | ||
| _currentLogDate = today; | ||
| } |
Comment on lines
+22
to
+39
| public static byte[]? DecryptFromFile(string filePath, byte[] key, byte[] iv) | ||
| { | ||
| if (!File.Exists(filePath)) return null; | ||
|
|
||
| try | ||
| { | ||
| var cipher = File.ReadAllBytes(filePath); | ||
| using var aes = Aes.Create(); | ||
| aes.Key = key; | ||
| aes.IV = iv; | ||
| using var decryptor = aes.CreateDecryptor(); | ||
| return decryptor.TransformFinalBlock(cipher, 0, cipher.Length); | ||
| } | ||
| finally | ||
| { | ||
| try { File.Delete(filePath); } catch { /* best-effort cleanup */ } | ||
| } | ||
| } |
Comment on lines
+1
to
+4
| using System; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using GeneralUpdate.Core.Differential; |
- Remove duplicate using directives in Bowl.cs - Fix garbled characters in MatcherTests.cs region comment - Remove unused using directives in DiffPipelineBuilder.cs Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
IBinaryDiffer,StreamingHdiffDiffer,BinaryHandler, compression providers). Zero project references.DefaultCleanStrategy,DefaultDirtyStrategy,DiffPipeline,DifferentialCore, matchers, etc.).GeneralTracer,StorageHelper,IpcEncryption,Environments,ProcessInfo. Zero project references.GeneralTracer. Zero project references.GeneralTracer. Zero project references.ICleanStrategy/IDirtyStrategy/IBinaryDifferfromCore.Differentialnamespace. They now live inCore.Differential(strategy interfaces) andDifferential.Abstractions(IBinaryDiffer).New Dependency Graph
Architecture
Verification
dotnet build— 0 errors across all 6 projectsdotnet test— 1360 tests passed, 0 failed (CoreTest: 957, DifferentialTest: 85, BowlTest: 50, DrivelutionTest: 144, ExtensionTest: 124)🤖 Generated with Claude Code