From 1354620da9912a8aeeefb7dd3407121d7aee4bb2 Mon Sep 17 00:00:00 2001 From: Bernie White Date: Sat, 25 Jan 2025 17:05:43 +1000 Subject: [PATCH] Added support dependency management in VSCode #2734 --- docs/CHANGELOG-v3.md | 5 + package.json | 33 +- .../Commands/ModuleCommand.cs | 7 +- .../Commands/ListenCommand.cs | 33 +- .../UpgradeDependencyCommandHandler.cs | 67 +++ .../UpgradeDependencyCommandHandlerInput.cs | 20 + .../UpgradeDependencyCommandHandlerOutput.cs | 12 + .../Hosting/LspServer.cs | 58 +- .../Hosting/ServerLogger.cs | 50 ++ src/PSRule.Tool/packages.lock.json | 541 +++++++++--------- src/PSRule.Types/Runtime/LoggerExtensions.cs | 12 + src/vscode-ps-rule/README.md | 4 +- src/vscode-ps-rule/client.ts | 5 +- .../commands/upgradeDependency.ts | 100 ++++ src/vscode-ps-rule/configuration.ts | 15 + src/vscode-ps-rule/dependencyLens.ts | 152 +++++ src/vscode-ps-rule/docLens.ts | 3 + src/vscode-ps-rule/extension.ts | 20 + .../test/suite/configuration.test.ts | 3 +- .../LanguageServerTestContainer.cs | 84 +++ .../LspServerTests.cs | 44 ++ .../PSRule.EditorServices.Tests.csproj | 12 +- tests/PSRule.EditorServices.Tests/Usings.cs | 2 +- 23 files changed, 978 insertions(+), 304 deletions(-) create mode 100644 src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandler.cs create mode 100644 src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandlerInput.cs create mode 100644 src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandlerOutput.cs create mode 100644 src/PSRule.EditorServices/Hosting/ServerLogger.cs create mode 100644 src/vscode-ps-rule/commands/upgradeDependency.ts create mode 100644 src/vscode-ps-rule/dependencyLens.ts create mode 100644 tests/PSRule.EditorServices.Tests/LanguageServerTestContainer.cs create mode 100644 tests/PSRule.EditorServices.Tests/LspServerTests.cs diff --git a/docs/CHANGELOG-v3.md b/docs/CHANGELOG-v3.md index 5a82df9df6..f1c6ab058e 100644 --- a/docs/CHANGELOG-v3.md +++ b/docs/CHANGELOG-v3.md @@ -29,6 +29,11 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers What's changed since pre-release v3.0.0-B0390: +- New features: + - Added support dependency management in VSCode by @BernieWhite. + [#2734](https://github.com/microsoft/PSRule/issues/2734) + - Code lens in `ps-rule.lock.json` allows you to upgrade all or specific modules to the latest version. + - The command `Upgrade dependency` allows you to upgrade all or specific modules to the latest version. - Bug fixes: - Fixed upgrade dependency could use pre-release version by @BernieWhite. [#2726](https://github.com/microsoft/PSRule/issues/2726) diff --git a/package.json b/package.json index 01e787590b..cdb40233e9 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,11 @@ "command": "PSRule.initLock", "title": "Initialize lock file", "category": "PSRule" + }, + { + "command": "PSRule.upgradeDependency", + "title": "Upgrade dependency", + "category": "PSRule" } ], "configuration": [ @@ -115,7 +120,13 @@ "PSRule.codeLens.ruleDocumentationLinks": { "type": "boolean", "default": true, - "description": "Enables Code Lens that displays links to rule documentation.", + "markdownDescription": "Enables Code Lens that displays links to rule documentation.", + "scope": "application" + }, + "PSRule.codeLens.dependencyManagement": { + "type": "boolean", + "default": true, + "markdownDescription": "Enables Code Lens that displays links to manage dependencies.", "scope": "application" }, "PSRule.documentation.path": { @@ -127,13 +138,13 @@ "PSRule.documentation.localePath": { "type": "string", "default": null, - "description": "The locale path to use for locating rule documentation. The VS Code locale will be used by default.", + "markdownDescription": "The locale path to use for locating rule documentation. The VS Code locale will be used by default.", "scope": "window" }, "PSRule.documentation.customSnippetPath": { "type": "string", "default": null, - "description": "The path to a file containing a rule documentation snippet. When not set, built-in PSRule snippets will be used.", + "markdownDescription": "The path to a file containing a rule documentation snippet. When not set, built-in PSRule snippets will be used.", "scope": "window" }, "PSRule.documentation.snippet": { @@ -199,45 +210,43 @@ "PSRule.experimental.enabled": { "type": "boolean", "default": false, - "description": "Enables experimental features in the PSRule extension.", + "markdownDescription": "Enables experimental features in the PSRule extension.", "scope": "application" }, "PSRule.lock.restore": { "type": "boolean", "default": false, - "description": "Determines if workspace modules will automatically be restored during activation. Modules can be restored manually using the PSRule: Restore modules command.", "markdownDescription": "Determines if workspace modules will automatically be restored during activation. Modules can be restored manually using the `PSRule: Restore modules` command.", "scope": "window" }, "PSRule.notifications.showChannelUpgrade": { "type": "boolean", "default": true, - "description": "Determines if a notification to switch to the stable channel is shown on activation.", + "markdownDescription": "Determines if a notification to switch to the stable channel is shown on activation.", "scope": "application" }, "PSRule.notifications.showModuleRestore": { "type": "boolean", "default": true, - "description": "Determines if a notification to restore modules is shown on activation.", + "markdownDescription": "Determines if a notification to restore modules is shown on activation.", "scope": "application" }, "PSRule.notifications.showPowerShellExtension": { "type": "boolean", "default": true, - "description": "Determines if a notification to install the PowerShell extension is shown on activation.", + "markdownDescription": "Determines if a notification to install the PowerShell extension is shown on activation.", "scope": "application" }, "PSRule.options.path": { "type": "string", "default": null, - "description": "The path specifying a PSRule option file. When not set, the default ps-rule.yaml will be used from the current workspace.", "markdownDescription": "The path specifying a PSRule option file. When not set, the default `ps-rule.yaml` will be used from the current workspace.", "scope": "window" }, "PSRule.output.as": { "type": "string", "default": "Summary", - "description": "Configures the output of analysis tasks, either summary or detailed.", + "markdownDescription": "Configures the output of analysis tasks, either summary or detailed.", "enum": [ "Detail", "Summary" @@ -247,13 +256,13 @@ "PSRule.rule.baseline": { "type": "string", "default": null, - "description": "The name of the default baseline to use for executing rules. This setting can be overridden on individual PSRule tasks.", + "markdownDescription": "The name of the default baseline to use for executing rules. This setting can be overridden on individual PSRule tasks.", "scope": "window" }, "PSRule.trace.task": { "type": "string", "default": "Off", - "description": "Determines if verbose logging is enabled for task output.", + "markdownDescription": "Determines if verbose logging is enabled for task output.", "enum": [ "Off", "Verbose" diff --git a/src/PSRule.CommandLine/Commands/ModuleCommand.cs b/src/PSRule.CommandLine/Commands/ModuleCommand.cs index 639434961c..3957e0c381 100644 --- a/src/PSRule.CommandLine/Commands/ModuleCommand.cs +++ b/src/PSRule.CommandLine/Commands/ModuleCommand.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System.Collections; +using System.CommandLine.IO; using System.Diagnostics.CodeAnalysis; using System.Management.Automation; using Newtonsoft.Json; @@ -376,7 +377,7 @@ public static async Task ModuleUpgradeAsync(ModuleOptions operationOptions, if (idealVersion == kv.Value.Version) continue; - if (!IsInstalled(pwsh, kv.Key, idealVersion, out _, out _) && await InstallVersionAsync(clientContext, kv.Key, idealVersion, null, cancellationToken) == null) + if (!IsInstalled(pwsh, kv.Key, idealVersion, out _, out var modulePath) && await InstallVersionAsync(clientContext, kv.Key, idealVersion, null, cancellationToken) == null) { clientContext.LogError(Messages.Error_501, kv.Key, idealVersion); return ERROR_MODULE_FAILED_TO_INSTALL; @@ -385,7 +386,7 @@ public static async Task ModuleUpgradeAsync(ModuleOptions operationOptions, clientContext.LogVerbose(Messages.UsingModule, kv.Key, idealVersion.ToString()); kv.Value.Version = idealVersion; - kv.Value.Integrity = IntegrityBuilder.Build(clientContext.IntegrityAlgorithm, GetModulePath(clientContext, kv.Key, idealVersion)); + kv.Value.Integrity = IntegrityBuilder.Build(clientContext.IntegrityAlgorithm, modulePath ?? GetModulePath(clientContext, kv.Key, idealVersion)); kv.Value.IncludePrerelease = (kv.Value.IncludePrerelease.GetValueOrDefault(false) || operationOptions.Prerelease) && !idealVersion.Stable ? true : null; file.Modules[kv.Key] = kv.Value; } @@ -441,7 +442,7 @@ private static IEnumerable GetModules(PowerShell pwsh, LockFile fi private static void ListModules(ClientContext context, IEnumerable results) { - context.Invocation.Console.Out.Write(JsonConvert.SerializeObject(results, new JsonSerializerSettings + context.Invocation.Console.Out.WriteLine(JsonConvert.SerializeObject(results, new JsonSerializerSettings { Formatting = Formatting.Indented })); diff --git a/src/PSRule.EditorServices/Commands/ListenCommand.cs b/src/PSRule.EditorServices/Commands/ListenCommand.cs index 3d2b0668aa..e4c641d132 100644 --- a/src/PSRule.EditorServices/Commands/ListenCommand.cs +++ b/src/PSRule.EditorServices/Commands/ListenCommand.cs @@ -2,6 +2,8 @@ // Licensed under the MIT License. using System.IO.Pipes; +using Microsoft.Extensions.DependencyInjection; +using OmniSharp.Extensions.LanguageServer.Server; using PSRule.CommandLine; using PSRule.EditorServices.Hosting; using PSRule.EditorServices.Models; @@ -16,6 +18,12 @@ internal sealed class ListenCommand private const string LOCAL_PIPE_SERVER_NAME = "."; private const string WINDOWS_PIPE_PREFIX = @"\\.\pipe\"; + // Timeout in minutes to wait for the debugger to attach. + private const int DEBUGGER_ATTACH_TIMEOUT = 5; + + // Time in milliseconds to wait between debugger attach checks. + private const int DEBUGGER_ATTACH_CYCLE_WAIT_TIME = 500; + private const int ERROR_SUCCESS = 0; private const int ERROR_INVALID_CONFIGURATION = 901; private const int ERROR_SERVER_EXCEPTION = 902; @@ -35,13 +43,13 @@ public static async Task ListenAsync(ListenOptions operationOptions, Client System.Diagnostics.Debugger.Break(); } - var server = await GetServerAsync(operationOptions, cancellationToken); + var server = await GetServerAsync(operationOptions, clientContext, cancellationToken); if (server == null) return ERROR_INVALID_CONFIGURATION; try { - await server.RunAsync(cancellationToken); + await server.RunWaitAsync(cancellationToken); } catch (Exception ex) { @@ -52,7 +60,7 @@ public static async Task ListenAsync(ListenOptions operationOptions, Client return ERROR_SUCCESS; } - private static async Task GetServerAsync(ListenOptions operationOptions, CancellationToken cancellationToken) + private static async Task GetServerAsync(ListenOptions operationOptions, ClientContext clientContext, CancellationToken cancellationToken) { // Create a server with a named pipe client stream. if (operationOptions.Pipe is { } pipeName) @@ -61,6 +69,8 @@ public static async Task ListenAsync(ListenOptions operationOptions, Client return new LspServer(options => { + WithServices(options, clientContext); + options.WithInput(clientPipe) .WithOutput(clientPipe) .RegisterForDisposal(clientPipe); @@ -70,6 +80,8 @@ public static async Task ListenAsync(ListenOptions operationOptions, Client { return new LspServer(options => { + WithServices(options, clientContext); + options.WithInput(Console.OpenStandardInput()) .WithOutput(Console.OpenStandardOutput()); }); @@ -101,12 +113,12 @@ private static async Task WaitForDebuggerAsync(CancellationToken cancellat var debuggerTimeoutToken = CancellationTokenSource.CreateLinkedTokenSource ( cancellationToken, - new CancellationTokenSource(TimeSpan.FromMinutes(5)).Token + new CancellationTokenSource(TimeSpan.FromMinutes(DEBUGGER_ATTACH_TIMEOUT)).Token ).Token; while (!System.Diagnostics.Debugger.IsAttached) { - await Task.Delay(500, debuggerTimeoutToken); + await Task.Delay(DEBUGGER_ATTACH_CYCLE_WAIT_TIME, debuggerTimeoutToken); } } catch @@ -116,4 +128,15 @@ private static async Task WaitForDebuggerAsync(CancellationToken cancellat return true; } + + /// + /// Register services for dependency injection. + /// + private static void WithServices(LanguageServerOptions options, ClientContext clientContext) + { + options.WithServices(services => + { + services.AddSingleton(clientContext); + }); + } } diff --git a/src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandler.cs b/src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandler.cs new file mode 100644 index 0000000000..9b0b29236c --- /dev/null +++ b/src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandler.cs @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.LanguageServer.Protocol.Window; +using OmniSharp.Extensions.LanguageServer.Protocol.Workspace; +using PSRule.CommandLine; +using PSRule.CommandLine.Commands; +using PSRule.CommandLine.Models; +using PSRule.Runtime; + +namespace PSRule.EditorServices.Handlers; + +/// +/// Handler the upgradeDependency command. +/// This command upgrades a module dependency to the latest version that meeds any specified constraints. +/// +public sealed class UpgradeDependencyCommandHandler(ClientContext context, ISerializer serializer, ILogger logger) + : ExecuteTypedResponseCommandHandlerBase(COMMAND_NAME, serializer) +{ + private const string COMMAND_NAME = "upgradeDependency"; + private const string ALL_MODULES_PLACEHOLDER = "*"; + + private readonly ClientContext _Context = context; + private readonly ILogger _Logger = logger; + + /// + /// Handle the upgradeDependency command. + /// + public override async Task Handle(UpgradeDependencyCommandHandlerInput input, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(input, nameof(input)); + ArgumentException.ThrowIfNullOrWhiteSpace(input.Path, nameof(input.Path)); + ArgumentException.ThrowIfNullOrWhiteSpace(input.Module, nameof(input.Module)); + + var all = input.Module == ALL_MODULES_PLACEHOLDER; + + var options = new ModuleOptions + { + Module = all ? null : [input.Module], + }; + + if (all) + { + _Logger.LogInformation(new EventId(0), "Checking for upgrades of all modules in: {0}", input.Path); + } + else + { + _Logger.LogInformation(new EventId(0), "Checking for upgrades of module {0} in: {1}", input.Module, input.Path); + } + + try + { + var exitCode = await ModuleCommand.ModuleUpgradeAsync(options, _Context, cancellationToken); + if (exitCode != 0) + { + throw new InvalidOperationException("Module upgrade failed"); + } + } + catch (Exception ex) + { + _Logger.LogError(new EventId(0), ex, ex.Message); + } + + return new UpgradeDependencyCommandHandlerOutput(); + } +} diff --git a/src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandlerInput.cs b/src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandlerInput.cs new file mode 100644 index 0000000000..04cf32a371 --- /dev/null +++ b/src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandlerInput.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace PSRule.EditorServices.Handlers; + +/// +/// Input for the upgrade dependency command handler. +/// +public sealed class UpgradeDependencyCommandHandlerInput +{ + /// + /// The path to the options file. + /// + public string? Path { get; set; } + + /// + /// The module to upgrade. + /// + public string? Module { get; set; } +} diff --git a/src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandlerOutput.cs b/src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandlerOutput.cs new file mode 100644 index 0000000000..15888ef5d9 --- /dev/null +++ b/src/PSRule.EditorServices/Handlers/UpgradeDependencyCommandHandlerOutput.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace PSRule.EditorServices.Handlers; + +/// +/// Output for the upgrade dependency command handler. +/// +public sealed class UpgradeDependencyCommandHandlerOutput +{ + +} diff --git a/src/PSRule.EditorServices/Hosting/LspServer.cs b/src/PSRule.EditorServices/Hosting/LspServer.cs index 1ce95e5d57..0355798150 100644 --- a/src/PSRule.EditorServices/Hosting/LspServer.cs +++ b/src/PSRule.EditorServices/Hosting/LspServer.cs @@ -1,36 +1,69 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using Microsoft.Extensions.DependencyInjection; +using OmniSharp.Extensions.LanguageServer.Protocol.Server; using OmniSharp.Extensions.LanguageServer.Protocol.Window; using OmniSharp.Extensions.LanguageServer.Server; +using PSRule.EditorServices.Handlers; +using PSRule.Runtime; namespace PSRule.EditorServices.Hosting; /// /// The LSP server for PSRule integration. /// -internal sealed class LspServer(Action configure) : IDisposable +internal sealed class LspServer : IDisposable { - private readonly LanguageServer _Server = LanguageServer.PreInit(options => - { - WithHandlers(options); - WithEvents(options); - - configure(options); - }); + private readonly LanguageServer _Server; private bool _Disposed; + public LspServer(Action configure) + { + _Server = LanguageServer.PreInit(options => + { + WithHandlers(options); + WithEvents(options); + WithServices(options); + + configure(options); + }); + } + /// /// Run the language server and block until exit. /// + public async Task RunWaitAsync(CancellationToken cancellationToken) + { + await RunAsync(cancellationToken); + await WaitForExitAsync(); + } + public async Task RunAsync(CancellationToken cancellationToken) { await _Server.Initialize(cancellationToken); _Server.LogInfo($"Language server running on processId: {System.Environment.ProcessId}"); + } - await _Server.WaitForExit; + /// + /// Returns a task that can be awaited to block calls until the server exits. + /// + public Task WaitForExitAsync() + { + return _Server.WaitForExit; + } + + /// + /// Register services for dependency injection. + /// + private void WithServices(LanguageServerOptions options) + { + options.WithServices(services => + { + services.AddSingleton(new ServerLogger(GetLanguageServer)); + }); } /// @@ -38,7 +71,7 @@ public async Task RunAsync(CancellationToken cancellationToken) /// private static void WithHandlers(LanguageServerOptions options) { - // options.WithHandler(); + options.WithHandler(); } /// @@ -53,6 +86,11 @@ private static void WithEvents(LanguageServerOptions options) }); } + private ILanguageServer? GetLanguageServer() + { + return _Server; + } + #region IDisposable private void Dispose(bool disposing) diff --git a/src/PSRule.EditorServices/Hosting/ServerLogger.cs b/src/PSRule.EditorServices/Hosting/ServerLogger.cs new file mode 100644 index 0000000000..21015ff378 --- /dev/null +++ b/src/PSRule.EditorServices/Hosting/ServerLogger.cs @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using OmniSharp.Extensions.LanguageServer.Protocol.Server; +using OmniSharp.Extensions.LanguageServer.Protocol.Window; +using PSRule.Runtime; + +namespace PSRule.EditorServices.Hosting; + +/// +/// Diagnostic logging client to send logs to the server client. +/// +internal sealed class ServerLogger(Func languageServer) : ILogger +{ + private readonly Func _LanguageServer = languageServer; + + public bool IsEnabled(LogLevel logLevel) + { + return logLevel == LogLevel.Information || + logLevel == LogLevel.Warning || + logLevel == LogLevel.Error || + logLevel == LogLevel.Debug; + } + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) + { + if (_LanguageServer == null) + return; + + var logger = _LanguageServer(); + if (logger == null) + return; + + switch (logLevel) + { + case LogLevel.Debug: + case LogLevel.Information: + logger.LogInfo(formatter(state, exception)); + break; + + case LogLevel.Warning: + logger.LogWarning(formatter(state, exception)); + break; + + case LogLevel.Error: + logger.LogError(formatter(state, exception)); + break; + } + } +} diff --git a/src/PSRule.Tool/packages.lock.json b/src/PSRule.Tool/packages.lock.json index 85789e2e69..aa7bab44da 100644 --- a/src/PSRule.Tool/packages.lock.json +++ b/src/PSRule.Tool/packages.lock.json @@ -25,13 +25,13 @@ }, "Json.More.Net": { "type": "Transitive", - "resolved": "2.0.1.2", - "contentHash": "uF3QeiaXEfH92emz0/BWUiNtMSfxIIvgynuB0Bf1vF4s8eWTcZitBx9l+g/FDaJk5XxqBv9buQXizXKQcXFG1w==" + "resolved": "2.0.2", + "contentHash": "izscdjjk8EAHDBCjyz7V7n77SzkrSjh/hUGV6cyR6PlVdjYDh5ohc8yqvwSqJ9+6Uof8W6B24dIHlDKD+I1F8A==" }, "JsonPointer.Net": { "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "fm4T5w20AY6C+p5/pJr0vrXRNGgtSfHl34I1LxC9zdPwS9S3j0GiR1Mz/CVPWKDXXGDpCt1APHpCq7kn5adCfA==", + "resolved": "5.0.2", + "contentHash": "H/OtixKadr+ja1j7Fru3WG56V9zP0AKT1Bd0O7RWN/zH1bl8ZIwW9aCa4+xvzuVvt4SPmrvBu3G6NpAkNOwNAA==", "dependencies": { "Humanizer.Core": "2.14.1", "Json.More.Net": "2.0.1.2" @@ -357,8 +357,8 @@ }, "Microsoft.Extensions.ObjectPool": { "type": "Transitive", - "resolved": "8.0.10", - "contentHash": "u7gAG7JgxF8VSJUGPSudAcPxOt+ymJKQCSxNRxiuKV+klCQbHljQR75SilpedCTfhPWDhtUwIJpnDVtspr9nMg==" + "resolved": "8.0.12", + "contentHash": "eW86yBDr/9sn7aVZqfg1O3sPDIfD5455GXkK2RZ6eS21w2Zq9CK+rPR526aNIrn0b4bN49eNScxvO4O7MKcssw==" }, "Microsoft.Extensions.Options": { "type": "Transitive", @@ -397,10 +397,10 @@ }, "Microsoft.Management.Infrastructure.CimCmdlets": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "pWlnAxpOLZf5lTX0SPX68dukSFowbEiGd39jRcO5rhsXDG5TjWrF3x1KxlFtMbiMGqJewVn5MJ7FlOWZDD7E3g==", + "resolved": "7.4.7", + "contentHash": "Gi9LGD3hj7j0eEYQnSF7mtYCe7mX+CK5Tb8l9JNHP44YyrKLh4gId4GxKaj+Vz0BMMzzpllJE9dHgeXu1rt2Sw==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.Management.Infrastructure.Runtime.Unix": { @@ -425,47 +425,49 @@ }, "Microsoft.PowerShell.Commands.Diagnostics": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "beys8wUfsWNda8JVr/Oj/Erx4PeC/AQC3X/TaU/O/BKKjzO1evm+Moz7wOOHb7bK3mqfGIWjsbOC9U/aRZGpGA==", + "resolved": "7.4.7", + "contentHash": "iSUdSG62b4wl4m5U5/O/RLBzF0GPgdpGIiE8if0VvwitqsRBtO0KKTF10rkz5Br5tFTkpo1ir1XM1VtfUdTQ9w==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.PowerShell.Commands.Management": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "IqM/FMnJMWpausi+ONG/eD2w7phwHG6SgKtLOG7anmlCiFOefjnQX2Jf3ihm7TYQJIFbxg05LtoIviyICJ8Wrw==", + "resolved": "7.4.7", + "contentHash": "3tJyPRLs+2hICQrD3R38dHypsUfsOisuhox52U9vyiqy0gnHfUhO3tYf/az7mZpLHsW1M4JHufegKzmMRQQTsw==", "dependencies": { - "Microsoft.PowerShell.Security": "7.4.6", + "Microsoft.PowerShell.Security": "7.4.7", "System.ServiceProcess.ServiceController": "8.0.1" } }, "Microsoft.PowerShell.Commands.Utility": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "dqu5AGtk/MH73osSK6on14X3a1TfBolKDnPMXM5EC6vo1XtpDL70MFoomypwgwkxz5B29p2+gtVoGqiQz5cicQ==", + "resolved": "7.4.7", + "contentHash": "5Z+R9su13qjgdRe94QF+mdc7n9IZGJxUfSw+wQU3FX77+lewBhAudne4gALJ2x7reM2Mq1lQM2Sg4AkVoCesmg==", "dependencies": { + "Json.More.Net": "2.0.2", + "JsonPointer.Net": "5.0.2", "JsonSchema.Net": "7.0.4", "Markdig.Signed": "0.33.0", "Microsoft.CodeAnalysis.CSharp": "4.9.2", "Microsoft.PowerShell.MarkdownRender": "7.2.1", - "System.Drawing.Common": "9.0.0-preview.6.24327.6", - "System.Management.Automation": "7.4.6", - "System.Threading.AccessControl": "9.0.0-preview.6.24327.7" + "System.Drawing.Common": "8.0.12", + "System.Management.Automation": "7.4.7", + "System.Threading.AccessControl": "8.0.0" } }, "Microsoft.PowerShell.ConsoleHost": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "LOMd4Zl4rsf3gHHwDf0L8iFdvLgHBACMQlgS3viz0L49N2o+0v5TAJSLOpjg77lcuH43rKLfjN+aoEen78iUBQ==", + "resolved": "7.4.7", + "contentHash": "6RjWr4N9xq5vK20UgKM5qUb32FPS3sX+I6cRdL+jZIkjaN75K2tBXlcYbVJQpM5ZNmsKD1rgRyZdkJv27ncEqA==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.PowerShell.CoreCLR.Eventing": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "z8XYESoGwJYT/L60192dE+n1dS7HRvbh2VinadhD3/zA6fDC/lu0VhQc42c56K4JiIMsLfHUUtaPJEa1JPaNBg==", + "resolved": "7.4.7", + "contentHash": "/Tlx5AqodsTCwxqEO0/K137DPrHwfnzQ7WYductm9B+JFbGIf7fxJ/yy0/yvlQrLTXLmnJU97ybOnjT4v1g2CA==", "dependencies": { "System.Diagnostics.EventLog": "8.0.1" } @@ -485,22 +487,23 @@ }, "Microsoft.PowerShell.SDK": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "fQb9dKdx+fD5vbJ5wjFngeJ1qSkJ91M3jy6bomVsrs1tLNnB06/8pm42Cv+6xhUVQGKV0JKMFy44+QjHl5puqQ==", + "resolved": "7.4.7", + "contentHash": "VdQT7kvYyuTCgmlSu3s3Tj2mCbKlrFHleTRLKrwFaPlgw0RUmluFjKfCHFx8BzfKVUlXZJBPkjuGSkLFZb58MA==", "dependencies": { "Microsoft.Bcl.AsyncInterfaces": "8.0.0", - "Microsoft.Extensions.ObjectPool": "8.0.10", - "Microsoft.Management.Infrastructure.CimCmdlets": "7.4.6", - "Microsoft.PowerShell.Commands.Diagnostics": "7.4.6", - "Microsoft.PowerShell.Commands.Management": "7.4.6", - "Microsoft.PowerShell.Commands.Utility": "7.4.6", - "Microsoft.PowerShell.ConsoleHost": "7.4.6", - "Microsoft.PowerShell.Security": "7.4.6", - "Microsoft.WSMan.Management": "7.4.6", - "Microsoft.Windows.Compatibility": "8.0.10", + "Microsoft.Extensions.ObjectPool": "8.0.12", + "Microsoft.Management.Infrastructure.CimCmdlets": "7.4.7", + "Microsoft.PowerShell.Commands.Diagnostics": "7.4.7", + "Microsoft.PowerShell.Commands.Management": "7.4.7", + "Microsoft.PowerShell.Commands.Utility": "7.4.7", + "Microsoft.PowerShell.ConsoleHost": "7.4.7", + "Microsoft.PowerShell.Security": "7.4.7", + "Microsoft.WSMan.Management": "7.4.7", + "Microsoft.Windows.Compatibility": "8.0.12", "System.Data.SqlClient": "4.8.6", + "System.Drawing.Common": "8.0.12", "System.IO.Packaging": "8.0.1", - "System.Management.Automation": "7.4.6", + "System.Management.Automation": "7.4.7", "System.Net.Http.WinHttpHandler": "8.0.2", "System.Private.ServiceModel": "4.10.3", "System.Runtime.Caching": "8.0.1", @@ -515,16 +518,16 @@ }, "Microsoft.PowerShell.Security": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "62WzHhtzItjTMbEV88J5zL65/1HIZspEoWGwFAAi9ajoUzJOZUtdGyBQPa7ZsxszPk/Ktk+h3QtW0hwBVdrrPg==", + "resolved": "7.4.7", + "contentHash": "dxAFqGRdYGbkAM53FYIxf7tGmZSLxmYR/t5GAQqK1lO22ymHIXm+TC5IlYBzO+X3AmSevV8zRlEbS34AQtnOtw==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.Security.Extensions": { "type": "Transitive", - "resolved": "1.2.0", - "contentHash": "GjHZBE5PHKrxPRyGujWQKwbKNjPQYds6HcAWKeV49X3KPgBfF2B1vV5uJey5UluyGQlvAO/DezL7WzEx9HlPQA==" + "resolved": "1.3.0", + "contentHash": "xK8WFEo5WMUE8DI8W+GjhRwpVcPrxc4DyTjfxh39+yOyhAtC5TBHDlFEJks5toNZHsUeUuiWELIX25oTWOKPBw==" }, "Microsoft.SourceLink.Common": { "type": "Transitive", @@ -547,13 +550,13 @@ }, "Microsoft.Win32.SystemEvents": { "type": "Transitive", - "resolved": "9.0.0-preview.6.24327.7", - "contentHash": "iY1g4tiJLFzV+Ygp+g78w8sNMkDLiEY9nYnZVhVto+lAt6UVzw5ZqwRvLGDPzyrV9J1D/MKchmnziLkL8Ro6hA==" + "resolved": "8.0.0", + "contentHash": "9opKRyOKMCi2xJ7Bj7kxtZ1r9vbzosMvRrdEhVhDz8j8MoBGgB+WmC94yH839NPH+BclAjtQ/pyagvi/8gDLkw==" }, "Microsoft.Windows.Compatibility": { "type": "Transitive", - "resolved": "8.0.10", - "contentHash": "V92Ri/nR0VqFT6vAVGj20sl0GI6tEFlZiB1IENyPdSdjs+1k5O1lr4vVwtIwoutlib8UyO8tnBwngT6SoOqvyA==", + "resolved": "8.0.12", + "contentHash": "Q+ge4Kuo0X6FioH+SY2E2VE5QNLkuJF6maOfXi3QHurFXzBZswbTN2eYCQutui3ygtRVvrzzkYQIMdUBnrOhow==", "dependencies": { "Microsoft.Win32.Registry.AccessControl": "8.0.0", "Microsoft.Win32.SystemEvents": "8.0.0", @@ -569,7 +572,7 @@ "System.DirectoryServices": "8.0.0", "System.DirectoryServices.AccountManagement": "8.0.1", "System.DirectoryServices.Protocols": "8.0.0", - "System.Drawing.Common": "8.0.10", + "System.Drawing.Common": "8.0.12", "System.IO.Packaging": "8.0.1", "System.IO.Ports": "8.0.0", "System.Management": "8.0.0", @@ -594,18 +597,18 @@ }, "Microsoft.WSMan.Management": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "bBEx8+wstdxpsXjqkOPvVq53PwCksDWb7VtyzXjzLdMGY33gPo8H8P3OACUluOcMG/Kd7rPnBszsP7CFhSkKSg==", + "resolved": "7.4.7", + "contentHash": "l4YJP8FvjKyEe4ETQG5tpXsor1Xb49RPaADCwk//Pp9tGJeDjcptui8mIUbpHGK7LDCZpQoYLucgQ4/Wue5R8g==", "dependencies": { - "Microsoft.WSMan.Runtime": "7.4.6", - "System.Management.Automation": "7.4.6", + "Microsoft.WSMan.Runtime": "7.4.7", + "System.Management.Automation": "7.4.7", "System.ServiceProcess.ServiceController": "8.0.1" } }, "Microsoft.WSMan.Runtime": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "pnNVcVUT+CP7r23Ju/+nhp0fLSdwevAZwe3qe8XQEahYOUv9ACIP29GijRsjdOwIL8+7DaLUQF5jjh+P/ZjGTQ==" + "resolved": "7.4.7", + "contentHash": "fpSryf4e/80fo5oeVfrXkpoESQnk3cA1rE9LaTS+qLWQl+TSxCVf5HZp8YPncAWSrFTuxqx3XET8+WGG5+lgWw==" }, "Newtonsoft.Json": { "type": "Transitive", @@ -982,10 +985,10 @@ }, "System.Drawing.Common": { "type": "Transitive", - "resolved": "9.0.0-preview.6.24327.6", - "contentHash": "4mNJBnN4iroaz44NIcYVKSPgOqhBTsPHqBG5aTfSjsKWCkRzhKnkVsWuYzx4FrZoEToGveMvUCanlY/V7GUZ5A==", + "resolved": "8.0.12", + "contentHash": "mZrI0KKFAZO8gWaARhdaJblMUNEeHMlPsFa/nRS4j4EenYP/+f8F2bzu4yb0Co7WYuJ/w/D8d/zW4KGCdYJCyQ==", "dependencies": { - "Microsoft.Win32.SystemEvents": "9.0.0-preview.6.24327.7" + "Microsoft.Win32.SystemEvents": "8.0.0" } }, "System.Formats.Asn1": { @@ -1097,14 +1100,14 @@ }, "System.Management.Automation": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "RxrDUOJuLC7Sd2RaUHf52ujP5VpdfSVTv75nwgEVAROCfYV4IcSd5mL4mLrKa+6LjkXGli7aUs853UyCwidl1A==", + "resolved": "7.4.7", + "contentHash": "6lWtGdSDaM8Nby/Bbiqw8KqnN/fqne/GqdbkGK5obh4Np9LHvgXxCODAaRcKQr6borJ1DPPO4ZwmwX1kLDRGtw==", "dependencies": { "Microsoft.ApplicationInsights": "2.21.0", "Microsoft.Management.Infrastructure": "3.0.0", - "Microsoft.PowerShell.CoreCLR.Eventing": "7.4.6", + "Microsoft.PowerShell.CoreCLR.Eventing": "7.4.7", "Microsoft.PowerShell.Native": "7.4.0", - "Microsoft.Security.Extensions": "1.2.0", + "Microsoft.Security.Extensions": "1.3.0", "Microsoft.Win32.Registry.AccessControl": "8.0.0", "Newtonsoft.Json": "13.0.3", "System.Configuration.ConfigurationManager": "8.0.1", @@ -1603,8 +1606,8 @@ }, "System.Threading.AccessControl": { "type": "Transitive", - "resolved": "9.0.0-preview.6.24327.7", - "contentHash": "t7e5cLBMvBx9/YhNsCp8W8iUw7geh08y0GKFawfJUD5YLgx6AjO2D497+0qHbXRQGpl2uxBGmkWKnCZ5azILZQ==" + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==" }, "System.Threading.Tasks": { "type": "Transitive", @@ -1646,7 +1649,7 @@ "type": "Project", "dependencies": { "Microsoft.PSRule.SDK": "[0.0.1, )", - "Microsoft.PowerShell.SDK": "[7.4.6, )", + "Microsoft.PowerShell.SDK": "[7.4.7, )", "NuGet.Protocol": "[6.12.1, )", "System.CommandLine": "[2.0.0-beta4.22272.1, )" } @@ -1681,10 +1684,10 @@ "net8.0/linux-musl-x64": { "Microsoft.Management.Infrastructure.CimCmdlets": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "pWlnAxpOLZf5lTX0SPX68dukSFowbEiGd39jRcO5rhsXDG5TjWrF3x1KxlFtMbiMGqJewVn5MJ7FlOWZDD7E3g==", + "resolved": "7.4.7", + "contentHash": "Gi9LGD3hj7j0eEYQnSF7mtYCe7mX+CK5Tb8l9JNHP44YyrKLh4gId4GxKaj+Vz0BMMzzpllJE9dHgeXu1rt2Sw==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.Management.Infrastructure.Runtime.Unix": { @@ -1699,47 +1702,49 @@ }, "Microsoft.PowerShell.Commands.Diagnostics": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "beys8wUfsWNda8JVr/Oj/Erx4PeC/AQC3X/TaU/O/BKKjzO1evm+Moz7wOOHb7bK3mqfGIWjsbOC9U/aRZGpGA==", + "resolved": "7.4.7", + "contentHash": "iSUdSG62b4wl4m5U5/O/RLBzF0GPgdpGIiE8if0VvwitqsRBtO0KKTF10rkz5Br5tFTkpo1ir1XM1VtfUdTQ9w==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.PowerShell.Commands.Management": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "IqM/FMnJMWpausi+ONG/eD2w7phwHG6SgKtLOG7anmlCiFOefjnQX2Jf3ihm7TYQJIFbxg05LtoIviyICJ8Wrw==", + "resolved": "7.4.7", + "contentHash": "3tJyPRLs+2hICQrD3R38dHypsUfsOisuhox52U9vyiqy0gnHfUhO3tYf/az7mZpLHsW1M4JHufegKzmMRQQTsw==", "dependencies": { - "Microsoft.PowerShell.Security": "7.4.6", + "Microsoft.PowerShell.Security": "7.4.7", "System.ServiceProcess.ServiceController": "8.0.1" } }, "Microsoft.PowerShell.Commands.Utility": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "dqu5AGtk/MH73osSK6on14X3a1TfBolKDnPMXM5EC6vo1XtpDL70MFoomypwgwkxz5B29p2+gtVoGqiQz5cicQ==", + "resolved": "7.4.7", + "contentHash": "5Z+R9su13qjgdRe94QF+mdc7n9IZGJxUfSw+wQU3FX77+lewBhAudne4gALJ2x7reM2Mq1lQM2Sg4AkVoCesmg==", "dependencies": { + "Json.More.Net": "2.0.2", + "JsonPointer.Net": "5.0.2", "JsonSchema.Net": "7.0.4", "Markdig.Signed": "0.33.0", "Microsoft.CodeAnalysis.CSharp": "4.9.2", "Microsoft.PowerShell.MarkdownRender": "7.2.1", - "System.Drawing.Common": "9.0.0-preview.6.24327.6", - "System.Management.Automation": "7.4.6", - "System.Threading.AccessControl": "9.0.0-preview.6.24327.7" + "System.Drawing.Common": "8.0.12", + "System.Management.Automation": "7.4.7", + "System.Threading.AccessControl": "8.0.0" } }, "Microsoft.PowerShell.ConsoleHost": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "LOMd4Zl4rsf3gHHwDf0L8iFdvLgHBACMQlgS3viz0L49N2o+0v5TAJSLOpjg77lcuH43rKLfjN+aoEen78iUBQ==", + "resolved": "7.4.7", + "contentHash": "6RjWr4N9xq5vK20UgKM5qUb32FPS3sX+I6cRdL+jZIkjaN75K2tBXlcYbVJQpM5ZNmsKD1rgRyZdkJv27ncEqA==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.PowerShell.CoreCLR.Eventing": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "z8XYESoGwJYT/L60192dE+n1dS7HRvbh2VinadhD3/zA6fDC/lu0VhQc42c56K4JiIMsLfHUUtaPJEa1JPaNBg==", + "resolved": "7.4.7", + "contentHash": "/Tlx5AqodsTCwxqEO0/K137DPrHwfnzQ7WYductm9B+JFbGIf7fxJ/yy0/yvlQrLTXLmnJU97ybOnjT4v1g2CA==", "dependencies": { "System.Diagnostics.EventLog": "8.0.1" } @@ -1751,22 +1756,23 @@ }, "Microsoft.PowerShell.SDK": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "fQb9dKdx+fD5vbJ5wjFngeJ1qSkJ91M3jy6bomVsrs1tLNnB06/8pm42Cv+6xhUVQGKV0JKMFy44+QjHl5puqQ==", + "resolved": "7.4.7", + "contentHash": "VdQT7kvYyuTCgmlSu3s3Tj2mCbKlrFHleTRLKrwFaPlgw0RUmluFjKfCHFx8BzfKVUlXZJBPkjuGSkLFZb58MA==", "dependencies": { "Microsoft.Bcl.AsyncInterfaces": "8.0.0", - "Microsoft.Extensions.ObjectPool": "8.0.10", - "Microsoft.Management.Infrastructure.CimCmdlets": "7.4.6", - "Microsoft.PowerShell.Commands.Diagnostics": "7.4.6", - "Microsoft.PowerShell.Commands.Management": "7.4.6", - "Microsoft.PowerShell.Commands.Utility": "7.4.6", - "Microsoft.PowerShell.ConsoleHost": "7.4.6", - "Microsoft.PowerShell.Security": "7.4.6", - "Microsoft.WSMan.Management": "7.4.6", - "Microsoft.Windows.Compatibility": "8.0.10", + "Microsoft.Extensions.ObjectPool": "8.0.12", + "Microsoft.Management.Infrastructure.CimCmdlets": "7.4.7", + "Microsoft.PowerShell.Commands.Diagnostics": "7.4.7", + "Microsoft.PowerShell.Commands.Management": "7.4.7", + "Microsoft.PowerShell.Commands.Utility": "7.4.7", + "Microsoft.PowerShell.ConsoleHost": "7.4.7", + "Microsoft.PowerShell.Security": "7.4.7", + "Microsoft.WSMan.Management": "7.4.7", + "Microsoft.Windows.Compatibility": "8.0.12", "System.Data.SqlClient": "4.8.6", + "System.Drawing.Common": "8.0.12", "System.IO.Packaging": "8.0.1", - "System.Management.Automation": "7.4.6", + "System.Management.Automation": "7.4.7", "System.Net.Http.WinHttpHandler": "8.0.2", "System.Private.ServiceModel": "4.10.3", "System.Runtime.Caching": "8.0.1", @@ -1781,16 +1787,16 @@ }, "Microsoft.PowerShell.Security": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "62WzHhtzItjTMbEV88J5zL65/1HIZspEoWGwFAAi9ajoUzJOZUtdGyBQPa7ZsxszPk/Ktk+h3QtW0hwBVdrrPg==", + "resolved": "7.4.7", + "contentHash": "dxAFqGRdYGbkAM53FYIxf7tGmZSLxmYR/t5GAQqK1lO22ymHIXm+TC5IlYBzO+X3AmSevV8zRlEbS34AQtnOtw==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.Security.Extensions": { "type": "Transitive", - "resolved": "1.2.0", - "contentHash": "GjHZBE5PHKrxPRyGujWQKwbKNjPQYds6HcAWKeV49X3KPgBfF2B1vV5uJey5UluyGQlvAO/DezL7WzEx9HlPQA==" + "resolved": "1.3.0", + "contentHash": "xK8WFEo5WMUE8DI8W+GjhRwpVcPrxc4DyTjfxh39+yOyhAtC5TBHDlFEJks5toNZHsUeUuiWELIX25oTWOKPBw==" }, "Microsoft.Win32.Primitives": { "type": "Transitive", @@ -1819,23 +1825,23 @@ }, "Microsoft.Win32.SystemEvents": { "type": "Transitive", - "resolved": "9.0.0-preview.6.24327.7", - "contentHash": "iY1g4tiJLFzV+Ygp+g78w8sNMkDLiEY9nYnZVhVto+lAt6UVzw5ZqwRvLGDPzyrV9J1D/MKchmnziLkL8Ro6hA==" + "resolved": "8.0.0", + "contentHash": "9opKRyOKMCi2xJ7Bj7kxtZ1r9vbzosMvRrdEhVhDz8j8MoBGgB+WmC94yH839NPH+BclAjtQ/pyagvi/8gDLkw==" }, "Microsoft.WSMan.Management": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "bBEx8+wstdxpsXjqkOPvVq53PwCksDWb7VtyzXjzLdMGY33gPo8H8P3OACUluOcMG/Kd7rPnBszsP7CFhSkKSg==", + "resolved": "7.4.7", + "contentHash": "l4YJP8FvjKyEe4ETQG5tpXsor1Xb49RPaADCwk//Pp9tGJeDjcptui8mIUbpHGK7LDCZpQoYLucgQ4/Wue5R8g==", "dependencies": { - "Microsoft.WSMan.Runtime": "7.4.6", - "System.Management.Automation": "7.4.6", + "Microsoft.WSMan.Runtime": "7.4.7", + "System.Management.Automation": "7.4.7", "System.ServiceProcess.ServiceController": "8.0.1" } }, "Microsoft.WSMan.Runtime": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "pnNVcVUT+CP7r23Ju/+nhp0fLSdwevAZwe3qe8XQEahYOUv9ACIP29GijRsjdOwIL8+7DaLUQF5jjh+P/ZjGTQ==" + "resolved": "7.4.7", + "contentHash": "fpSryf4e/80fo5oeVfrXkpoESQnk3cA1rE9LaTS+qLWQl+TSxCVf5HZp8YPncAWSrFTuxqx3XET8+WGG5+lgWw==" }, "runtime.any.System.Collections": { "type": "Transitive", @@ -2269,14 +2275,14 @@ }, "System.Management.Automation": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "RxrDUOJuLC7Sd2RaUHf52ujP5VpdfSVTv75nwgEVAROCfYV4IcSd5mL4mLrKa+6LjkXGli7aUs853UyCwidl1A==", + "resolved": "7.4.7", + "contentHash": "6lWtGdSDaM8Nby/Bbiqw8KqnN/fqne/GqdbkGK5obh4Np9LHvgXxCODAaRcKQr6borJ1DPPO4ZwmwX1kLDRGtw==", "dependencies": { "Microsoft.ApplicationInsights": "2.21.0", "Microsoft.Management.Infrastructure": "3.0.0", - "Microsoft.PowerShell.CoreCLR.Eventing": "7.4.6", + "Microsoft.PowerShell.CoreCLR.Eventing": "7.4.7", "Microsoft.PowerShell.Native": "7.4.0", - "Microsoft.Security.Extensions": "1.2.0", + "Microsoft.Security.Extensions": "1.3.0", "Microsoft.Win32.Registry.AccessControl": "8.0.0", "Newtonsoft.Json": "13.0.3", "System.Configuration.ConfigurationManager": "8.0.1", @@ -2643,8 +2649,8 @@ }, "System.Threading.AccessControl": { "type": "Transitive", - "resolved": "9.0.0-preview.6.24327.7", - "contentHash": "t7e5cLBMvBx9/YhNsCp8W8iUw7geh08y0GKFawfJUD5YLgx6AjO2D497+0qHbXRQGpl2uxBGmkWKnCZ5azILZQ==" + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==" }, "System.Threading.Tasks": { "type": "Transitive", @@ -2666,10 +2672,10 @@ "net8.0/linux-x64": { "Microsoft.Management.Infrastructure.CimCmdlets": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "pWlnAxpOLZf5lTX0SPX68dukSFowbEiGd39jRcO5rhsXDG5TjWrF3x1KxlFtMbiMGqJewVn5MJ7FlOWZDD7E3g==", + "resolved": "7.4.7", + "contentHash": "Gi9LGD3hj7j0eEYQnSF7mtYCe7mX+CK5Tb8l9JNHP44YyrKLh4gId4GxKaj+Vz0BMMzzpllJE9dHgeXu1rt2Sw==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.Management.Infrastructure.Runtime.Unix": { @@ -2684,47 +2690,49 @@ }, "Microsoft.PowerShell.Commands.Diagnostics": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "beys8wUfsWNda8JVr/Oj/Erx4PeC/AQC3X/TaU/O/BKKjzO1evm+Moz7wOOHb7bK3mqfGIWjsbOC9U/aRZGpGA==", + "resolved": "7.4.7", + "contentHash": "iSUdSG62b4wl4m5U5/O/RLBzF0GPgdpGIiE8if0VvwitqsRBtO0KKTF10rkz5Br5tFTkpo1ir1XM1VtfUdTQ9w==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.PowerShell.Commands.Management": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "IqM/FMnJMWpausi+ONG/eD2w7phwHG6SgKtLOG7anmlCiFOefjnQX2Jf3ihm7TYQJIFbxg05LtoIviyICJ8Wrw==", + "resolved": "7.4.7", + "contentHash": "3tJyPRLs+2hICQrD3R38dHypsUfsOisuhox52U9vyiqy0gnHfUhO3tYf/az7mZpLHsW1M4JHufegKzmMRQQTsw==", "dependencies": { - "Microsoft.PowerShell.Security": "7.4.6", + "Microsoft.PowerShell.Security": "7.4.7", "System.ServiceProcess.ServiceController": "8.0.1" } }, "Microsoft.PowerShell.Commands.Utility": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "dqu5AGtk/MH73osSK6on14X3a1TfBolKDnPMXM5EC6vo1XtpDL70MFoomypwgwkxz5B29p2+gtVoGqiQz5cicQ==", + "resolved": "7.4.7", + "contentHash": "5Z+R9su13qjgdRe94QF+mdc7n9IZGJxUfSw+wQU3FX77+lewBhAudne4gALJ2x7reM2Mq1lQM2Sg4AkVoCesmg==", "dependencies": { + "Json.More.Net": "2.0.2", + "JsonPointer.Net": "5.0.2", "JsonSchema.Net": "7.0.4", "Markdig.Signed": "0.33.0", "Microsoft.CodeAnalysis.CSharp": "4.9.2", "Microsoft.PowerShell.MarkdownRender": "7.2.1", - "System.Drawing.Common": "9.0.0-preview.6.24327.6", - "System.Management.Automation": "7.4.6", - "System.Threading.AccessControl": "9.0.0-preview.6.24327.7" + "System.Drawing.Common": "8.0.12", + "System.Management.Automation": "7.4.7", + "System.Threading.AccessControl": "8.0.0" } }, "Microsoft.PowerShell.ConsoleHost": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "LOMd4Zl4rsf3gHHwDf0L8iFdvLgHBACMQlgS3viz0L49N2o+0v5TAJSLOpjg77lcuH43rKLfjN+aoEen78iUBQ==", + "resolved": "7.4.7", + "contentHash": "6RjWr4N9xq5vK20UgKM5qUb32FPS3sX+I6cRdL+jZIkjaN75K2tBXlcYbVJQpM5ZNmsKD1rgRyZdkJv27ncEqA==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.PowerShell.CoreCLR.Eventing": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "z8XYESoGwJYT/L60192dE+n1dS7HRvbh2VinadhD3/zA6fDC/lu0VhQc42c56K4JiIMsLfHUUtaPJEa1JPaNBg==", + "resolved": "7.4.7", + "contentHash": "/Tlx5AqodsTCwxqEO0/K137DPrHwfnzQ7WYductm9B+JFbGIf7fxJ/yy0/yvlQrLTXLmnJU97ybOnjT4v1g2CA==", "dependencies": { "System.Diagnostics.EventLog": "8.0.1" } @@ -2736,22 +2744,23 @@ }, "Microsoft.PowerShell.SDK": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "fQb9dKdx+fD5vbJ5wjFngeJ1qSkJ91M3jy6bomVsrs1tLNnB06/8pm42Cv+6xhUVQGKV0JKMFy44+QjHl5puqQ==", + "resolved": "7.4.7", + "contentHash": "VdQT7kvYyuTCgmlSu3s3Tj2mCbKlrFHleTRLKrwFaPlgw0RUmluFjKfCHFx8BzfKVUlXZJBPkjuGSkLFZb58MA==", "dependencies": { "Microsoft.Bcl.AsyncInterfaces": "8.0.0", - "Microsoft.Extensions.ObjectPool": "8.0.10", - "Microsoft.Management.Infrastructure.CimCmdlets": "7.4.6", - "Microsoft.PowerShell.Commands.Diagnostics": "7.4.6", - "Microsoft.PowerShell.Commands.Management": "7.4.6", - "Microsoft.PowerShell.Commands.Utility": "7.4.6", - "Microsoft.PowerShell.ConsoleHost": "7.4.6", - "Microsoft.PowerShell.Security": "7.4.6", - "Microsoft.WSMan.Management": "7.4.6", - "Microsoft.Windows.Compatibility": "8.0.10", + "Microsoft.Extensions.ObjectPool": "8.0.12", + "Microsoft.Management.Infrastructure.CimCmdlets": "7.4.7", + "Microsoft.PowerShell.Commands.Diagnostics": "7.4.7", + "Microsoft.PowerShell.Commands.Management": "7.4.7", + "Microsoft.PowerShell.Commands.Utility": "7.4.7", + "Microsoft.PowerShell.ConsoleHost": "7.4.7", + "Microsoft.PowerShell.Security": "7.4.7", + "Microsoft.WSMan.Management": "7.4.7", + "Microsoft.Windows.Compatibility": "8.0.12", "System.Data.SqlClient": "4.8.6", + "System.Drawing.Common": "8.0.12", "System.IO.Packaging": "8.0.1", - "System.Management.Automation": "7.4.6", + "System.Management.Automation": "7.4.7", "System.Net.Http.WinHttpHandler": "8.0.2", "System.Private.ServiceModel": "4.10.3", "System.Runtime.Caching": "8.0.1", @@ -2766,16 +2775,16 @@ }, "Microsoft.PowerShell.Security": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "62WzHhtzItjTMbEV88J5zL65/1HIZspEoWGwFAAi9ajoUzJOZUtdGyBQPa7ZsxszPk/Ktk+h3QtW0hwBVdrrPg==", + "resolved": "7.4.7", + "contentHash": "dxAFqGRdYGbkAM53FYIxf7tGmZSLxmYR/t5GAQqK1lO22ymHIXm+TC5IlYBzO+X3AmSevV8zRlEbS34AQtnOtw==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.Security.Extensions": { "type": "Transitive", - "resolved": "1.2.0", - "contentHash": "GjHZBE5PHKrxPRyGujWQKwbKNjPQYds6HcAWKeV49X3KPgBfF2B1vV5uJey5UluyGQlvAO/DezL7WzEx9HlPQA==" + "resolved": "1.3.0", + "contentHash": "xK8WFEo5WMUE8DI8W+GjhRwpVcPrxc4DyTjfxh39+yOyhAtC5TBHDlFEJks5toNZHsUeUuiWELIX25oTWOKPBw==" }, "Microsoft.Win32.Primitives": { "type": "Transitive", @@ -2804,23 +2813,23 @@ }, "Microsoft.Win32.SystemEvents": { "type": "Transitive", - "resolved": "9.0.0-preview.6.24327.7", - "contentHash": "iY1g4tiJLFzV+Ygp+g78w8sNMkDLiEY9nYnZVhVto+lAt6UVzw5ZqwRvLGDPzyrV9J1D/MKchmnziLkL8Ro6hA==" + "resolved": "8.0.0", + "contentHash": "9opKRyOKMCi2xJ7Bj7kxtZ1r9vbzosMvRrdEhVhDz8j8MoBGgB+WmC94yH839NPH+BclAjtQ/pyagvi/8gDLkw==" }, "Microsoft.WSMan.Management": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "bBEx8+wstdxpsXjqkOPvVq53PwCksDWb7VtyzXjzLdMGY33gPo8H8P3OACUluOcMG/Kd7rPnBszsP7CFhSkKSg==", + "resolved": "7.4.7", + "contentHash": "l4YJP8FvjKyEe4ETQG5tpXsor1Xb49RPaADCwk//Pp9tGJeDjcptui8mIUbpHGK7LDCZpQoYLucgQ4/Wue5R8g==", "dependencies": { - "Microsoft.WSMan.Runtime": "7.4.6", - "System.Management.Automation": "7.4.6", + "Microsoft.WSMan.Runtime": "7.4.7", + "System.Management.Automation": "7.4.7", "System.ServiceProcess.ServiceController": "8.0.1" } }, "Microsoft.WSMan.Runtime": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "pnNVcVUT+CP7r23Ju/+nhp0fLSdwevAZwe3qe8XQEahYOUv9ACIP29GijRsjdOwIL8+7DaLUQF5jjh+P/ZjGTQ==" + "resolved": "7.4.7", + "contentHash": "fpSryf4e/80fo5oeVfrXkpoESQnk3cA1rE9LaTS+qLWQl+TSxCVf5HZp8YPncAWSrFTuxqx3XET8+WGG5+lgWw==" }, "runtime.any.System.Collections": { "type": "Transitive", @@ -3254,14 +3263,14 @@ }, "System.Management.Automation": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "RxrDUOJuLC7Sd2RaUHf52ujP5VpdfSVTv75nwgEVAROCfYV4IcSd5mL4mLrKa+6LjkXGli7aUs853UyCwidl1A==", + "resolved": "7.4.7", + "contentHash": "6lWtGdSDaM8Nby/Bbiqw8KqnN/fqne/GqdbkGK5obh4Np9LHvgXxCODAaRcKQr6borJ1DPPO4ZwmwX1kLDRGtw==", "dependencies": { "Microsoft.ApplicationInsights": "2.21.0", "Microsoft.Management.Infrastructure": "3.0.0", - "Microsoft.PowerShell.CoreCLR.Eventing": "7.4.6", + "Microsoft.PowerShell.CoreCLR.Eventing": "7.4.7", "Microsoft.PowerShell.Native": "7.4.0", - "Microsoft.Security.Extensions": "1.2.0", + "Microsoft.Security.Extensions": "1.3.0", "Microsoft.Win32.Registry.AccessControl": "8.0.0", "Newtonsoft.Json": "13.0.3", "System.Configuration.ConfigurationManager": "8.0.1", @@ -3628,8 +3637,8 @@ }, "System.Threading.AccessControl": { "type": "Transitive", - "resolved": "9.0.0-preview.6.24327.7", - "contentHash": "t7e5cLBMvBx9/YhNsCp8W8iUw7geh08y0GKFawfJUD5YLgx6AjO2D497+0qHbXRQGpl2uxBGmkWKnCZ5azILZQ==" + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==" }, "System.Threading.Tasks": { "type": "Transitive", @@ -3651,10 +3660,10 @@ "net8.0/osx-x64": { "Microsoft.Management.Infrastructure.CimCmdlets": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "pWlnAxpOLZf5lTX0SPX68dukSFowbEiGd39jRcO5rhsXDG5TjWrF3x1KxlFtMbiMGqJewVn5MJ7FlOWZDD7E3g==", + "resolved": "7.4.7", + "contentHash": "Gi9LGD3hj7j0eEYQnSF7mtYCe7mX+CK5Tb8l9JNHP44YyrKLh4gId4GxKaj+Vz0BMMzzpllJE9dHgeXu1rt2Sw==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.Management.Infrastructure.Runtime.Unix": { @@ -3669,47 +3678,49 @@ }, "Microsoft.PowerShell.Commands.Diagnostics": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "beys8wUfsWNda8JVr/Oj/Erx4PeC/AQC3X/TaU/O/BKKjzO1evm+Moz7wOOHb7bK3mqfGIWjsbOC9U/aRZGpGA==", + "resolved": "7.4.7", + "contentHash": "iSUdSG62b4wl4m5U5/O/RLBzF0GPgdpGIiE8if0VvwitqsRBtO0KKTF10rkz5Br5tFTkpo1ir1XM1VtfUdTQ9w==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.PowerShell.Commands.Management": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "IqM/FMnJMWpausi+ONG/eD2w7phwHG6SgKtLOG7anmlCiFOefjnQX2Jf3ihm7TYQJIFbxg05LtoIviyICJ8Wrw==", + "resolved": "7.4.7", + "contentHash": "3tJyPRLs+2hICQrD3R38dHypsUfsOisuhox52U9vyiqy0gnHfUhO3tYf/az7mZpLHsW1M4JHufegKzmMRQQTsw==", "dependencies": { - "Microsoft.PowerShell.Security": "7.4.6", + "Microsoft.PowerShell.Security": "7.4.7", "System.ServiceProcess.ServiceController": "8.0.1" } }, "Microsoft.PowerShell.Commands.Utility": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "dqu5AGtk/MH73osSK6on14X3a1TfBolKDnPMXM5EC6vo1XtpDL70MFoomypwgwkxz5B29p2+gtVoGqiQz5cicQ==", + "resolved": "7.4.7", + "contentHash": "5Z+R9su13qjgdRe94QF+mdc7n9IZGJxUfSw+wQU3FX77+lewBhAudne4gALJ2x7reM2Mq1lQM2Sg4AkVoCesmg==", "dependencies": { + "Json.More.Net": "2.0.2", + "JsonPointer.Net": "5.0.2", "JsonSchema.Net": "7.0.4", "Markdig.Signed": "0.33.0", "Microsoft.CodeAnalysis.CSharp": "4.9.2", "Microsoft.PowerShell.MarkdownRender": "7.2.1", - "System.Drawing.Common": "9.0.0-preview.6.24327.6", - "System.Management.Automation": "7.4.6", - "System.Threading.AccessControl": "9.0.0-preview.6.24327.7" + "System.Drawing.Common": "8.0.12", + "System.Management.Automation": "7.4.7", + "System.Threading.AccessControl": "8.0.0" } }, "Microsoft.PowerShell.ConsoleHost": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "LOMd4Zl4rsf3gHHwDf0L8iFdvLgHBACMQlgS3viz0L49N2o+0v5TAJSLOpjg77lcuH43rKLfjN+aoEen78iUBQ==", + "resolved": "7.4.7", + "contentHash": "6RjWr4N9xq5vK20UgKM5qUb32FPS3sX+I6cRdL+jZIkjaN75K2tBXlcYbVJQpM5ZNmsKD1rgRyZdkJv27ncEqA==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.PowerShell.CoreCLR.Eventing": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "z8XYESoGwJYT/L60192dE+n1dS7HRvbh2VinadhD3/zA6fDC/lu0VhQc42c56K4JiIMsLfHUUtaPJEa1JPaNBg==", + "resolved": "7.4.7", + "contentHash": "/Tlx5AqodsTCwxqEO0/K137DPrHwfnzQ7WYductm9B+JFbGIf7fxJ/yy0/yvlQrLTXLmnJU97ybOnjT4v1g2CA==", "dependencies": { "System.Diagnostics.EventLog": "8.0.1" } @@ -3721,22 +3732,23 @@ }, "Microsoft.PowerShell.SDK": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "fQb9dKdx+fD5vbJ5wjFngeJ1qSkJ91M3jy6bomVsrs1tLNnB06/8pm42Cv+6xhUVQGKV0JKMFy44+QjHl5puqQ==", + "resolved": "7.4.7", + "contentHash": "VdQT7kvYyuTCgmlSu3s3Tj2mCbKlrFHleTRLKrwFaPlgw0RUmluFjKfCHFx8BzfKVUlXZJBPkjuGSkLFZb58MA==", "dependencies": { "Microsoft.Bcl.AsyncInterfaces": "8.0.0", - "Microsoft.Extensions.ObjectPool": "8.0.10", - "Microsoft.Management.Infrastructure.CimCmdlets": "7.4.6", - "Microsoft.PowerShell.Commands.Diagnostics": "7.4.6", - "Microsoft.PowerShell.Commands.Management": "7.4.6", - "Microsoft.PowerShell.Commands.Utility": "7.4.6", - "Microsoft.PowerShell.ConsoleHost": "7.4.6", - "Microsoft.PowerShell.Security": "7.4.6", - "Microsoft.WSMan.Management": "7.4.6", - "Microsoft.Windows.Compatibility": "8.0.10", + "Microsoft.Extensions.ObjectPool": "8.0.12", + "Microsoft.Management.Infrastructure.CimCmdlets": "7.4.7", + "Microsoft.PowerShell.Commands.Diagnostics": "7.4.7", + "Microsoft.PowerShell.Commands.Management": "7.4.7", + "Microsoft.PowerShell.Commands.Utility": "7.4.7", + "Microsoft.PowerShell.ConsoleHost": "7.4.7", + "Microsoft.PowerShell.Security": "7.4.7", + "Microsoft.WSMan.Management": "7.4.7", + "Microsoft.Windows.Compatibility": "8.0.12", "System.Data.SqlClient": "4.8.6", + "System.Drawing.Common": "8.0.12", "System.IO.Packaging": "8.0.1", - "System.Management.Automation": "7.4.6", + "System.Management.Automation": "7.4.7", "System.Net.Http.WinHttpHandler": "8.0.2", "System.Private.ServiceModel": "4.10.3", "System.Runtime.Caching": "8.0.1", @@ -3751,16 +3763,16 @@ }, "Microsoft.PowerShell.Security": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "62WzHhtzItjTMbEV88J5zL65/1HIZspEoWGwFAAi9ajoUzJOZUtdGyBQPa7ZsxszPk/Ktk+h3QtW0hwBVdrrPg==", + "resolved": "7.4.7", + "contentHash": "dxAFqGRdYGbkAM53FYIxf7tGmZSLxmYR/t5GAQqK1lO22ymHIXm+TC5IlYBzO+X3AmSevV8zRlEbS34AQtnOtw==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.Security.Extensions": { "type": "Transitive", - "resolved": "1.2.0", - "contentHash": "GjHZBE5PHKrxPRyGujWQKwbKNjPQYds6HcAWKeV49X3KPgBfF2B1vV5uJey5UluyGQlvAO/DezL7WzEx9HlPQA==" + "resolved": "1.3.0", + "contentHash": "xK8WFEo5WMUE8DI8W+GjhRwpVcPrxc4DyTjfxh39+yOyhAtC5TBHDlFEJks5toNZHsUeUuiWELIX25oTWOKPBw==" }, "Microsoft.Win32.Primitives": { "type": "Transitive", @@ -3789,23 +3801,23 @@ }, "Microsoft.Win32.SystemEvents": { "type": "Transitive", - "resolved": "9.0.0-preview.6.24327.7", - "contentHash": "iY1g4tiJLFzV+Ygp+g78w8sNMkDLiEY9nYnZVhVto+lAt6UVzw5ZqwRvLGDPzyrV9J1D/MKchmnziLkL8Ro6hA==" + "resolved": "8.0.0", + "contentHash": "9opKRyOKMCi2xJ7Bj7kxtZ1r9vbzosMvRrdEhVhDz8j8MoBGgB+WmC94yH839NPH+BclAjtQ/pyagvi/8gDLkw==" }, "Microsoft.WSMan.Management": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "bBEx8+wstdxpsXjqkOPvVq53PwCksDWb7VtyzXjzLdMGY33gPo8H8P3OACUluOcMG/Kd7rPnBszsP7CFhSkKSg==", + "resolved": "7.4.7", + "contentHash": "l4YJP8FvjKyEe4ETQG5tpXsor1Xb49RPaADCwk//Pp9tGJeDjcptui8mIUbpHGK7LDCZpQoYLucgQ4/Wue5R8g==", "dependencies": { - "Microsoft.WSMan.Runtime": "7.4.6", - "System.Management.Automation": "7.4.6", + "Microsoft.WSMan.Runtime": "7.4.7", + "System.Management.Automation": "7.4.7", "System.ServiceProcess.ServiceController": "8.0.1" } }, "Microsoft.WSMan.Runtime": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "pnNVcVUT+CP7r23Ju/+nhp0fLSdwevAZwe3qe8XQEahYOUv9ACIP29GijRsjdOwIL8+7DaLUQF5jjh+P/ZjGTQ==" + "resolved": "7.4.7", + "contentHash": "fpSryf4e/80fo5oeVfrXkpoESQnk3cA1rE9LaTS+qLWQl+TSxCVf5HZp8YPncAWSrFTuxqx3XET8+WGG5+lgWw==" }, "runtime.any.System.Collections": { "type": "Transitive", @@ -4239,14 +4251,14 @@ }, "System.Management.Automation": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "RxrDUOJuLC7Sd2RaUHf52ujP5VpdfSVTv75nwgEVAROCfYV4IcSd5mL4mLrKa+6LjkXGli7aUs853UyCwidl1A==", + "resolved": "7.4.7", + "contentHash": "6lWtGdSDaM8Nby/Bbiqw8KqnN/fqne/GqdbkGK5obh4Np9LHvgXxCODAaRcKQr6borJ1DPPO4ZwmwX1kLDRGtw==", "dependencies": { "Microsoft.ApplicationInsights": "2.21.0", "Microsoft.Management.Infrastructure": "3.0.0", - "Microsoft.PowerShell.CoreCLR.Eventing": "7.4.6", + "Microsoft.PowerShell.CoreCLR.Eventing": "7.4.7", "Microsoft.PowerShell.Native": "7.4.0", - "Microsoft.Security.Extensions": "1.2.0", + "Microsoft.Security.Extensions": "1.3.0", "Microsoft.Win32.Registry.AccessControl": "8.0.0", "Newtonsoft.Json": "13.0.3", "System.Configuration.ConfigurationManager": "8.0.1", @@ -4613,8 +4625,8 @@ }, "System.Threading.AccessControl": { "type": "Transitive", - "resolved": "9.0.0-preview.6.24327.7", - "contentHash": "t7e5cLBMvBx9/YhNsCp8W8iUw7geh08y0GKFawfJUD5YLgx6AjO2D497+0qHbXRQGpl2uxBGmkWKnCZ5azILZQ==" + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==" }, "System.Threading.Tasks": { "type": "Transitive", @@ -4636,10 +4648,10 @@ "net8.0/win-x64": { "Microsoft.Management.Infrastructure.CimCmdlets": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "pWlnAxpOLZf5lTX0SPX68dukSFowbEiGd39jRcO5rhsXDG5TjWrF3x1KxlFtMbiMGqJewVn5MJ7FlOWZDD7E3g==", + "resolved": "7.4.7", + "contentHash": "Gi9LGD3hj7j0eEYQnSF7mtYCe7mX+CK5Tb8l9JNHP44YyrKLh4gId4GxKaj+Vz0BMMzzpllJE9dHgeXu1rt2Sw==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.Management.Infrastructure.Runtime.Unix": { @@ -4654,47 +4666,49 @@ }, "Microsoft.PowerShell.Commands.Diagnostics": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "beys8wUfsWNda8JVr/Oj/Erx4PeC/AQC3X/TaU/O/BKKjzO1evm+Moz7wOOHb7bK3mqfGIWjsbOC9U/aRZGpGA==", + "resolved": "7.4.7", + "contentHash": "iSUdSG62b4wl4m5U5/O/RLBzF0GPgdpGIiE8if0VvwitqsRBtO0KKTF10rkz5Br5tFTkpo1ir1XM1VtfUdTQ9w==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.PowerShell.Commands.Management": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "IqM/FMnJMWpausi+ONG/eD2w7phwHG6SgKtLOG7anmlCiFOefjnQX2Jf3ihm7TYQJIFbxg05LtoIviyICJ8Wrw==", + "resolved": "7.4.7", + "contentHash": "3tJyPRLs+2hICQrD3R38dHypsUfsOisuhox52U9vyiqy0gnHfUhO3tYf/az7mZpLHsW1M4JHufegKzmMRQQTsw==", "dependencies": { - "Microsoft.PowerShell.Security": "7.4.6", + "Microsoft.PowerShell.Security": "7.4.7", "System.ServiceProcess.ServiceController": "8.0.1" } }, "Microsoft.PowerShell.Commands.Utility": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "dqu5AGtk/MH73osSK6on14X3a1TfBolKDnPMXM5EC6vo1XtpDL70MFoomypwgwkxz5B29p2+gtVoGqiQz5cicQ==", + "resolved": "7.4.7", + "contentHash": "5Z+R9su13qjgdRe94QF+mdc7n9IZGJxUfSw+wQU3FX77+lewBhAudne4gALJ2x7reM2Mq1lQM2Sg4AkVoCesmg==", "dependencies": { + "Json.More.Net": "2.0.2", + "JsonPointer.Net": "5.0.2", "JsonSchema.Net": "7.0.4", "Markdig.Signed": "0.33.0", "Microsoft.CodeAnalysis.CSharp": "4.9.2", "Microsoft.PowerShell.MarkdownRender": "7.2.1", - "System.Drawing.Common": "9.0.0-preview.6.24327.6", - "System.Management.Automation": "7.4.6", - "System.Threading.AccessControl": "9.0.0-preview.6.24327.7" + "System.Drawing.Common": "8.0.12", + "System.Management.Automation": "7.4.7", + "System.Threading.AccessControl": "8.0.0" } }, "Microsoft.PowerShell.ConsoleHost": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "LOMd4Zl4rsf3gHHwDf0L8iFdvLgHBACMQlgS3viz0L49N2o+0v5TAJSLOpjg77lcuH43rKLfjN+aoEen78iUBQ==", + "resolved": "7.4.7", + "contentHash": "6RjWr4N9xq5vK20UgKM5qUb32FPS3sX+I6cRdL+jZIkjaN75K2tBXlcYbVJQpM5ZNmsKD1rgRyZdkJv27ncEqA==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.PowerShell.CoreCLR.Eventing": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "z8XYESoGwJYT/L60192dE+n1dS7HRvbh2VinadhD3/zA6fDC/lu0VhQc42c56K4JiIMsLfHUUtaPJEa1JPaNBg==", + "resolved": "7.4.7", + "contentHash": "/Tlx5AqodsTCwxqEO0/K137DPrHwfnzQ7WYductm9B+JFbGIf7fxJ/yy0/yvlQrLTXLmnJU97ybOnjT4v1g2CA==", "dependencies": { "System.Diagnostics.EventLog": "8.0.1" } @@ -4706,22 +4720,23 @@ }, "Microsoft.PowerShell.SDK": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "fQb9dKdx+fD5vbJ5wjFngeJ1qSkJ91M3jy6bomVsrs1tLNnB06/8pm42Cv+6xhUVQGKV0JKMFy44+QjHl5puqQ==", + "resolved": "7.4.7", + "contentHash": "VdQT7kvYyuTCgmlSu3s3Tj2mCbKlrFHleTRLKrwFaPlgw0RUmluFjKfCHFx8BzfKVUlXZJBPkjuGSkLFZb58MA==", "dependencies": { "Microsoft.Bcl.AsyncInterfaces": "8.0.0", - "Microsoft.Extensions.ObjectPool": "8.0.10", - "Microsoft.Management.Infrastructure.CimCmdlets": "7.4.6", - "Microsoft.PowerShell.Commands.Diagnostics": "7.4.6", - "Microsoft.PowerShell.Commands.Management": "7.4.6", - "Microsoft.PowerShell.Commands.Utility": "7.4.6", - "Microsoft.PowerShell.ConsoleHost": "7.4.6", - "Microsoft.PowerShell.Security": "7.4.6", - "Microsoft.WSMan.Management": "7.4.6", - "Microsoft.Windows.Compatibility": "8.0.10", + "Microsoft.Extensions.ObjectPool": "8.0.12", + "Microsoft.Management.Infrastructure.CimCmdlets": "7.4.7", + "Microsoft.PowerShell.Commands.Diagnostics": "7.4.7", + "Microsoft.PowerShell.Commands.Management": "7.4.7", + "Microsoft.PowerShell.Commands.Utility": "7.4.7", + "Microsoft.PowerShell.ConsoleHost": "7.4.7", + "Microsoft.PowerShell.Security": "7.4.7", + "Microsoft.WSMan.Management": "7.4.7", + "Microsoft.Windows.Compatibility": "8.0.12", "System.Data.SqlClient": "4.8.6", + "System.Drawing.Common": "8.0.12", "System.IO.Packaging": "8.0.1", - "System.Management.Automation": "7.4.6", + "System.Management.Automation": "7.4.7", "System.Net.Http.WinHttpHandler": "8.0.2", "System.Private.ServiceModel": "4.10.3", "System.Runtime.Caching": "8.0.1", @@ -4736,16 +4751,16 @@ }, "Microsoft.PowerShell.Security": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "62WzHhtzItjTMbEV88J5zL65/1HIZspEoWGwFAAi9ajoUzJOZUtdGyBQPa7ZsxszPk/Ktk+h3QtW0hwBVdrrPg==", + "resolved": "7.4.7", + "contentHash": "dxAFqGRdYGbkAM53FYIxf7tGmZSLxmYR/t5GAQqK1lO22ymHIXm+TC5IlYBzO+X3AmSevV8zRlEbS34AQtnOtw==", "dependencies": { - "System.Management.Automation": "7.4.6" + "System.Management.Automation": "7.4.7" } }, "Microsoft.Security.Extensions": { "type": "Transitive", - "resolved": "1.2.0", - "contentHash": "GjHZBE5PHKrxPRyGujWQKwbKNjPQYds6HcAWKeV49X3KPgBfF2B1vV5uJey5UluyGQlvAO/DezL7WzEx9HlPQA==" + "resolved": "1.3.0", + "contentHash": "xK8WFEo5WMUE8DI8W+GjhRwpVcPrxc4DyTjfxh39+yOyhAtC5TBHDlFEJks5toNZHsUeUuiWELIX25oTWOKPBw==" }, "Microsoft.Win32.Primitives": { "type": "Transitive", @@ -4774,23 +4789,23 @@ }, "Microsoft.Win32.SystemEvents": { "type": "Transitive", - "resolved": "9.0.0-preview.6.24327.7", - "contentHash": "iY1g4tiJLFzV+Ygp+g78w8sNMkDLiEY9nYnZVhVto+lAt6UVzw5ZqwRvLGDPzyrV9J1D/MKchmnziLkL8Ro6hA==" + "resolved": "8.0.0", + "contentHash": "9opKRyOKMCi2xJ7Bj7kxtZ1r9vbzosMvRrdEhVhDz8j8MoBGgB+WmC94yH839NPH+BclAjtQ/pyagvi/8gDLkw==" }, "Microsoft.WSMan.Management": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "bBEx8+wstdxpsXjqkOPvVq53PwCksDWb7VtyzXjzLdMGY33gPo8H8P3OACUluOcMG/Kd7rPnBszsP7CFhSkKSg==", + "resolved": "7.4.7", + "contentHash": "l4YJP8FvjKyEe4ETQG5tpXsor1Xb49RPaADCwk//Pp9tGJeDjcptui8mIUbpHGK7LDCZpQoYLucgQ4/Wue5R8g==", "dependencies": { - "Microsoft.WSMan.Runtime": "7.4.6", - "System.Management.Automation": "7.4.6", + "Microsoft.WSMan.Runtime": "7.4.7", + "System.Management.Automation": "7.4.7", "System.ServiceProcess.ServiceController": "8.0.1" } }, "Microsoft.WSMan.Runtime": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "pnNVcVUT+CP7r23Ju/+nhp0fLSdwevAZwe3qe8XQEahYOUv9ACIP29GijRsjdOwIL8+7DaLUQF5jjh+P/ZjGTQ==" + "resolved": "7.4.7", + "contentHash": "fpSryf4e/80fo5oeVfrXkpoESQnk3cA1rE9LaTS+qLWQl+TSxCVf5HZp8YPncAWSrFTuxqx3XET8+WGG5+lgWw==" }, "runtime.any.System.Collections": { "type": "Transitive", @@ -5209,14 +5224,14 @@ }, "System.Management.Automation": { "type": "Transitive", - "resolved": "7.4.6", - "contentHash": "RxrDUOJuLC7Sd2RaUHf52ujP5VpdfSVTv75nwgEVAROCfYV4IcSd5mL4mLrKa+6LjkXGli7aUs853UyCwidl1A==", + "resolved": "7.4.7", + "contentHash": "6lWtGdSDaM8Nby/Bbiqw8KqnN/fqne/GqdbkGK5obh4Np9LHvgXxCODAaRcKQr6borJ1DPPO4ZwmwX1kLDRGtw==", "dependencies": { "Microsoft.ApplicationInsights": "2.21.0", "Microsoft.Management.Infrastructure": "3.0.0", - "Microsoft.PowerShell.CoreCLR.Eventing": "7.4.6", + "Microsoft.PowerShell.CoreCLR.Eventing": "7.4.7", "Microsoft.PowerShell.Native": "7.4.0", - "Microsoft.Security.Extensions": "1.2.0", + "Microsoft.Security.Extensions": "1.3.0", "Microsoft.Win32.Registry.AccessControl": "8.0.0", "Newtonsoft.Json": "13.0.3", "System.Configuration.ConfigurationManager": "8.0.1", @@ -5582,8 +5597,8 @@ }, "System.Threading.AccessControl": { "type": "Transitive", - "resolved": "9.0.0-preview.6.24327.7", - "contentHash": "t7e5cLBMvBx9/YhNsCp8W8iUw7geh08y0GKFawfJUD5YLgx6AjO2D497+0qHbXRQGpl2uxBGmkWKnCZ5azILZQ==" + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==" }, "System.Threading.Overlapped": { "type": "Transitive", diff --git a/src/PSRule.Types/Runtime/LoggerExtensions.cs b/src/PSRule.Types/Runtime/LoggerExtensions.cs index d35ad00e02..a161b688ac 100644 --- a/src/PSRule.Types/Runtime/LoggerExtensions.cs +++ b/src/PSRule.Types/Runtime/LoggerExtensions.cs @@ -10,6 +10,18 @@ public static class LoggerExtensions { private static readonly Func _messageFormatter = MessageFormatter; + /// + /// Log an information level message. + /// + /// A valid instance. + /// An event identifier for the warning. + /// The format message text. + /// Additional arguments to use within the format message. + public static void LogInformation(this ILogger logger, EventId eventId, string? message, params object?[] args) + { + logger.Log(LogLevel.Information, eventId, default, message, args); + } + /// /// Log a warning message. /// diff --git a/src/vscode-ps-rule/README.md b/src/vscode-ps-rule/README.md index 5421b9d1f1..88573c68ab 100644 --- a/src/vscode-ps-rule/README.md +++ b/src/vscode-ps-rule/README.md @@ -67,7 +67,8 @@ In addition to configuring the [ps-rule.yaml] options file, the following settin Name | Description ---- | ----------- -`PSRule.codeLens.ruleDocumentationLinks` | Enables Code Lens that displays links to rule documentation. This is an experimental feature that requires experimental features to be enabled. +`PSRule.codeLens.dependencyManagement` | Enables Code Lens that displays links to manage dependencies. +`PSRule.codeLens.ruleDocumentationLinks` | Enables Code Lens that displays links to rule documentation. `PSRule.documentation.path` | The path to look for rule documentation. When not set, the path containing rules will be used. `PSRule.documentation.localePath` | The locale path to use for locating rule documentation. The VS Code locale will be used by default. `PSRule.documentation.customSnippetPath` | The path to a file containing a rule documentation snippet. When not set, built-in PSRule snippets will be used. @@ -83,5 +84,6 @@ Name | Description `PSRule.options.path` | The path specifying a PSRule option file. When not set, the default `ps-rule.yaml` will be used from the current workspace. `PSRule.output.as` | Configures the output of analysis tasks, either summary or detailed. `PSRule.rule.baseline` | The name of the default baseline to use for executing rules. This setting can be overridden on individual PSRule tasks. +`PSRule.trace.task` | Determines the level of trace information to output for PSRule tasks. [ps-rule.yaml]: https://aka.ms/ps-rule/options diff --git a/src/vscode-ps-rule/client.ts b/src/vscode-ps-rule/client.ts index 8f9eeba671..ae6fa4efc3 100644 --- a/src/vscode-ps-rule/client.ts +++ b/src/vscode-ps-rule/client.ts @@ -9,8 +9,6 @@ import { logger } from './logger'; import { ext } from './extension'; import { getActiveOrFirstWorkspace } from './utils'; -// export const GetVersionRequestType = new lsp.RequestType('ps-rule/getVersion'); - export const StartProgressNotificationType = new lsp.ProgressType(); /** @@ -55,7 +53,7 @@ export class PSRuleClient implements vscode.Disposable { }); client.onProgress(StartProgressNotificationType, 'server/ready', (arg1) => { - logger.verbose(`Connected to client v${arg1}.`); + logger.verbose(`Language server ready and connected: v${arg1}.`); }); // Start the server and return the client. @@ -88,6 +86,7 @@ export class PSRuleClient implements vscode.Disposable { fileEvents: [ vscode.workspace.createFileSystemWatcher('**/'), // folder changes vscode.workspace.createFileSystemWatcher('**/*.Rule.yaml'), // Rule file changes + vscode.workspace.createFileSystemWatcher('**/ps-rule.lock.json'), // Lock file changes ], }, }; diff --git a/src/vscode-ps-rule/commands/upgradeDependency.ts b/src/vscode-ps-rule/commands/upgradeDependency.ts new file mode 100644 index 0000000000..b0873c8280 --- /dev/null +++ b/src/vscode-ps-rule/commands/upgradeDependency.ts @@ -0,0 +1,100 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import * as fse from 'fs-extra'; +import { ProgressLocation, Uri, window } from 'vscode'; +import { logger } from '../logger'; +import { ext } from '../extension'; +import { ExecuteCommandRequest } from 'vscode-languageclient'; +import { getActiveOrFirstWorkspace } from '../utils'; + +/** + * Upgrades a PSRule dependency. + * @param path The path to the options file. + * @returns A promise for the task. + */ +export async function upgradeDependency(path: string | undefined, name: string | undefined): Promise { + let workspaceUri: Uri | undefined = getActiveOrFirstWorkspace()?.uri; + if (workspaceUri !== undefined && path === undefined) { + path = Uri.joinPath(workspaceUri, '/ps-rule.lock.json').fsPath; + } + + if (path !== '' && path !== undefined) { + const exists = await fse.pathExists(path); + if (!exists) { + path = undefined; + return; + } + + // Try to get possible modules from the lock file. + if (name === '' || name === undefined) { + const lockFile = await fse.readJson(path, { encoding: 'utf-8' }); + if (lockFile !== undefined && lockFile.modules !== undefined) { + const modules = Object.keys(lockFile.modules); + + if (modules == undefined || modules.length === 0) { + return; + } + + // Get quick pick items. + let items = modules.map((module) => { + return { + label: module, + kind: 0, + }; + }); + + items.push({ + label: '', + kind: -1, + }); + + items.push({ + label: 'Upgrade all modules', + kind: 0, + }); + + // Prompt user to select a module. + const selectedModule = await window.showQuickPick(items, { + placeHolder: 'Select a module to upgrade', + }); + + if (selectedModule !== undefined) { + name = selectedModule.label === 'Upgrade all modules' ? '*' : selectedModule.label; + } + } + } + } + + // Ignore if no path or name is provided. + if (path === '' || path === undefined || name === '' || name === undefined) return; + + let uri = Uri.file(path); + if (uri) { + + await window.withProgress({ + location: ProgressLocation.Window, + title: 'PSRule', + cancellable: false, + }, async (progress) => { + + progress.report({ message: 'Upgrading dependencies' }); + + const result = await ext.client.sendRequest(ExecuteCommandRequest.type, { + command: 'upgradeDependency', + arguments: [ + { + path: uri.fsPath, + module: name + } + ] + }); + + if (result !== undefined) { + logger.verbose(`Upgraded dependency completed.`); + } + + progress.report({ message: 'Completed upgrade', increment: 100 }); + }); + } +} diff --git a/src/vscode-ps-rule/configuration.ts b/src/vscode-ps-rule/configuration.ts index b8f77cbc63..c0571603b7 100644 --- a/src/vscode-ps-rule/configuration.ts +++ b/src/vscode-ps-rule/configuration.ts @@ -52,7 +52,16 @@ export enum TraceLevelPreference { * PSRule extension settings. */ export interface ISetting { + /** + * Determines if code lens rule documentation links are enabled. + */ codeLensRuleDocumentationLinks: boolean; + + /** + * Determines if code lens for dependency management are enabled. + */ + codeLensDependencyManagement: boolean; + documentationCustomSnippetPath: string | undefined; documentationSnippet: string; documentationPath: string | undefined; @@ -130,6 +139,7 @@ export interface ISetting { */ const globalDefaults: ISetting = { codeLensRuleDocumentationLinks: true, + codeLensDependencyManagement: true, documentationCustomSnippetPath: undefined, documentationSnippet: 'Rule Doc', documentationPath: undefined, @@ -222,6 +232,11 @@ export class ConfigurationManager { this.default.codeLensRuleDocumentationLinks ); + this.current.codeLensDependencyManagement = config.get( + 'codeLens.dependencyManagement', + this.default.codeLensDependencyManagement + ); + this.current.executionRuleExcluded = config.get('execution.ruleExcluded', this.default.executionRuleExcluded); this.current.executionRuleSuppressed = config.get('execution.ruleSuppressed', this.default.executionRuleSuppressed); this.current.executionUnprocessedObject = config.get('execution.unprocessedObject', this.default.executionUnprocessedObject); diff --git a/src/vscode-ps-rule/dependencyLens.ts b/src/vscode-ps-rule/dependencyLens.ts new file mode 100644 index 0000000000..860df86d29 --- /dev/null +++ b/src/vscode-ps-rule/dependencyLens.ts @@ -0,0 +1,152 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +'use strict'; + +import * as fse from 'fs-extra'; +import { + CancellationToken, + CodeLens, + CodeLensProvider, + Disposable, + Event, + EventEmitter, + ExtensionContext, + Position, + Range, + TextDocument, + languages, + workspace, +} from 'vscode'; +import { DocumentSelector } from 'vscode-languageclient'; +import { configuration } from './configuration'; +import { ILogger } from './logger'; + +interface IContext { + readonly logger: ILogger; + readonly extensionContext: ExtensionContext; +} + +/** + * Provides code lenses for upgrading dependencies in a PSRule lock file. + */ +export class DependencyLensProvider implements CodeLensProvider, Disposable { + // Fields + private readonly context: IContext; + + private codeLenses: CodeLens[] = []; + private regexModuleBlock: RegExp; + private regexModuleName: RegExp; + private _registration: Disposable | undefined; + private _onDidChangeCodeLenses: EventEmitter = new EventEmitter(); + public readonly onDidChangeCodeLenses: Event = this._onDidChangeCodeLenses.event; + + constructor(logger: ILogger, extensionContext: ExtensionContext) { + this.context = { logger, extensionContext }; + this.regexModuleBlock = /"modules":\s*\{([^{}]*\{[^{}]*\}[^{}]*)*\}/g; + this.regexModuleName = + /(?[^"]+)":\s*{\s*"version":\s*"[^"]*"/g; + + workspace.onDidChangeConfiguration((_) => { + this._onDidChangeCodeLenses.fire(); + }); + } + + dispose() { + this._registration?.dispose(); + } + + public register(): void { + let filter: DocumentSelector = [ + { language: 'json', pattern: '**/ps-rule.lock.json' }, + ]; + this._registration = languages.registerCodeLensProvider(filter, this); + } + + public async provideCodeLenses( + document: TextDocument, + token: CancellationToken + ): Promise { + if (configuration.get().codeLensDependencyManagement) { + this.codeLenses = []; + + const text = document.getText(); + + // Add top of document. + let topOfDocument = new Range(0, 0, 0, 0); + this.codeLenses.push(await this.createUpgradeAllCodeLens(topOfDocument, document.uri.fsPath)); + + // Get the text range of the module block. + let outerMatches; + let outerRange: Range | undefined = undefined; + while ((outerMatches = this.regexModuleBlock.exec(text)) !== null) { + const startPos = document.positionAt(outerMatches.index); + const endPos = document.positionAt(outerMatches.index + outerMatches[0].length); + outerRange = new Range(startPos, endPos); + } + + // Add links for each module. + if (outerRange) { + + let matches; + while ((matches = this.regexModuleName.exec(text)) !== null) { + let name = matches.groups !== undefined ? matches.groups['name'].replace(/\'/g, '') : ''; + + const line = document.lineAt(document.positionAt(matches.index).line); + const indexOf = line.text.indexOf(matches[1]); + const position = new Position(line.lineNumber, indexOf); + const range = document.getWordRangeAtPosition(position); + if (range && name && outerRange.contains(range)) { + this.codeLenses.push(await this.createUpgradeModuleCodeLens(range, document.uri.fsPath, name)); + } + } + } + return this.codeLenses; + } + return []; + } + + /** + * Create a code lens for upgrading a specific dependency. + * @param range The range in the document the code lens applies to. + * @param path The file path to lock file. + * @param name The name of the module. + * @returns A code lens object. + */ + private async createUpgradeModuleCodeLens(range: Range, path: string, name: string): Promise { + let title = 'Upgrade dependency'; + let tooltip = 'Upgrade the selected module.'; + + return new CodeLens(range, { + title: title, + tooltip: tooltip, + command: 'PSRule.upgradeDependency', + arguments: [path, name], + }); + } + + /** + * Create a code lens for upgrading all dependencies. + * @param range The range in the document the code lens applies to. + * @param path The file path to lock file. + * @returns A code lens object. + */ + private async createUpgradeAllCodeLens(range: Range, path: string): Promise { + let title = 'Upgrade all dependencies'; + let tooltip = 'Upgrade all modules.'; + + return new CodeLens(range, { + title: title, + tooltip: tooltip, + command: 'PSRule.upgradeDependency', + arguments: [path, '*'], + }); + } + + public async resolveCodeLens( + codeLens: CodeLens, + token: CancellationToken + ): Promise { + return undefined; + } +} diff --git a/src/vscode-ps-rule/docLens.ts b/src/vscode-ps-rule/docLens.ts index 37fe376482..c88c78e212 100644 --- a/src/vscode-ps-rule/docLens.ts +++ b/src/vscode-ps-rule/docLens.ts @@ -30,6 +30,9 @@ interface IContext { readonly extensionContext: ExtensionContext; } +/** + * Provides a code lenses linking to rule documentation. + */ export class DocumentationLensProvider implements CodeLensProvider, Disposable { // Fields private readonly context: IContext; diff --git a/src/vscode-ps-rule/extension.ts b/src/vscode-ps-rule/extension.ts index 4b2df68193..957080ceca 100644 --- a/src/vscode-ps-rule/extension.ts +++ b/src/vscode-ps-rule/extension.ts @@ -22,9 +22,12 @@ import { restore } from './commands/restore'; import { initLock } from './commands/initLock'; import { client } from './client'; import { LanguageClient } from 'vscode-languageclient/node'; +import { DependencyLensProvider } from './dependencyLens'; +import { upgradeDependency } from './commands/upgradeDependency'; export let taskManager: PSRuleTaskProvider | undefined; export let docLensProvider: DocumentationLensProvider | undefined; +export let lockLensProvider: DependencyLensProvider | undefined; export interface ExtensionInfo { id: string; @@ -72,6 +75,10 @@ export class ExtensionManager implements vscode.Disposable { return this._server; } + public get client(): LanguageClient { + return this._client; + } + public activate(context: vscode.ExtensionContext) { this._context = context; this._info = this.checkExtension(context); @@ -84,6 +91,9 @@ export class ExtensionManager implements vscode.Disposable { if (docLensProvider) { docLensProvider.dispose(); } + if (lockLensProvider) { + lockLensProvider.dispose(); + } if (taskManager) { taskManager.dispose(); } @@ -147,6 +157,11 @@ export class ExtensionManager implements vscode.Disposable { initLock(); }) ); + this._context.subscriptions.push( + vscode.commands.registerCommand('PSRule.upgradeDependency', (path: string, name: string) => { + upgradeDependency(path, name); + }) + ); } } @@ -158,6 +173,11 @@ export class ExtensionManager implements vscode.Disposable { docLensProvider.register(); } + if (!lockLensProvider) { + lockLensProvider = new DependencyLensProvider(logger, this._context); + lockLensProvider.register(); + } + if (this.isTrusted) { this.setContextVariables(); } diff --git a/src/vscode-ps-rule/test/suite/configuration.test.ts b/src/vscode-ps-rule/test/suite/configuration.test.ts index a123127e05..d8a6284e10 100644 --- a/src/vscode-ps-rule/test/suite/configuration.test.ts +++ b/src/vscode-ps-rule/test/suite/configuration.test.ts @@ -8,6 +8,7 @@ suite('ConfigurationManager tests', () => { test('Defaults', () => { const config = new ConfigurationManager(undefined, 'PSRule_unit_test'); + assert.equal(config.get().codeLensDependencyManagement, true); assert.equal(config.get().codeLensRuleDocumentationLinks, true); assert.equal(config.get().documentationCustomSnippetPath, undefined); assert.equal(config.get().documentationLocalePath, 'en'); @@ -23,6 +24,6 @@ suite('ConfigurationManager tests', () => { assert.equal(config.get().notificationsShowModuleRestore, true); assert.equal(config.get().notificationsShowPowerShellExtension, true); assert.equal(config.get().ruleBaseline, undefined); - //assert.equal(config.get().languageServerPath, false); + assert.equal(config.get().traceTask, false); }); }); diff --git a/tests/PSRule.EditorServices.Tests/LanguageServerTestContainer.cs b/tests/PSRule.EditorServices.Tests/LanguageServerTestContainer.cs new file mode 100644 index 0000000000..4c0116ef64 --- /dev/null +++ b/tests/PSRule.EditorServices.Tests/LanguageServerTestContainer.cs @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.CommandLine; +using System.CommandLine.Invocation; +using System.CommandLine.Parsing; +using System.IO.Pipelines; +using Microsoft.Extensions.DependencyInjection; +using OmniSharp.Extensions.LanguageServer.Client; +using PSRule.CommandLine; +using PSRule.EditorServices.Hosting; + +namespace PSRule.EditorServices; + +internal sealed class LanguageServerTestContainer(LspServer server, LanguageClient client) : IDisposable +{ + private bool _Disposed; + + public LspServer Server { get; } = server; + public LanguageClient Client { get; } = client; + + public static async Task CreateAsync(string? workingPath = default, CancellationToken cancellationToken = default) + { + var clientPipe = new Pipe(); + var serverPipe = new Pipe(); + + // Setup server. + var server = new LspServer(options => + { + options.WithInput(serverPipe.Reader) + .WithOutput(clientPipe.Writer) + .WithServices(services => + { + services.AddSingleton(new ClientContext(InvocationContext(), null, false, false, workingPath)); + + }); + }); + + // Setup client. + var client = LanguageClient.PreInit(options => + { + options.WithInput(clientPipe.Reader) + .WithOutput(serverPipe.Writer); + }); + + // Wait for the server and client to initialize and connect. + await Task.WhenAll( + server.RunAsync(cancellationToken), + client.Initialize(cancellationToken) + ); + + // Don't wait until exit, fire and forget on this thread. + _ = server.WaitForExitAsync(); + + return new(server, client); + } + + private void Dispose(bool disposing) + { + if (!_Disposed) + { + if (disposing) + { + Client.Dispose(); + Server.Dispose(); + } + _Disposed = true; + } + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + private static InvocationContext InvocationContext(IConsole? console = null) + { + var p = new Parser(); + var result = p.Parse(string.Empty); + return new InvocationContext(result, console); + } +} diff --git a/tests/PSRule.EditorServices.Tests/LspServerTests.cs b/tests/PSRule.EditorServices.Tests/LspServerTests.cs new file mode 100644 index 0000000000..3231b09a52 --- /dev/null +++ b/tests/PSRule.EditorServices.Tests/LspServerTests.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using OmniSharp.Extensions.LanguageServer.Protocol.Workspace; +using PSRule.EditorServices.Handlers; + +namespace PSRule.EditorServices; + +/// +/// Tests for . +/// +public sealed class LspServerTests +{ + [Fact] + public async Task TestServerCommandAsync() + { + using var container = await LanguageServerTestContainer.CreateAsync(workingPath: GetRootPath()); + + var client = container.Client; + + var response = await client.ExecuteCommandWithResponse(Command.Create + ( + name: "upgradeDependency", + args: new UpgradeDependencyCommandHandlerInput + { + Module = "*", + Path = GetSourcePath("ps-rule.lock.json") + } + )); + + Assert.NotNull(response); + } + + private static string GetRootPath() + { + return Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../../../")); + } + + private static string GetSourcePath(string file) + { + return Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../../../", file)); + } +} diff --git a/tests/PSRule.EditorServices.Tests/PSRule.EditorServices.Tests.csproj b/tests/PSRule.EditorServices.Tests/PSRule.EditorServices.Tests.csproj index 31e03be05c..33cb950f15 100644 --- a/tests/PSRule.EditorServices.Tests/PSRule.EditorServices.Tests.csproj +++ b/tests/PSRule.EditorServices.Tests/PSRule.EditorServices.Tests.csproj @@ -2,16 +2,18 @@ net8.0 - {89d6aaaa-2ad9-4899-935e-5330efb3383e} - true - false PSRule.EditorServices + {89d6aaaa-2ad9-4899-935e-5330efb3383e} Full + 12.0 + enable + enable + false + true - - + diff --git a/tests/PSRule.EditorServices.Tests/Usings.cs b/tests/PSRule.EditorServices.Tests/Usings.cs index 0ebd54d508..8c07c6cf4c 100644 --- a/tests/PSRule.EditorServices.Tests/Usings.cs +++ b/tests/PSRule.EditorServices.Tests/Usings.cs @@ -1,4 +1,4 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -// global using Xunit; +global using Xunit;