From 8f5ae24fee8898605f6e19b0e5f7759eec179ef8 Mon Sep 17 00:00:00 2001 From: Santiago Squarzon Date: Wed, 2 Jul 2025 12:18:46 -0300 Subject: [PATCH 1/5] multi-target --- module/PSCompression.psd1 | 9 +++++++-- src/PSCompression/Abstractions/EntryBase.cs | 2 ++ src/PSCompression/Abstractions/TarEntryBase.cs | 2 +- .../Abstractions/ToCompressedFileCommandBase.cs | 4 ++-- src/PSCompression/Abstractions/ZipEntryBase.cs | 11 +++++++---- .../Commands/ConvertFromBrotliStringCommand.cs | 3 +-- .../Commands/ExpandTarArchiveCommand.cs | 4 +++- src/PSCompression/Commands/NewZipEntryCommand.cs | 15 ++++++++------- .../Extensions/CompressionExtensions.cs | 12 +++++++----- src/PSCompression/Extensions/PathExtensions.cs | 6 +++--- src/PSCompression/OnModuleImportAndRemove.cs | 4 ++-- src/PSCompression/PSCompression.csproj | 9 ++++++++- src/PSCompression/SortingOps.cs | 4 ++-- src/PSCompression/TarEntryFile.cs | 2 +- src/PSCompression/ZipEntryCache.cs | 10 ++++++++-- src/PSCompression/ZipEntryFile.cs | 10 ++++++---- 16 files changed, 68 insertions(+), 39 deletions(-) diff --git a/module/PSCompression.psd1 b/module/PSCompression.psd1 index 66574f7..3a65081 100644 --- a/module/PSCompression.psd1 +++ b/module/PSCompression.psd1 @@ -8,10 +8,15 @@ @{ # Script module or binary module file associated with this manifest. - RootModule = 'bin/netstandard2.0/PSCompression.dll' + RootModule = if ($PSEdition -eq 'Core') { + 'bin/net8.0/PSCompression.dll' + } + else { + 'bin/netstandard2.0/PSCompression.dll' + } # Version number of this module. - ModuleVersion = '3.0.0' + ModuleVersion = '3.0.1' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/src/PSCompression/Abstractions/EntryBase.cs b/src/PSCompression/Abstractions/EntryBase.cs index 78847fe..99a5b1f 100644 --- a/src/PSCompression/Abstractions/EntryBase.cs +++ b/src/PSCompression/Abstractions/EntryBase.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.IO; namespace PSCompression.Abstractions; @@ -11,6 +12,7 @@ public abstract class EntryBase(string source) internal string? FormatDirectoryPath { get => _formatDirectoryPath ??= GetFormatDirectoryPath(); } + [MemberNotNullWhen(true, nameof(_stream))] internal bool FromStream { get => _stream is not null; } public string Source { get; } = source; diff --git a/src/PSCompression/Abstractions/TarEntryBase.cs b/src/PSCompression/Abstractions/TarEntryBase.cs index b83a4b4..bdb6bd7 100644 --- a/src/PSCompression/Abstractions/TarEntryBase.cs +++ b/src/PSCompression/Abstractions/TarEntryBase.cs @@ -36,7 +36,7 @@ internal FileSystemInfo ExtractTo( } FileInfo file = new(destination); - file.Directory.Create(); + file.Directory?.Create(); using FileStream destStream = File.Open( destination, diff --git a/src/PSCompression/Abstractions/ToCompressedFileCommandBase.cs b/src/PSCompression/Abstractions/ToCompressedFileCommandBase.cs index 2338d13..90eefef 100644 --- a/src/PSCompression/Abstractions/ToCompressedFileCommandBase.cs +++ b/src/PSCompression/Abstractions/ToCompressedFileCommandBase.cs @@ -69,7 +69,7 @@ protected override void BeginProcessing() try { - Directory.CreateDirectory(IOPath.GetDirectoryName(Destination)); + Directory.CreateDirectory(IOPath.GetDirectoryName(Destination)!); _destination = File.Open(Destination, FileMode); _archive = CreateCompressionStream(_destination); @@ -116,7 +116,7 @@ private void Traverse(DirectoryInfo dir, T archive) { _queue.Enqueue(dir); IEnumerable enumerator; - int length = dir.Parent.FullName.Length + 1; + int length = dir.Parent!.FullName.Length + 1; while (_queue.Count > 0) { diff --git a/src/PSCompression/Abstractions/ZipEntryBase.cs b/src/PSCompression/Abstractions/ZipEntryBase.cs index d4a4344..d6ecaf0 100644 --- a/src/PSCompression/Abstractions/ZipEntryBase.cs +++ b/src/PSCompression/Abstractions/ZipEntryBase.cs @@ -97,7 +97,7 @@ internal ZipArchive OpenZip(ZipArchiveMode mode) => public FileSystemInfo ExtractTo(string destination, bool overwrite) { - using ZipArchive zip = _stream is not null + using ZipArchive zip = FromStream ? new ZipArchive(_stream, ZipArchiveMode.Read, leaveOpen: true) : ZipFile.OpenRead(Source); @@ -120,10 +120,13 @@ internal FileSystemInfo ExtractTo( } FileInfo file = new(destination); - file.Directory.Create(); + file.Directory?.Create(); + + if (zip.TryGetEntry(RelativePath, out ZipArchiveEntry? entry)) + { + entry.ExtractToFile(destination, overwrite); + } - ZipArchiveEntry entry = zip.GetEntry(RelativePath); - entry.ExtractToFile(destination, overwrite); return file; } } diff --git a/src/PSCompression/Commands/ConvertFromBrotliStringCommand.cs b/src/PSCompression/Commands/ConvertFromBrotliStringCommand.cs index dfe29a7..7de4ec9 100644 --- a/src/PSCompression/Commands/ConvertFromBrotliStringCommand.cs +++ b/src/PSCompression/Commands/ConvertFromBrotliStringCommand.cs @@ -1,7 +1,6 @@ using System.IO; using System.IO.Compression; using System.Management.Automation; -using BrotliSharpLib; using PSCompression.Abstractions; namespace PSCompression.Commands; @@ -12,5 +11,5 @@ namespace PSCompression.Commands; public sealed class ConvertFromBrotliStringCommand : FromCompressedStringCommandBase { protected override Stream CreateDecompressionStream(Stream inputStream) => - new BrotliStream(inputStream, CompressionMode.Decompress); + new BrotliSharpLib.BrotliStream(inputStream, CompressionMode.Decompress); } diff --git a/src/PSCompression/Commands/ExpandTarArchiveCommand.cs b/src/PSCompression/Commands/ExpandTarArchiveCommand.cs index 669e9eb..8a1ee7d 100644 --- a/src/PSCompression/Commands/ExpandTarArchiveCommand.cs +++ b/src/PSCompression/Commands/ExpandTarArchiveCommand.cs @@ -113,6 +113,8 @@ private FileSystemInfo[] ExtractArchive(string path) private FileSystemInfo ExtractEntry(TarEntry entry, TarInputStream tar) { + Dbg.Assert(Destination is not null); + string destination = IO.Path.GetFullPath( IO.Path.Combine(Destination, entry.Name)); @@ -124,7 +126,7 @@ private FileSystemInfo ExtractEntry(TarEntry entry, TarInputStream tar) } FileInfo file = new(destination); - file.Directory.Create(); + file.Directory?.Create(); using (FileStream destStream = File.Open( destination, diff --git a/src/PSCompression/Commands/NewZipEntryCommand.cs b/src/PSCompression/Commands/NewZipEntryCommand.cs index 3de6656..770ee4a 100644 --- a/src/PSCompression/Commands/NewZipEntryCommand.cs +++ b/src/PSCompression/Commands/NewZipEntryCommand.cs @@ -40,7 +40,7 @@ public sealed class NewZipEntryCommand : PSCmdlet, IDisposable public string[]? EntryPath { get => _entryPath; - set => _entryPath = [.. value.Select(e => e.NormalizePath())]; + set => _entryPath = [.. value!.Select(e => e.NormalizePath())]; } [Parameter] @@ -194,17 +194,18 @@ private IEnumerable GetResult() foreach (ZipArchiveEntry entry in _entries) { + if (!zip.TryGetEntry(entry.FullName, out ZipArchiveEntry? zipEntry)) + { + continue; + } + if (string.IsNullOrEmpty(entry.Name)) { - _result.Add(new ZipEntryDirectory( - zip.GetEntry(entry.FullName), - Destination)); + _result.Add(new ZipEntryDirectory(zipEntry, Destination)); continue; } - _result.Add(new ZipEntryFile( - zip.GetEntry(entry.FullName), - Destination)); + _result.Add(new ZipEntryFile(zipEntry, Destination)); } return _result.ToEntrySort(); diff --git a/src/PSCompression/Extensions/CompressionExtensions.cs b/src/PSCompression/Extensions/CompressionExtensions.cs index a1fe7ca..0480b14 100644 --- a/src/PSCompression/Extensions/CompressionExtensions.cs +++ b/src/PSCompression/Extensions/CompressionExtensions.cs @@ -5,7 +5,6 @@ using System.IO.Compression; using System.Management.Automation; using System.Text.RegularExpressions; -using BrotliSharpLib; using ICSharpCode.SharpZipLib.BZip2; using ICSharpCode.SharpZipLib.Tar; using SharpCompress.Compressors.LZMA; @@ -54,7 +53,10 @@ internal static bool TryGetEntry( this ZipArchive zip, string path, [NotNullWhen(true)] out ZipArchiveEntry? entry) - => (entry = zip.GetEntry(path)) is not null; + { + entry = zip.GetEntry(path); + return entry is not null; + } internal static string ChangeName( this ZipEntryFile file, @@ -91,7 +93,7 @@ internal static void WriteAllTextToPipeline(this StreamReader reader, PSCmdlet c internal static void WriteLinesToPipeline(this StreamReader reader, PSCmdlet cmdlet) { - string line; + string? line; while ((line = reader.ReadLine()) is not null) { cmdlet.WriteObject(line); @@ -114,11 +116,11 @@ internal static void WriteContent(this StreamWriter writer, string[] lines) } } - internal static BrotliStream AsBrotliCompressedStream( + internal static BrotliSharpLib.BrotliStream AsBrotliCompressedStream( this Stream stream, CompressionLevel compressionLevel) { - BrotliStream brotli = new(stream, CompressionMode.Compress); + BrotliSharpLib.BrotliStream brotli = new(stream, CompressionMode.Compress); brotli.SetQuality(compressionLevel switch { CompressionLevel.NoCompression => 0, diff --git a/src/PSCompression/Extensions/PathExtensions.cs b/src/PSCompression/Extensions/PathExtensions.cs index 0a2e5d6..1cb40fe 100644 --- a/src/PSCompression/Extensions/PathExtensions.cs +++ b/src/PSCompression/Extensions/PathExtensions.cs @@ -83,14 +83,14 @@ internal static void Create(this DirectoryInfo dir, bool force) internal static PSObject AppendPSProperties(this FileSystemInfo info) { - string parent = info is DirectoryInfo dir - ? dir.Parent.FullName + string? parent = info is DirectoryInfo dir + ? dir.Parent?.FullName : Unsafe.As(info).DirectoryName; return info.AppendPSProperties(parent); } - internal static PSObject AppendPSProperties(this FileSystemInfo info, string parent) + internal static PSObject AppendPSProperties(this FileSystemInfo info, string? parent) { const string provider = @"Microsoft.PowerShell.Core\FileSystem::"; PSObject pso = PSObject.AsPSObject(info); diff --git a/src/PSCompression/OnModuleImportAndRemove.cs b/src/PSCompression/OnModuleImportAndRemove.cs index e100d8b..d507c49 100644 --- a/src/PSCompression/OnModuleImportAndRemove.cs +++ b/src/PSCompression/OnModuleImportAndRemove.cs @@ -44,7 +44,7 @@ public void OnRemove(PSModuleInfo module) /// private static Assembly? MyResolveEventHandler(object? sender, ResolveEventArgs args) { - string libDirectory = Path.GetDirectoryName(typeof(OnModuleImportAndRemove).Assembly.Location); + string? libDirectory = Path.GetDirectoryName(typeof(OnModuleImportAndRemove).Assembly.Location); List directoriesToSearch = []; if (!string.IsNullOrEmpty(libDirectory)) @@ -85,6 +85,6 @@ public void OnRemove(PSModuleInfo module) /// Determine if the current runtime is .NET Framework /// /// - private bool IsNetFramework() => RuntimeInformation.FrameworkDescription + private static bool IsNetFramework() => RuntimeInformation.FrameworkDescription .StartsWith(".NET Framework", StringComparison.OrdinalIgnoreCase); } diff --git a/src/PSCompression/PSCompression.csproj b/src/PSCompression/PSCompression.csproj index 4a12f39..36f7877 100644 --- a/src/PSCompression/PSCompression.csproj +++ b/src/PSCompression/PSCompression.csproj @@ -1,7 +1,7 @@ - netstandard2.0 + netstandard2.0;net8.0 enable true PSCompression @@ -17,9 +17,16 @@ + + + + + + + true true diff --git a/src/PSCompression/SortingOps.cs b/src/PSCompression/SortingOps.cs index b275207..ae1d6ae 100644 --- a/src/PSCompression/SortingOps.cs +++ b/src/PSCompression/SortingOps.cs @@ -8,8 +8,8 @@ namespace PSCompression; internal static class SortingOps { - private static string SortByParent(EntryBase entry) => - Path.GetDirectoryName(entry.RelativePath).NormalizeEntryPath(); + private static string? SortByParent(EntryBase entry) => + Path.GetDirectoryName(entry.RelativePath)?.NormalizeEntryPath(); private static int SortByLength(EntryBase entry) => entry.RelativePath.Count(e => e == '/'); diff --git a/src/PSCompression/TarEntryFile.cs b/src/PSCompression/TarEntryFile.cs index 10773f7..fa847d3 100644 --- a/src/PSCompression/TarEntryFile.cs +++ b/src/PSCompression/TarEntryFile.cs @@ -30,7 +30,7 @@ internal TarEntryFile(TarEntry entry, Stream? stream, Algorithm algorithm) } protected override string GetFormatDirectoryPath() => - $"/{Path.GetDirectoryName(RelativePath).NormalizeEntryPath()}"; + $"/{Path.GetDirectoryName(RelativePath)?.NormalizeEntryPath()}"; internal bool GetContentStream(Stream destination) { diff --git a/src/PSCompression/ZipEntryCache.cs b/src/PSCompression/ZipEntryCache.cs index c167cf3..3c14c7a 100644 --- a/src/PSCompression/ZipEntryCache.cs +++ b/src/PSCompression/ZipEntryCache.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO.Compression; using PSCompression.Abstractions; +using PSCompression.Extensions; namespace PSCompression; @@ -41,13 +42,18 @@ internal IEnumerable GetEntries() using ZipArchive zip = ZipFile.OpenRead(entry.Key); foreach ((string path, EntryType type) in entry.Value) { + if (!zip.TryGetEntry(path, out ZipArchiveEntry? zipEntry)) + { + continue; + } + if (type is EntryType.Archive) { - yield return new ZipEntryFile(zip.GetEntry(path), entry.Key); + yield return new ZipEntryFile(zipEntry, entry.Key); continue; } - yield return new ZipEntryDirectory(zip.GetEntry(path), entry.Key); + yield return new ZipEntryDirectory(zipEntry, entry.Key); } } } diff --git a/src/PSCompression/ZipEntryFile.cs b/src/PSCompression/ZipEntryFile.cs index 7d7a7b5..f322517 100644 --- a/src/PSCompression/ZipEntryFile.cs +++ b/src/PSCompression/ZipEntryFile.cs @@ -55,11 +55,13 @@ internal void Refresh() internal void Refresh(ZipArchive zip) { - ZipArchiveEntry entry = zip.GetEntry(RelativePath); - Length = entry.Length; - CompressedLength = entry.CompressedLength; + if (zip.TryGetEntry(RelativePath, out ZipArchiveEntry? entry)) + { + Length = entry.Length; + CompressedLength = entry.CompressedLength; + } } protected override string GetFormatDirectoryPath() => - $"/{Path.GetDirectoryName(RelativePath).NormalizeEntryPath()}"; + $"/{Path.GetDirectoryName(RelativePath)?.NormalizeEntryPath()}"; } From 3f93f30350f98c9ec7ee6e2a82226db89d2665ac Mon Sep 17 00:00:00 2001 From: Santiago Squarzon Date: Wed, 2 Jul 2025 13:52:39 -0300 Subject: [PATCH 2/5] fix coverage issue.... --- src/PSCompression/PSCompression.csproj | 7 ------- tools/ProjectBuilder/Project.cs | 23 ++++++++++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/PSCompression/PSCompression.csproj b/src/PSCompression/PSCompression.csproj index 36f7877..d052b85 100644 --- a/src/PSCompression/PSCompression.csproj +++ b/src/PSCompression/PSCompression.csproj @@ -17,16 +17,9 @@ - - - - - - - true true diff --git a/tools/ProjectBuilder/Project.cs b/tools/ProjectBuilder/Project.cs index 9afcd3a..a84530f 100644 --- a/tools/ProjectBuilder/Project.cs +++ b/tools/ProjectBuilder/Project.cs @@ -18,13 +18,22 @@ public sealed class Project public string? TestFramework { - get => _info.PowerShellVersion is { Major: 5, Minor: 1 } - ? TargetFrameworks - .Where(e => Regex.Match(e, "^net(?:4|standard)").Success) - .FirstOrDefault() - : TargetFrameworks - .Where(e => !e.StartsWith("net4")) - .FirstOrDefault(); + get + { + if (TargetFrameworks is { Length: 1 }) + { + return TargetFrameworks.First(); + } + + return _info.PowerShellVersion is { Major: 5, Minor: 1 } + ? TargetFrameworks + .Where(e => Regex.Match(e, "^net(?:4|standard)").Success) + .FirstOrDefault() + + : TargetFrameworks + .Where(e => !Regex.Match(e, "^net(?:4|standard)").Success) + .FirstOrDefault(); + } } private Configuration Configuration { get => _info.Configuration; } From 38ef5c2bfafc0b22c27c4460c33288b9954ebcaf Mon Sep 17 00:00:00 2001 From: Santiago Squarzon Date: Wed, 2 Jul 2025 14:41:57 -0300 Subject: [PATCH 3/5] adds ALC support to the project --- module/PSCompression.psd1 | 7 +- module/PSCompression.psm1 | 33 +++++++++ src/PSCompression.Shared/LoadContext.cs | 72 +++++++++++++++++++ .../PSCompression.Shared.csproj | 14 ++++ src/PSCompression.Shared/SharedUtil.cs | 21 ++++++ src/PSCompression/PSCompression.csproj | 4 ++ 6 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 module/PSCompression.psm1 create mode 100644 src/PSCompression.Shared/LoadContext.cs create mode 100644 src/PSCompression.Shared/PSCompression.Shared.csproj create mode 100644 src/PSCompression.Shared/SharedUtil.cs diff --git a/module/PSCompression.psd1 b/module/PSCompression.psd1 index 3a65081..ab55e7f 100644 --- a/module/PSCompression.psd1 +++ b/module/PSCompression.psd1 @@ -8,12 +8,7 @@ @{ # Script module or binary module file associated with this manifest. - RootModule = if ($PSEdition -eq 'Core') { - 'bin/net8.0/PSCompression.dll' - } - else { - 'bin/netstandard2.0/PSCompression.dll' - } + RootModule = 'PSCompression.psm1' # Version number of this module. ModuleVersion = '3.0.1' diff --git a/module/PSCompression.psm1 b/module/PSCompression.psm1 new file mode 100644 index 0000000..b85482f --- /dev/null +++ b/module/PSCompression.psm1 @@ -0,0 +1,33 @@ +using namespace System.IO +using namespace System.Reflection +using namespace PSCompression.Shared + +$moduleName = [Path]::GetFileNameWithoutExtension($PSCommandPath) +$frame = 'net8.0' + +if (-not $IsCoreCLR) { + $frame = 'netstandard2.0' + $asm = [Path]::Combine($PSScriptRoot, 'bin', $frame, "${moduleName}.dll") + Import-Module -Name $asm -ErrorAction Stop -PassThru + return +} + +$context = [Path]::Combine($PSScriptRoot, 'bin', $frame, "${moduleName}.Shared.dll") +$isReload = $true + +if (-not ("${moduleName}.Shared.LoadContext" -as [type])) { + $isReload = $false + Add-Type -Path $context +} + +$mainModule = [LoadContext]::Initialize() +$innerMod = Import-Module -Assembly $mainModule -PassThru:$isReload + +if ($innerMod) { + $addExportedCmdlet = [psmoduleinfo].GetMethod( + 'AddExportedCmdlet', [BindingFlags] 'Instance, NonPublic') + + foreach ($cmd in $innerMod.ExportedCmdlets.Values) { + $addExportedCmdlet.Invoke($ExecutionContext.SessionState.Module, @($cmd)) + } +} diff --git a/src/PSCompression.Shared/LoadContext.cs b/src/PSCompression.Shared/LoadContext.cs new file mode 100644 index 0000000..e61208f --- /dev/null +++ b/src/PSCompression.Shared/LoadContext.cs @@ -0,0 +1,72 @@ +using System.IO; +using System.Reflection; +using System.Runtime.Loader; + +namespace PSCompression.Shared; + +public sealed class LoadContext : AssemblyLoadContext +{ + private static LoadContext? _instance; + + private readonly static object s_sync = new(); + + private readonly Assembly _thisAssembly; + + private readonly AssemblyName _thisAssemblyName; + + private readonly Assembly _moduleAssembly; + + private readonly string _assemblyDir; + + private LoadContext(string mainModulePathAssemblyPath) + : base(name: "PSCompression", isCollectible: false) + { + _assemblyDir = Path.GetDirectoryName(mainModulePathAssemblyPath) ?? ""; + _thisAssembly = typeof(LoadContext).Assembly; + _thisAssemblyName = _thisAssembly.GetName(); + _moduleAssembly = LoadFromAssemblyPath(mainModulePathAssemblyPath); + } + + protected override Assembly? Load(AssemblyName assemblyName) + { + if (AssemblyName.ReferenceMatchesDefinition(_thisAssemblyName, assemblyName)) + { + return _thisAssembly; + } + + string asmPath = Path.Join(_assemblyDir, $"{assemblyName.Name}.dll"); + if (File.Exists(asmPath)) + { + return LoadFromAssemblyPath(asmPath); + } + + return null; + } + + public static Assembly Initialize() + { + LoadContext? instance = _instance; + if (instance is not null) + { + return instance._moduleAssembly; + } + + lock (s_sync) + { + if (_instance is not null) + { + return _instance._moduleAssembly; + } + + string assemblyPath = typeof(LoadContext).Assembly.Location; + string assemblyName = Path.GetFileNameWithoutExtension(assemblyPath); + string moduleName = assemblyName[..^7]; + string modulePath = Path.Combine( + Path.GetDirectoryName(assemblyPath)!, + $"{moduleName}.dll"); + + _instance = new LoadContext(modulePath); + return _instance._moduleAssembly; + } + } +} diff --git a/src/PSCompression.Shared/PSCompression.Shared.csproj b/src/PSCompression.Shared/PSCompression.Shared.csproj new file mode 100644 index 0000000..fb4da02 --- /dev/null +++ b/src/PSCompression.Shared/PSCompression.Shared.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + PSCompression.Shared + latest + + + + + + + diff --git a/src/PSCompression.Shared/SharedUtil.cs b/src/PSCompression.Shared/SharedUtil.cs new file mode 100644 index 0000000..81c5a7f --- /dev/null +++ b/src/PSCompression.Shared/SharedUtil.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Loader; + +namespace PowerShellKusto.Shared; + +internal sealed class SharedUtil +{ + public static void AddAssemblyInfo(Type type, Dictionary data) + { + Assembly asm = type.Assembly; + + data["Assembly"] = new Dictionary() + { + ["Name"] = asm.GetName().FullName, + ["ALC"] = AssemblyLoadContext.GetLoadContext(asm)?.Name, + ["Location"] = asm.Location + }; + } +} diff --git a/src/PSCompression/PSCompression.csproj b/src/PSCompression/PSCompression.csproj index d052b85..e100fb4 100644 --- a/src/PSCompression/PSCompression.csproj +++ b/src/PSCompression/PSCompression.csproj @@ -20,6 +20,10 @@ + + + + true true From f90a6707045beb01c1cc8bfe1afcde523bf59dae Mon Sep 17 00:00:00 2001 From: Santiago Squarzon Date: Wed, 2 Jul 2025 14:55:53 -0300 Subject: [PATCH 4/5] exclude ALC src from coverage... --- src/PSCompression.Shared/LoadContext.cs | 5 +++-- src/PSCompression.Shared/SharedUtil.cs | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/PSCompression.Shared/LoadContext.cs b/src/PSCompression.Shared/LoadContext.cs index e61208f..048bb01 100644 --- a/src/PSCompression.Shared/LoadContext.cs +++ b/src/PSCompression.Shared/LoadContext.cs @@ -1,9 +1,11 @@ +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; using System.Runtime.Loader; namespace PSCompression.Shared; +[ExcludeFromCodeCoverage] public sealed class LoadContext : AssemblyLoadContext { private static LoadContext? _instance; @@ -65,8 +67,7 @@ public static Assembly Initialize() Path.GetDirectoryName(assemblyPath)!, $"{moduleName}.dll"); - _instance = new LoadContext(modulePath); - return _instance._moduleAssembly; + return new LoadContext(modulePath)._moduleAssembly; } } } diff --git a/src/PSCompression.Shared/SharedUtil.cs b/src/PSCompression.Shared/SharedUtil.cs index 81c5a7f..0706d93 100644 --- a/src/PSCompression.Shared/SharedUtil.cs +++ b/src/PSCompression.Shared/SharedUtil.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.Loader; -namespace PowerShellKusto.Shared; +namespace PSCompression.Shared; +[ExcludeFromCodeCoverage] internal sealed class SharedUtil { public static void AddAssemblyInfo(Type type, Dictionary data) From 2080c2608ead29736e68ab8057e3cb75352676ca Mon Sep 17 00:00:00 2001 From: Santiago Squarzon Date: Wed, 2 Jul 2025 15:26:11 -0300 Subject: [PATCH 5/5] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1893963..79676b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 07/02/2025 + +- Added `AssemblyLoadContext` support for PowerShell 7 (.NET 8.0) to resolve DLL hell by isolating module dependencies. No support for PowerShell 5.1 (.NET Framework) due to lack of `AssemblyLoadContext` in that runtime. + ## 06/23/2025 - Added commands supporting several algorithms to compress and decompress strings: