Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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