Skip to content

Commit 29bbac3

Browse files
committed
Merge pull request #209 from rkeithhill/rkeithhill/scriptAnalysisProfilePath
Rkeithhill/script analysis profile path
2 parents dca0f2d + 076ce90 commit 29bbac3

File tree

6 files changed

+96
-28
lines changed

6 files changed

+96
-28
lines changed

src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,14 @@ protected async Task HandleDidChangeConfigurationNotification(
300300
EventContext eventContext)
301301
{
302302
bool oldLoadProfiles = this.currentSettings.EnableProfileLoading;
303-
bool oldScriptAnalysisEnabled =
303+
bool oldScriptAnalysisEnabled =
304304
this.currentSettings.ScriptAnalysis.Enable.HasValue;
305+
string oldScriptAnalysisSettingsPath =
306+
this.currentSettings.ScriptAnalysis.SettingsPath;
305307

306308
this.currentSettings.Update(
307-
configChangeParams.Settings.Powershell);
309+
configChangeParams.Settings.Powershell,
310+
this.editorSession.Workspace.WorkspacePath);
308311

309312
if (!this.profilesLoaded &&
310313
this.currentSettings.EnableProfileLoading &&
@@ -314,11 +317,21 @@ protected async Task HandleDidChangeConfigurationNotification(
314317
this.profilesLoaded = true;
315318
}
316319

317-
if (oldScriptAnalysisEnabled != this.currentSettings.ScriptAnalysis.Enable)
320+
// If there is a new settings file path, restart the analyzer with the new settigs.
321+
bool settingsPathChanged = false;
322+
string newSettingsPath = this.currentSettings.ScriptAnalysis.SettingsPath;
323+
if (!(oldScriptAnalysisSettingsPath?.Equals(newSettingsPath, StringComparison.OrdinalIgnoreCase) ?? false))
318324
{
319-
// If the user just turned off script analysis, send a diagnostics
320-
// event to clear the analysis markers that they already have
321-
if (!this.currentSettings.ScriptAnalysis.Enable.Value)
325+
this.editorSession.RestartAnalysisService(newSettingsPath);
326+
settingsPathChanged = true;
327+
}
328+
329+
// If script analysis settings have changed we need to clear & possibly update the current diagnostic records.
330+
if ((oldScriptAnalysisEnabled != this.currentSettings.ScriptAnalysis.Enable) || settingsPathChanged)
331+
{
332+
// If the user just turned off script analysis or changed the settings path, send a diagnostics
333+
// event to clear the analysis markers that they already have.
334+
if (!this.currentSettings.ScriptAnalysis.Enable.Value || settingsPathChanged)
322335
{
323336
ScriptFileMarker[] emptyAnalysisDiagnostics = new ScriptFileMarker[0];
324337

@@ -330,6 +343,15 @@ await PublishScriptDiagnostics(
330343
eventContext);
331344
}
332345
}
346+
347+
// If script analysis is enabled and the settings file changed get new diagnostic records.
348+
if (this.currentSettings.ScriptAnalysis.Enable.Value && settingsPathChanged)
349+
{
350+
await this.RunScriptDiagnostics(
351+
this.editorSession.Workspace.GetOpenedFiles(),
352+
this.editorSession,
353+
eventContext);
354+
}
333355
}
334356
}
335357

src/PowerShellEditorServices.Protocol/Server/LanguageServerSettings.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
44
//
55

6+
using System.IO;
7+
using Microsoft.PowerShell.EditorServices.Utility;
8+
69
namespace Microsoft.PowerShell.EditorServices.Protocol.Server
710
{
811
public class LanguageServerSettings
@@ -16,12 +19,12 @@ public LanguageServerSettings()
1619
this.ScriptAnalysis = new ScriptAnalysisSettings();
1720
}
1821

