Skip to content

Commit

Permalink
Update vscode extension support #1755 #2642 (#2657)
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Dec 5, 2024
1 parent 3688167 commit 7f3dc1f
Show file tree
Hide file tree
Showing 21 changed files with 371 additions and 158 deletions.
12 changes: 12 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/out/dist/**/*.js"
],
"preLaunchTask": "Build vscode"
}
]
}
19 changes: 8 additions & 11 deletions PSRule.sln
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PSRule.CommandLine.Tests",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PSRule.Types.Tests", "tests\PSRule.Types.Tests\PSRule.Types.Tests.csproj", "{34095F78-CDA3-4E72-B64C-6366EA4B3EAF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2E2A23CD-BD35-45DE-B2BD-20C8E45BBA41}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PSRule.EditorServices", "src\PSRule.EditorServices\PSRule.EditorServices.csproj", "{061DD38A-B9E9-4EF1-B5B7-D0A484DB74D1}"
EndProject
Global
Expand All @@ -46,6 +44,14 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5FE4DB0B-63D1-4DDB-9762-9C0D29168BC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5FE4DB0B-63D1-4DDB-9762-9C0D29168BC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5FE4DB0B-63D1-4DDB-9762-9C0D29168BC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5FE4DB0B-63D1-4DDB-9762-9C0D29168BC9}.Release|Any CPU.Build.0 = Release|Any CPU
{309BED8B-4E60-4C42-A2B4-37A2E7EBEF3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{309BED8B-4E60-4C42-A2B4-37A2E7EBEF3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{309BED8B-4E60-4C42-A2B4-37A2E7EBEF3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{309BED8B-4E60-4C42-A2B4-37A2E7EBEF3F}.Release|Any CPU.Build.0 = Release|Any CPU
{0130215D-58EB-4887-B6FA-31ED02500569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0130215D-58EB-4887-B6FA-31ED02500569}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0130215D-58EB-4887-B6FA-31ED02500569}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -58,10 +64,6 @@ Global
{D3488CE2-779F-4474-B38A-F894A4B689F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3488CE2-779F-4474-B38A-F894A4B689F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3488CE2-779F-4474-B38A-F894A4B689F7}.Release|Any CPU.Build.0 = Release|Any CPU
{309BED8B-4E60-4C42-A2B4-37A2E7EBEF3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{309BED8B-4E60-4C42-A2B4-37A2E7EBEF3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{309BED8B-4E60-4C42-A2B4-37A2E7EBEF3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{309BED8B-4E60-4C42-A2B4-37A2E7EBEF3F}.Release|Any CPU.Build.0 = Release|Any CPU
{20DDCC65-8A9A-4BDC-91EC-C3BE6F32E52E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{20DDCC65-8A9A-4BDC-91EC-C3BE6F32E52E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20DDCC65-8A9A-4BDC-91EC-C3BE6F32E52E}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -74,10 +76,6 @@ Global
{BDDBFDB8-614F-4B8A-930C-DCB60144598C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BDDBFDB8-614F-4B8A-930C-DCB60144598C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BDDBFDB8-614F-4B8A-930C-DCB60144598C}.Release|Any CPU.Build.0 = Release|Any CPU
{5FE4DB0B-63D1-4DDB-9762-9C0D29168BC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5FE4DB0B-63D1-4DDB-9762-9C0D29168BC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5FE4DB0B-63D1-4DDB-9762-9C0D29168BC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5FE4DB0B-63D1-4DDB-9762-9C0D29168BC9}.Release|Any CPU.Build.0 = Release|Any CPU
{872D2648-2F00-475E-84B5-F08BE07385B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{872D2648-2F00-475E-84B5-F08BE07385B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{872D2648-2F00-475E-84B5-F08BE07385B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -111,7 +109,6 @@ Global
{DA46C891-08F1-4D01-9F98-1F8BB10CAFEC} = {E0EA0CBA-96C5-4447-8B69-BC13EF0D7A4A}
{C25E2FC1-E306-4D99-925C-15E5DD51F6A2} = {E0EA0CBA-96C5-4447-8B69-BC13EF0D7A4A}
{34095F78-CDA3-4E72-B64C-6366EA4B3EAF} = {E0EA0CBA-96C5-4447-8B69-BC13EF0D7A4A}
{061DD38A-B9E9-4EF1-B5B7-D0A484DB74D1} = {2E2A23CD-BD35-45DE-B2BD-20C8E45BBA41}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {533491EB-BAE9-472E-B57F-A675ECD335B5}
Expand Down
12 changes: 12 additions & 0 deletions docs/CHANGELOG-v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers

## Unreleased

What's changed since pre-release v3.0.0-B0340:

- New features:
- VSCode extension includes PSRule runtime by @BernieWhite.
[#1755](https://github.com/microsoft/PSRule/issues/1755)
- The PSRule runtime is bundled with the VSCode extension.
- Separate installation of the PSRule PowerShell module is no longer required.
- VSCode extension asks to automatically restore modules by @BernieWhite.
[#2642](https://github.com/microsoft/PSRule/issues/2642)
- When opening a workspace, the extension will ask to restore any modules from the lock file.
- Alternatively, running the `PSRule: Restore modules` command manually will restore modules.

## v3.0.0-B0340 (pre-release)

What's changed since pre-release v3.0.0-B0315:
Expand Down
18 changes: 16 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"onLanguage:powershell",
"onLanguage:yaml",
"workspaceContains:/ps-rule.yaml",
"workspaceContains:/ps-rule.lock.json",
"workspaceContains:**/ps-rule.yaml",
"workspaceContains:**/*.Rule.yaml",
"workspaceContains:**/*.Rule.yml",
Expand Down Expand Up @@ -196,16 +197,29 @@
"description": "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 start up.",
"description": "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.",
"scope": "application"
},
"PSRule.notifications.showPowerShellExtension": {
"type": "boolean",
"default": true,
"description": "Determines if a notification to install the PowerShell extension is shown on start up.",
"description": "Determines if a notification to install the PowerShell extension is shown on activation.",
"scope": "application"
},
"PSRule.options.path": {
Expand Down
3 changes: 2 additions & 1 deletion src/PSRule.CommandLine/ClientContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ public ClientContext(InvocationContext invocation, string? option, bool verbose,
public bool Debug { get; }

/// <summary>
/// Configures the path to use for caching rules modules.
/// Configures the root path to use for caching artifacts including modules.
/// Each artifact is in a subdirectory of the root path.
/// </summary>
public string CachePath { get; }

Expand Down
3 changes: 3 additions & 0 deletions src/PSRule.CommandLine/ClientHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,7 @@ public override void Debug(string text)

_Context.Invocation.Console.WriteLine(text);
}

/// <inheritdoc/>
public override string? CachePath => _Context.CachePath;
}
8 changes: 8 additions & 0 deletions src/PSRule.EditorServices/ClientBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ internal sealed class ClientBuilder
private readonly Option<string[]> _Run_Module;
private readonly Option<string> _Run_Baseline;
private readonly Option<string[]> _Run_Outcome;
private readonly Option<bool> _Run_NoRestore;

private ClientBuilder(RootCommand cmd)
{
Expand Down Expand Up @@ -87,6 +88,10 @@ private ClientBuilder(RootCommand cmd)
description: CmdStrings.Run_Outcome_Description
).FromAmong("Pass", "Fail", "Error", "Processed", "Problem");
_Run_Outcome.Arity = ArgumentArity.ZeroOrMore;
_Run_NoRestore = new Option<bool>(
"--no-restore",
description: CmdStrings.Run_NoRestore_Description
);

// Options for the module command.
_Module_Init_Force = new Option<bool>(
Expand Down Expand Up @@ -144,6 +149,7 @@ private void AddRun()
cmd.AddOption(_Run_Module);
cmd.AddOption(_Run_Baseline);
cmd.AddOption(_Run_Outcome);
cmd.AddOption(_Run_NoRestore);
cmd.SetHandler(async (invocation) =>
{
var option = new RunOptions
Expand All @@ -153,6 +159,7 @@ private void AddRun()
Module = invocation.ParseResult.GetValueForOption(_Run_Module),
Baseline = invocation.ParseResult.GetValueForOption(_Run_Baseline),
Outcome = ParseOutcome(invocation.ParseResult.GetValueForOption(_Run_Outcome)),
NoRestore = invocation.ParseResult.GetValueForOption(_Run_NoRestore),
};
var client = GetClientContext(invocation);

Expand All @@ -164,6 +171,7 @@ private void AddRun()
invocation.Console.WriteLine($"VERBOSE: Using workspace: {Environment.GetWorkingPath()}");
invocation.Console.WriteLine($"VERBOSE: Using module search path: {sp}");
invocation.Console.WriteLine($"VERBOSE: Using language server: {client.Path}");
invocation.Console.WriteLine($"VERBOSE: Using cache path: {client.CachePath}");
}

invocation.ExitCode = await RunCommand.RunAsync(option, client);
Expand Down
9 changes: 9 additions & 0 deletions src/PSRule.EditorServices/Resources/CmdStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/PSRule.EditorServices/Resources/CmdStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,7 @@
<data name="Run_OutputPath_Description" xml:space="preserve">
<value>Specifies a path to write results to.</value>
</data>
<data name="Run_NoRestore_Description" xml:space="preserve">
<value>Do not restore modules before running rules.</value>
</data>
</root>
2 changes: 1 addition & 1 deletion src/PSRule/Pipeline/CommandLineBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static class CommandLineBuilder
/// <returns>A builder object to configure the pipeline.</returns>
public static IInvokePipelineBuilder Invoke(string[] module, PSRuleOption option, IHostContext hostContext, LockFile? file = null)
{
var sourcePipeline = new SourcePipelineBuilder(hostContext, option, GetLocalPath());
var sourcePipeline = new SourcePipelineBuilder(hostContext, option, hostContext.CachePath ?? GetLocalPath());
LoadModules(sourcePipeline, module, option, file);

var source = sourcePipeline.Build();
Expand Down
7 changes: 7 additions & 0 deletions src/PSRule/Pipeline/HostContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

namespace PSRule.Pipeline;

#nullable enable

/// <summary>
/// A base class for custom host context instances.
/// </summary>
Expand Down Expand Up @@ -94,4 +96,9 @@ public virtual string GetWorkingPath()
{
return Directory.GetCurrentDirectory();
}

/// <inheritdoc/>
public virtual string? CachePath => null;
}

#nullable restore
10 changes: 10 additions & 0 deletions src/PSRule/Pipeline/IHostContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

namespace PSRule.Pipeline;

#nullable enable

/// <summary>
/// A host context for handling input and output emitted from the pipeline.
/// </summary>
Expand Down Expand Up @@ -76,4 +78,12 @@ public interface IHostContext
/// Get the current working path.
/// </summary>
string GetWorkingPath();

/// <summary>
/// Configures the root path to use for caching artifacts including modules.
/// Each artifact is in a subdirectory of the root path.
/// </summary>
string? CachePath { get; }
}

#nullable restore
7 changes: 7 additions & 0 deletions src/PSRule/Pipeline/PSHostContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

namespace PSRule.Pipeline;

#nullable enable

/// <summary>
/// The host context used for PowerShell-based pipelines.
/// </summary>
Expand Down Expand Up @@ -98,4 +100,9 @@ public string GetWorkingPath()
{
return ExecutionContext.SessionState.Path.CurrentFileSystemLocation.Path;
}

/// <inheritdoc/>
public string? CachePath { get; }
}

#nullable restore
27 changes: 12 additions & 15 deletions src/PSRule/Pipeline/SourcePipelineBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@ public sealed class SourcePipelineBuilder : ISourcePipelineBuilder, ISourceComma
private readonly IHostContext _HostContext;
private readonly HostPipelineWriter _Writer;
private readonly bool _UseDefaultPath;
private readonly string _LocalPath;
private readonly string _CachePath;
private readonly RestrictScriptSource _RestrictScriptSource;
private readonly string _WorkspacePath;

internal SourcePipelineBuilder(IHostContext hostContext, PSRuleOption option, string localPath = null)
internal SourcePipelineBuilder(IHostContext hostContext, PSRuleOption option, string cachePath = null)
{
_Source = new Dictionary<string, Source>(StringComparer.OrdinalIgnoreCase);
_HostContext = hostContext;
_Writer = new HostPipelineWriter(hostContext, option, ShouldProcess);
_Writer.EnterScope("[Discovery.Source]");
_UseDefaultPath = option == null || option.Include == null || option.Include.Path == null;
_LocalPath = localPath;
_CachePath = cachePath;
_RestrictScriptSource = option?.Execution?.RestrictScriptSource ?? ExecutionOption.Default.RestrictScriptSource.Value;
_WorkspacePath = Environment.GetRootedBasePath(null);

Expand Down Expand Up @@ -162,32 +162,29 @@ public void ModuleByName(string name, string version = null)

private string FindModule(string name, string version)
{
return TryPackagedModule(name, version, out var path) ||
return TryPackagedModuleFromCache(name, version, out var path) ||
TryInstalledModule(name, version, out path) ? path : null;
}

/// <summary>
/// Try to find a packaged module found relative to the tool.
/// </summary>
private bool TryPackagedModule(string name, string version, out string path)
private bool TryPackagedModuleFromCache(string name, string version, out string path)
{
path = null;
if (_LocalPath == null)
if (_CachePath == null)
return false;

Log($"[PSRule][S] -- Searching for module in: {_LocalPath}");
Log($"[PSRule][S] -- Searching for module in: {_CachePath}");
if (!string.IsNullOrEmpty(version))
{
path = Environment.GetRootedBasePath(Path.Combine(_LocalPath, "Modules", name, version));
if (System.IO.Directory.Exists(path))
path = Environment.GetRootedBasePath(Path.Combine(_CachePath, "Modules", name, version));
if (File.Exists(Path.Combine(path, GetManifestName(name))))
return true;
}

path = Environment.GetRootedBasePath(Path.Combine(_LocalPath, "Modules", name));
if (System.IO.Directory.Exists(path))
return true;

return System.IO.Directory.Exists(path);
path = Environment.GetRootedBasePath(Path.Combine(_CachePath, "Modules", name));
return File.Exists(Path.Combine(path, GetManifestName(name)));
}

/// <summary>
Expand Down Expand Up @@ -253,10 +250,10 @@ private static string[] SortModulePath(IEnumerable<string> values)
private Source.ModuleInfo LoadManifest(string basePath, string name)
{
var path = Path.Combine(basePath, GetManifestName(name));
Log("[PSRule][S] -- Loading manifest from: {0}", path);
if (!File.Exists(path))
return null;

Log("[PSRule][S] -- Loading manifest for: {0}", basePath);
using var reader = new StreamReader(path);
var data = reader.ReadToEnd();
var ast = System.Management.Automation.Language.Parser.ParseInput(data, out _, out _);
Expand Down
6 changes: 4 additions & 2 deletions src/vscode-ps-rule/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,10 @@ Name | Description
`PSRule.execution.ruleSuppressed` | Determines how to handle suppressed rules. When set to `None`, PSRule will use the default (`Warn`), unless set by PSRule options.
`PSRule.execution.unprocessedObject` | Determines how to report objects that are not processed by any rule. When set to `None`, PSRule will use the default (`Warn`), unless set by PSRule options.
`PSRule.experimental.enabled` | Enables experimental features in the PSRule extension.
`PSRule.notifications.showChannelUpgrade` | Determines if a notification to switch to the stable channel is shown on start up.
`PSRule.notifications.showPowerShellExtension` | Determines if a notification to install the PowerShell extension is shown on start up.
`PSRule.lock.restore` | Determines if workspace modules will automatically be restored during activation. Modules can be restored manually using the `PSRule: Restore modules` command.
`PSRule.notifications.showChannelUpgrade` | Determines if a notification to switch to the stable channel is shown on activation.
`PSRule.notifications.showModuleRestore` | Determines if a notification to restore modules is shown on activation.
`PSRule.notifications.showPowerShellExtension` | Determines if a notification to install the PowerShell extension is shown on activation.
`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.
Expand Down
Loading

0 comments on commit 7f3dc1f

Please sign in to comment.