From 3663252e93779deaaf7b33aedee33a62b0f2f8db Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Sun, 27 Mar 2016 15:10:03 -0600 Subject: [PATCH 1/3] Initial attempt to fix #122 analyzer settings path This adds a scriptAnalysis.settingsPath setting but uncovers some issues about how to be an absolute path back to the language host from the client. Depending on where the user "set" this setting a relative path has a different meaning. If set in .vscode\settings.json then relative probably should be relative to the workspaceRoot. In the global settings file, it should probably be the extensionInstallDir. If in the user's settings file, then what ... their home dir? If we treated this like the other HostPaths then relative would *always* be relative to the extensionInstallDir. If we could get VSCode to expand ${workspaceRoot} that would allow the user to specify a path in the current workspace folder. --- PSScriptAnalyzerSettings.psd1 | 26 ++++++++++++++++++++++++++ package.json | 5 +++++ src/main.ts | 33 ++++++++++++++++++++++++++++++++- src/settings.ts | 4 +++- 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 PSScriptAnalyzerSettings.psd1 diff --git a/PSScriptAnalyzerSettings.psd1 b/PSScriptAnalyzerSettings.psd1 new file mode 100644 index 0000000000..6fea018c7d --- /dev/null +++ b/PSScriptAnalyzerSettings.psd1 @@ -0,0 +1,26 @@ +# The PowerShell Script Analyzer will generate a warning +# diagnostic record for this file due to a bug - +# https://github.com/PowerShell/PSScriptAnalyzer/issues/472 +@{ + # Only diagnostic records of the specified severity will be generated. + # Uncomment the following line if you only want Errors and Warnings but + # not Information diagnostic records. + #Severity = @('Error','Warning') + + # Analyze **only** the following rules. Use IncludeRules when you want + # to invoke only a small subset of the defualt rules. + IncludeRules = @('PSAvoidDefaultValueSwitchParameter', + 'PSMissingModuleManifestField', + 'PSReservedCmdletChar', + 'PSReservedParams', + 'PSShouldProcess', + 'PSUseApprovedVerbs', + 'PSUseDeclaredVarsMoreThanAssigments') + + # Do not analyze the following rules. Use ExcludeRules when you have + # commented out the IncludeRules settings above and want to include all + # the default rules except for those you exclude below. + # Note: if a rule is in both IncludeRules and ExcludeRules, the rule + # will be excluded. + #ExcludeRules = @('PSAvoidUsingWriteHost') +} diff --git a/package.json b/package.json index 493124b7e5..06cad1b66d 100644 --- a/package.json +++ b/package.json @@ -233,6 +233,11 @@ "default": true, "description": "Enables real-time script analysis using PowerShell Script Analyzer." }, + "powershell.scriptAnalysis.settingsPath": { + "type": "string", + "default": "./PSScriptAnalyzerSettings.psd1", + "description": "Specifies the path to the PowerShell Script Analyzer settings file. The settings file can be used to customize which rules to include or exclude as well as what severity levels to report." + }, "powershell.developer.editorServicesHostPath": { "type": "string", "default": "../bin/", diff --git a/src/main.ts b/src/main.ts index 4e699ffc9e..8b1ded1ba3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -73,6 +73,8 @@ export function activate(context: vscode.ExtensionContext): void { try { + settings.scriptAnalysis.settingsPath = resolveScriptAnalysisSettingsPath(settings); + let serverPath = resolveLanguageServerPath(settings); let serverOptions = { run: { @@ -151,7 +153,7 @@ function resolveLanguageServerPath(settings: settingsManager.ISettings): string console.log(" Resolved path to: " + editorServicesHostPath); } else { - // Use the default path in the plugin's 'bin' folder + // Use the default path in the extension's 'bin' folder editorServicesHostPath = path.join( __dirname, @@ -165,6 +167,35 @@ function resolveLanguageServerPath(settings: settingsManager.ISettings): string return editorServicesHostPath; } +function resolveScriptAnalysisSettingsPath(settings: settingsManager.ISettings): string { + var scriptAnalysisSettingsPath = settings.scriptAnalysis.settingsPath; + + if (scriptAnalysisSettingsPath) { + console.log("Found scriptAnalysis.settingsPath from config: " + scriptAnalysisSettingsPath); + + // Make the path absolute if it's not + scriptAnalysisSettingsPath = + path.resolve( + __dirname, + '..', + scriptAnalysisSettingsPath); + + console.log(" Resolved path to: " + scriptAnalysisSettingsPath); + } + else { + // Use the default path in the extension's 'root' folder + scriptAnalysisSettingsPath = + path.join( + __dirname, + '..', + 'PSScriptAnalyzerSettings.psd1'); + + console.log("Using default scriptAnalysis.settingsPath: " + scriptAnalysisSettingsPath); + } + + return scriptAnalysisSettingsPath; +} + function getHostExeName(useX86Host: boolean): string { // The useX86Host setting is only relevant on 64-bit OS var is64BitOS = process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'); diff --git a/src/settings.ts b/src/settings.ts index 610fd426ae..478f45edf1 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -8,6 +8,7 @@ import vscode = require('vscode'); export interface IScriptAnalysisSettings { enable?: boolean + settingsPath: string } export interface IDeveloperSettings { @@ -26,7 +27,8 @@ export function load(myPluginId: string): ISettings { let configuration = vscode.workspace.getConfiguration(myPluginId); let defaultScriptAnalysisSettings = { - enable: true + enable: true, + settingsPath: "./PSScriptAnalyzerSettings.psd1" }; let defaultDeveloperSettings = { From a798b2e06134c2976fbdf7e6a5efe7679c81030c Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Sun, 10 Apr 2016 13:55:25 -0600 Subject: [PATCH 2/3] Finishing up fix #122 Use empty string now to get the default (built-in) settings for script analysis. Tweaked the build script to fix some problems and to exclude the script analysis settings file. Also changed encoding the SampleModule.psd1 file to UTF8. --- .vscode/tasks.json | 4 +-- examples/.vscode/settings.json | 5 +++ examples/Build.ps1 | 19 ++++++----- .../PSScriptAnalyzerSettings.psd1 | 0 examples/SampleModule.psd1 | Bin 7694 -> 3733 bytes package.json | 4 +-- src/main.ts | 31 ------------------ 7 files changed, 20 insertions(+), 43 deletions(-) create mode 100644 examples/.vscode/settings.json rename PSScriptAnalyzerSettings.psd1 => examples/PSScriptAnalyzerSettings.psd1 (100%) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 99ea9b0775..fd52c8d715 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -31,7 +31,7 @@ // we run the custom script "compile" as defined in package.json "args": ["run", "compile"], - // use the standard tsc problem matcher to find compile problems in the output. + // use the standard tsc problem matcher to find compile problems in the output. "problemMatcher": "$tsc" }, { @@ -47,7 +47,7 @@ // The tsc compiler is started in watching mode "isWatching": true, - // use the standard tsc in watch mode problem matcher to find compile problems in the output. + // use the standard tsc in watch mode problem matcher to find compile problems in the output. "problemMatcher": "$tsc-watch" } ] diff --git a/examples/.vscode/settings.json b/examples/.vscode/settings.json new file mode 100644 index 0000000000..28db732896 --- /dev/null +++ b/examples/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + // Use a custom PowerShell Script Analyzer settings file for this workspace. + // Relative paths for this setting are always relative to the workspace root dir. + "powershell.scriptAnalysis.settingsPath": "./PSScriptAnalyzerSettings.psd1" +} \ No newline at end of file diff --git a/examples/Build.ps1 b/examples/Build.ps1 index 8c7a657a3d..6ec5f2e534 100644 --- a/examples/Build.ps1 +++ b/examples/Build.ps1 @@ -65,27 +65,30 @@ ############################################################################### Properties { # The name of your module should match the basename of the PSD1 file. - $ModuleName = (Get-Item $PSScriptRoot\*.psd1)[0].BaseName + $ModuleName = (Get-Item $PSScriptRoot\*.psd1 | + Foreach-Object {$null = Test-ModuleManifest -Path $_ -ErrorAction SilentlyContinue; if ($?) {$_}})[0].BaseName # Path to the release notes file. Set to $null if the release notes reside in the manifest file. $ReleaseNotesPath = "$PSScriptRoot\ReleaseNotes.md" # The directory used to publish the module from. If you are using Git, the - # $PublishDir should be ignored if it is under the workspace directory. - $PublishDir = "$PSScriptRoot\Release\$ModuleName" + # $PublishRootDir should be ignored if it is under the workspace directory. + $PublishRootDir = "$PSScriptRoot\Release" + $PublishDir = "$PublishRootDir\$ModuleName" # The following items will not be copied to the $PublishDir. # Add items that should not be published with the module. $Exclude = @( + (Split-Path $PSCommandPath -Leaf), 'Release', 'Tests', '.git*', '.vscode', - # The next three files are unique to this examples dir. + # These files are unique to this examples dir. 'DebugTest.ps1', - 'Stop*.ps1', + 'PSScriptAnalyzerSettings.psd1', 'Readme.md', - (Split-Path $PSCommandPath -Leaf) + 'Stop*.ps1' ) # Name of the repository you wish to publish to. Default repo is the PSGallery. @@ -170,8 +173,8 @@ Task Clean -depends Init -requiredVariables PublishDir { # Sanity check the dir we are about to "clean". If $PublishDir were to # inadvertently get set to $null, the Remove-Item commmand removes the # contents of \*. That's a bad day. Ask me how I know? :-( - if ($PublishDir.Contains($PSScriptRoot)) { - Remove-Item $PublishDir\* -Recurse -Force + if ($PublishRootDir.Contains($PSScriptRoot)) { + Remove-Item $PublishRootDir\* -Recurse -Force } } diff --git a/PSScriptAnalyzerSettings.psd1 b/examples/PSScriptAnalyzerSettings.psd1 similarity index 100% rename from PSScriptAnalyzerSettings.psd1 rename to examples/PSScriptAnalyzerSettings.psd1 diff --git a/examples/SampleModule.psd1 b/examples/SampleModule.psd1 index ba441347581c305bed4503ed88f8740def4e03c7..21fd49acb1d6406346a475525713d0bf177cd000 100644 GIT binary patch literal 3733 zcmbVP+iu%N5PjEI4B!XZg+<$mW4J|ARJG(pg(bPVB+XN>BA4PeT)}`La^}qa%;<=EV;YTTbThvHK(n`lDGj@$!EJv!qj&wuAKlqt7?6K~cYn_D zyi3#W@cynJw2tUaf7G9JXMOrGo=>)_^XXvp23ma@@l|KYq=>mGhAJvk4pT$e=+SI! z0p{IFcQore1i)GN`DpOhypLCd9^H;7752C{w>E$Ow?+6I(Y+QAtl$)}f>EI;XU5q7 zMZzibmQ2n=5epuXkTg-M^5D!nGE?_jh1{5cW{EJAu{E*OC<>J<7&I8&PkRVd{M@@#1sn+zst2yuHee-FAvrBsnsP0;@t#<4`*H9vd)yvm zxza`Zl-jo<+yG>?O5poIBvC_!&)}tMrJ1;cXf?iWQDT>_ua(1>v z?#e|Fs_g9J$B$a0S3;{Y~AtXcdRo&=3#8j$KU{E99 zslI6{MhIHlskE&!Wm%qbKb}EuvI}^8MDMsZ7&nq-w%~d%XFjxeM4!XyUE1%7*3j+gI z%Fq*=DAt52dqA=rpEX9k)l`JVse;?l7R;^-OAPqa{BtSv27xzNk={5~T02jMLW-=+ zkR4y=%A5BB$y%AF7MDv)X}h>J387WCyxZspXT)XqY2-wi;)ihGLU2>5XL|oE8~gr$ zBS}LMYGqVhP%y&cywzx+mC~OM#L-j5h!?fw4;ZoQ6qKEzOHwA6C0io@B_;?}Kfbw} zoE)%**ZUT#m5U)@I!wUoVNrtNjz>!JQ~LY*>Xf=!bai9U{JT?(1}7;C&DsS3oLLhAB0xY4OXrN{K9)Ly|)0+U6ZPxJ>wV*>+i={mspX; z@N9uiy=OL6;E@QE^n<_+oEp0#Sxcsdj=_o-Cq6d28Bhtk>RplCM77N`Lb4Z}hd1>x zv<+&u&Or%VvtP0lmX%Fs71t`^Fz-_PI9XQxTd=oEXQ<5o2lfEpg5K1nE+H{P5|<}x z;K{PuxX-;1k*AS^*;uHnb6ZiSJ3aXqdr48ORo2`tSnGI$dq))5KdC@Vauy~v-THEx zM3pJXmcy6_0#k3eG_z!k`sZBZ3d)!axm(@!nMtk|oBPjK!w)W#5y)5q)u$k6)jrQu z-+S!tKzpj++6(ZsItkskk$NxEC}cX?eO^Cx18|c?DK8Es0ro4QhSl~@Ze-svE$n&y z9sOGDF+w*LxT(IQUkN?d?oDsNVg|Pteh%0cf1;3xp=ZL$MzR4^@xYy}EtU*Mv2M7W zg`Ys0JLiw1D4_Xva$0pqH8K2<973=K+tq)I9|Z#$D_re^{rlvIHgE0A4P*9r%*wO? zP4QTKarcE~eAhUePJGnV0gWHH);JIx`$W4KrLisOe_3>Vl+?L*_?C1ki#U9&75}_) I=WDC=AMAF>OaK4? literal 7694 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 H?;QUE%{|Y; diff --git a/package.json b/package.json index 66510d203e..f181d0e06b 100644 --- a/package.json +++ b/package.json @@ -247,8 +247,8 @@ }, "powershell.scriptAnalysis.settingsPath": { "type": "string", - "default": "./PSScriptAnalyzerSettings.psd1", - "description": "Specifies the path to the PowerShell Script Analyzer settings file. The settings file can be used to customize which rules to include or exclude as well as what severity levels to report." + "default": "", + "description": "Specifies the path to a PowerShell Script Analyzer settings file. Use either an absolute path (to override the default settings for all projects) or use a path relative to your workspace." }, "powershell.developer.editorServicesHostPath": { "type": "string", diff --git a/src/main.ts b/src/main.ts index 7f39ef64d0..07cbd629d1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -86,8 +86,6 @@ export function activate(context: vscode.ExtensionContext): void { try { - settings.scriptAnalysis.settingsPath = resolveScriptAnalysisSettingsPath(settings); - let serverPath = resolveLanguageServerPath(settings); let serverOptions = { run: { @@ -180,35 +178,6 @@ function resolveLanguageServerPath(settings: settingsManager.ISettings): string return editorServicesHostPath; } -function resolveScriptAnalysisSettingsPath(settings: settingsManager.ISettings): string { - var scriptAnalysisSettingsPath = settings.scriptAnalysis.settingsPath; - - if (scriptAnalysisSettingsPath) { - console.log("Found scriptAnalysis.settingsPath from config: " + scriptAnalysisSettingsPath); - - // Make the path absolute if it's not - scriptAnalysisSettingsPath = - path.resolve( - __dirname, - '..', - scriptAnalysisSettingsPath); - - console.log(" Resolved path to: " + scriptAnalysisSettingsPath); - } - else { - // Use the default path in the extension's 'root' folder - scriptAnalysisSettingsPath = - path.join( - __dirname, - '..', - 'PSScriptAnalyzerSettings.psd1'); - - console.log("Using default scriptAnalysis.settingsPath: " + scriptAnalysisSettingsPath); - } - - return scriptAnalysisSettingsPath; -} - function getHostExeName(useX86Host: boolean): string { // The useX86Host setting is only relevant on 64-bit OS var is64BitOS = process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'); From 5ddd2c9549e9f66acbe379eff86f5f27f54acecb Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Sun, 10 Apr 2016 13:57:21 -0600 Subject: [PATCH 3/3] Oops, need to set the correct default setting value for the settings path. --- src/settings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings.ts b/src/settings.ts index e0f5c5281d..5ab0e07c5f 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -29,7 +29,7 @@ export function load(myPluginId: string): ISettings { let defaultScriptAnalysisSettings = { enable: true, - settingsPath: "./PSScriptAnalyzerSettings.psd1" + settingsPath: "" }; let defaultDeveloperSettings = {