19-
public void Update(LanguageServerSettings settings)
22+
public void Update(LanguageServerSettings settings, string workspaceRootPath)
2023
{
2124
if (settings != null)
2225
{
2326
this.EnableProfileLoading = settings.EnableProfileLoading;
24-
this.ScriptAnalysis.Update(settings.ScriptAnalysis);
27+
this.ScriptAnalysis.Update(settings.ScriptAnalysis, workspaceRootPath);
2528
}
2629
}
2730
}
@@ -30,16 +33,33 @@ public class ScriptAnalysisSettings
3033
{
3134
public bool? Enable { get; set; }
3235

36+
public string SettingsPath { get; set; }
37+
3338
public ScriptAnalysisSettings()
3439
{
3540
this.Enable = true;
3641
}
3742

38-
public void Update(ScriptAnalysisSettings settings)
43+
public void Update(ScriptAnalysisSettings settings, string workspaceRootPath)
3944
{
4045
if (settings != null)
4146
{
47+
Validate.IsNotNullOrEmptyString(nameof(workspaceRootPath), workspaceRootPath);
48+
4249
this.Enable = settings.Enable;
50+
51+
string settingsPath = settings.SettingsPath;
52+
53+
if (string.IsNullOrWhiteSpace(settingsPath))
54+
{
55+
settingsPath = null;
56+
}
57+
else if (!Path.IsPathRooted(settingsPath))
58+
{
59+
settingsPath = Path.GetFullPath(Path.Combine(workspaceRootPath, settingsPath));
60+
}
61+
62+
this.SettingsPath = settingsPath;
4363
}
4464
}
4565
}

src/PowerShellEditorServices/Analysis/AnalysisOutputWriter.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
44
//
55

6-
using Microsoft.Windows.PowerShell.ScriptAnalyzer;
6+
using System;
77
using System.Management.Automation;
8+
using Microsoft.PowerShell.EditorServices.Console;
9+
using Microsoft.Windows.PowerShell.ScriptAnalyzer;
810

911
namespace Microsoft.PowerShell.EditorServices
1012
{
@@ -14,31 +16,36 @@ namespace Microsoft.PowerShell.EditorServices
1416
/// </summary>
1517
internal class AnalysisOutputWriter : IOutputWriter
1618
{
19+
private IConsoleHost consoleHost;
20+
21+
public AnalysisOutputWriter(IConsoleHost consoleHost)
22+
{
23+
this.consoleHost = consoleHost;
24+
}
25+
1726
#region IOutputWriter Implementation
1827

1928
void IOutputWriter.WriteError(ErrorRecord error)
2029
{
21-
// TODO: Find a way to trace out this output!
30+
this.consoleHost?.WriteOutput(error.ToString(), true, OutputType.Error, ConsoleColor.Red, ConsoleColor.Black);
2231
}
2332

2433
void IOutputWriter.WriteWarning(string message)
2534
{
26-
// TODO: Find a way to trace out this output!
35+
this.consoleHost?.WriteOutput(message, true, OutputType.Warning, ConsoleColor.Yellow, ConsoleColor.Black);
2736
}
2837

2938
void IOutputWriter.WriteVerbose(string message)
3039
{
31-
// TODO: Find a way to trace out this output!
3240
}
3341

3442
void IOutputWriter.WriteDebug(string message)
3543
{
36-
// TODO: Find a way to trace out this output!
3744
}
3845

3946
void IOutputWriter.ThrowTerminatingError(ErrorRecord record)
4047
{
41-
// TODO: Find a way to trace out this output!
48+
this.consoleHost?.WriteOutput(record.ToString(), true, OutputType.Error, ConsoleColor.Red, ConsoleColor.Black);
4249
}
4350

4451
#endregion

src/PowerShellEditorServices/Analysis/AnalysisService.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.Management.Automation.Runspaces;
1212
using System.Threading;
1313
using System.Threading.Tasks;
14+
using Microsoft.PowerShell.EditorServices.Console;
1415

1516
namespace Microsoft.PowerShell.EditorServices
1617
{
@@ -26,11 +27,10 @@ public class AnalysisService : IDisposable
2627
private ScriptAnalyzer scriptAnalyzer;
2728

2829
/// <summary>
29-
/// Defines the list of Script Analyzer rules to include by default.
30-
/// In the future, a default rule set from Script Analyzer may be used.
30+
/// Defines the list of Script Analyzer rules to include by default if
31+
/// no settings file is specified.
3132
/// </summary>
32-
private static readonly string[] IncludedRules = new string[]
33-
{
33+
private static readonly string[] IncludedRules = {
3434
"PSUseApprovedVerbs",
3535
"PSReservedCmdletChar",
3636
"PSReservedParams",
@@ -47,7 +47,10 @@ public class AnalysisService : IDisposable
4747
/// <summary>
4848
/// Creates an instance of the AnalysisService class.
4949
/// </summary>
50-
public AnalysisService()
50+
/// <param name="consoleHost">An object that implements IConsoleHost in which to write errors/warnings
51+
/// from analyzer.</param>
52+
/// <param name="settingsPath">Path to a PSScriptAnalyzer settings file.</param>
53+
public AnalysisService(IConsoleHost consoleHost, string settingsPath = null)
5154
{
5255
try
5356
{
@@ -63,9 +66,10 @@ public AnalysisService()
6366

6467
this.scriptAnalyzer.Initialize(
6568
this.analysisRunspace,
66-
new AnalysisOutputWriter(),
67-
includeRuleNames: IncludedRules,
68-
includeDefaultRules: true);
69+
new AnalysisOutputWriter(consoleHost),
70+
includeRuleNames: settingsPath == null ? IncludedRules : null,
71+
includeDefaultRules: true,
72+
profile: settingsPath);
6973
}
7074
catch (FileNotFoundException)
7175
{

src/PowerShellEditorServices/Session/EditorSession.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,24 @@ public void StartSession(HostDetails hostDetails)
7676
this.DebugService = new DebugService(this.PowerShellContext);
7777
this.ConsoleService = new ConsoleService(this.PowerShellContext);
7878

79+
this.InstantiateAnalysisService();
80+
81+
// Create a workspace to contain open files
82+
this.Workspace = new Workspace(this.PowerShellContext.PowerShellVersion);
83+
}
84+
85+
/// <summary>
86+
/// Restarts the AnalysisService so it can be configured with a new settings file.
87+
/// </summary>
88+
/// <param name="settingsPath">Path to the settings file.</param>
89+
public void RestartAnalysisService(string settingsPath)
90+
{
91+
this.AnalysisService?.Dispose();
92+
InstantiateAnalysisService(settingsPath);
93+
}
94+
95+
internal void InstantiateAnalysisService(string settingsPath = null)
96+
{
7997
// Only enable the AnalysisService if the machine has PowerShell
8098
// v5 installed. Script Analyzer works on earlier PowerShell
8199
// versions but our hard dependency on their binaries complicates
@@ -89,7 +107,7 @@ public void StartSession(HostDetails hostDetails)
89107
// Script Analyzer binaries are not included.
90108
try
91109
{
92-
this.AnalysisService = new AnalysisService();
110+
this.AnalysisService = new AnalysisService(this.PowerShellContext.ConsoleHost, settingsPath);
93111
}
94112
catch (FileNotFoundException)
95113
{
@@ -105,9 +123,6 @@ public void StartSession(HostDetails hostDetails)
105123
"Script Analyzer cannot be loaded due to unsupported PowerShell version " +
106124
this.PowerShellContext.PowerShellVersion.ToString());
107125
}
108-
109-
// Create a workspace to contain open files
110-
this.Workspace = new Workspace(this.PowerShellContext.PowerShellVersion);
111126
}
112127

113128
#endregion

0 commit comments

Comments
 (0)