summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Harris <zigford@gmail.com>2019-03-30 01:25:55 +1000
committerw0rp <w0rp@users.noreply.github.com>2019-03-29 15:25:55 +0000
commit000c37e77540310afc500a212401946c7bfd75fe (patch)
treeb860d667c77b726f3f529bada981f487a9d0af45
parent442d672d8aa20d866c6c186d8a11ad63bb1a9c6d (diff)
downloadale-000c37e77540310afc500a212401946c7bfd75fe.zip
PSScriptAnalyzer (#2370)
* Added psscriptanalyzer * Added exclusions and documentation * Added PSScriptAnalyzer handler test
-rw-r--r--ale_linters/powershell/psscriptanalyzer.vim105
-rw-r--r--doc/ale-powershell.txt62
-rw-r--r--doc/ale-supported-languages-and-tools.txt2
-rw-r--r--doc/ale.txt2
-rw-r--r--supported-tools.md2
-rw-r--r--test/handler/test_psscriptanalyzer_handler.vader42
6 files changed, 215 insertions, 0 deletions
diff --git a/ale_linters/powershell/psscriptanalyzer.vim b/ale_linters/powershell/psscriptanalyzer.vim
new file mode 100644
index 00000000..8d1804f8
--- /dev/null
+++ b/ale_linters/powershell/psscriptanalyzer.vim
@@ -0,0 +1,105 @@
+" Author: Jesse Harris - https://github.com/zigford
+" Description: This file adds support for lintng powershell scripts
+" using the PSScriptAnalyzer module.
+
+" let g:ale_powershell_psscriptanalyzer_exclusions =
+" \ 'PSAvoidUsingWriteHost,PSAvoidGlobalVars'
+call ale#Set('powershell_psscriptanalyzer_exclusions', '')
+call ale#Set('powershell_psscriptanalyzer_executable', 'pwsh')
+call ale#Set('powershell_psscriptanalyzer_module',
+\ 'psscriptanalyzer')
+
+function! ale_linters#powershell#psscriptanalyzer#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'powershell_psscriptanalyzer_executable')
+endfunction
+
+" Write a powershell script to a temp file for execution
+" return the command used to execute it
+function! s:TemporaryPSScript(buffer, input) abort
+ let l:filename = 'script.ps1'
+ " Create a temp dir to house our temp .ps1 script
+ " a temp dir is needed as powershell needs the .ps1
+ " extension
+ let l:tempdir = ale#util#Tempname() . (has('win32') ? '\' : '/')
+ let l:tempscript = l:tempdir . l:filename
+ " Create the temporary directory for the file, unreadable by 'other'
+ " users.
+ call mkdir(l:tempdir, '', 0750)
+ " Automatically delete the directory later.
+ call ale#command#ManageDirectory(a:buffer, l:tempdir)
+ " Write the script input out to a file.
+ call ale#util#Writefile(a:buffer, a:input, l:tempscript)
+
+ return l:tempscript
+endfunction
+
+function! ale_linters#powershell#psscriptanalyzer#RunPowerShell(buffer, command) abort
+ let l:executable = ale_linters#powershell#psscriptanalyzer#GetExecutable(
+ \ a:buffer)
+ let l:tempscript = s:TemporaryPSScript(a:buffer, a:command)
+
+ return ale#Escape(l:executable)
+ \ . ' -Exe Bypass -NoProfile -File '
+ \ . ale#Escape(l:tempscript)
+ \ . ' %t'
+endfunction
+
+" Run Invoke-ScriptAnalyzer and output each linting message as 4 seperate lines
+" for each parsing
+function! ale_linters#powershell#psscriptanalyzer#GetCommand(buffer) abort
+ let l:exclude_option = ale#Var(
+ \ a:buffer, 'powershell_psscriptanalyzer_exclusions')
+ let l:module = ale#Var(
+ \ a:buffer, 'powershell_psscriptanalyzer_module')
+ let l:script = ['Param($Script);
+ \ Invoke-ScriptAnalyzer "$Script" '
+ \ . (!empty(l:exclude_option) ? '-Exclude ' . l:exclude_option : '')
+ \ . '| ForEach-Object {
+ \ $_.Line;
+ \ $_.Severity;
+ \ $_.Message;
+ \ $_.RuleName}']
+
+ return ale_linters#powershell#psscriptanalyzer#RunPowerShell(
+ \ a:buffer, l:script)
+endfunction
+
+" add every 4 lines to an item(Dict) and every item to a list
+" return the list
+function! ale_linters#powershell#psscriptanalyzer#Handle(buffer, lines) abort
+ let l:output = []
+ let l:lcount = 0
+
+ for l:line in a:lines
+ if l:lcount is# 0
+ " the very first line
+ let l:item = {'lnum': str2nr(l:line)}
+ elseif l:lcount is# 1
+ if l:line is# 'Error'
+ let l:item['type'] = 'E'
+ elseif l:line is# 'Information'
+ let l:item['type'] = 'I'
+ else
+ let l:item['type'] = 'W'
+ endif
+ elseif l:lcount is# 2
+ let l:item['text'] = l:line
+ elseif l:lcount is# 3
+ let l:item['code'] = l:line
+ call add(l:output, l:item)
+ let l:lcount = -1
+ endif
+
+ let l:lcount = l:lcount + 1
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('powershell', {
+\ 'name': 'psscriptanalyzer',
+\ 'executable_callback': 'ale_linters#powershell#psscriptanalyzer#GetExecutable',
+\ 'command_callback': 'ale_linters#powershell#psscriptanalyzer#GetCommand',
+\ 'output_stream': 'stdout',
+\ 'callback': 'ale_linters#powershell#psscriptanalyzer#Handle',
+\})
diff --git a/doc/ale-powershell.txt b/doc/ale-powershell.txt
new file mode 100644
index 00000000..743b5ae3
--- /dev/null
+++ b/doc/ale-powershell.txt
@@ -0,0 +1,62 @@
+===============================================================================
+ALE PowerShell Integration *ale-powershell-options*
+
+
+===============================================================================
+psscriptanalyzer *ale-powershell-psscriptanalyzer*
+
+Installation
+-------------------------------------------------------------------------------
+
+Install PSScriptAnalyzer by any means, so long as it can be automatically
+imported in PowerShell.
+Some PowerShell plugins set the filetype of files to `ps1`. To continue using
+these plugins, use the ale_linter_aliases global to alias `ps1` to `powershell`
+
+>
+ " Allow ps1 filetype to work with powershell linters
+ let g:ale_linter_aliases = {'ps1': 'powershell'}
+<
+
+g:ale_powershell_psscriptanalyzer_executable
+*g:ale_powershell_psscriptanalyzer_executable*
+ *b:ale_powershell_psscriptanalyzer_executable*
+ Type: |String|
+ Default: `'pwsh'`
+
+ This variable sets executable used for powershell.
+
+ For example, on Windows you could set powershell to be Windows Powershell:
+>
+ let g:ale_powershell_psscriptanalyzer_executable = 'powershell.exe'
+<
+
+g:ale_powershell_psscriptanalyzer_module
+*g:ale_powershell_psscriptanalyzer_module*
+ *b:ale_powershell_psscriptanalyzer_module*
+ Type: |String
+ Default: `'psscriptanalyzer'`
+
+ This variable sets the name of the psscriptanalyzer module.
+ for psscriptanalyzer invocation.
+
+
+g:ale_powershell_psscriptanalyzer_exclusions
+*g:ale_powershell_psscriptanalyzer_exclusions*
+ *b:ale_powershell_psscriptanalyzer_exclusions*
+ Type: |String|
+ Default: `''`
+
+ Set this variable to exclude test(s) for psscriptanalyzer
+ (-ExcludeRule option). To exclude more than one option, separate them with
+ commas.
+
+>
+ " Suppress Write-Host and Global vars warnings
+ let g:ale_powershell_psscriptanalyzer_exclusions =
+ \ 'PSAvoidUsingWriteHost,PSAvoidGlobalVars'
+<
+
+
+===============================================================================
+ vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt
index 9be28f87..5ca66ace 100644
--- a/doc/ale-supported-languages-and-tools.txt
+++ b/doc/ale-supported-languages-and-tools.txt
@@ -315,6 +315,8 @@ Notes:
* `write-good`
* Pony
* `ponyc`
+* PowerShell
+ * `psscriptanalyzer`
* Prolog
* `swipl`
* proto
diff --git a/doc/ale.txt b/doc/ale.txt
index cc83fdda..0cdb35ab 100644
--- a/doc/ale.txt
+++ b/doc/ale.txt
@@ -275,6 +275,8 @@ ALE supports the following key features for linting:
write-good..........................|ale-pod-write-good|
pony..................................|ale-pony-options|
ponyc...............................|ale-pony-ponyc|
+ powershell............................|ale-powershell-options|
+ psscriptanalyzer....................|ale-powershell-psscriptanalyzer|
prolog................................|ale-prolog-options|
swipl...............................|ale-prolog-swipl|
proto.................................|ale-proto-options|
diff --git a/supported-tools.md b/supported-tools.md
index b540e828..0f60c4ce 100644
--- a/supported-tools.md
+++ b/supported-tools.md
@@ -324,6 +324,8 @@ formatting.
* [write-good](https://github.com/btford/write-good)
* Pony
* [ponyc](https://github.com/ponylang/ponyc)
+* PowerShell
+ * [psscriptanalyzer](https://github.com/PowerShell/PSScriptAnalyzer) :floppy_disk
* Prolog
* [swipl](https://github.com/SWI-Prolog/swipl-devel)
* proto
diff --git a/test/handler/test_psscriptanalyzer_handler.vader b/test/handler/test_psscriptanalyzer_handler.vader
new file mode 100644
index 00000000..060d5941
--- /dev/null
+++ b/test/handler/test_psscriptanalyzer_handler.vader
@@ -0,0 +1,42 @@
+Before:
+ runtime ale_linters/powershell/psscriptanalyzer.vim
+
+After:
+ call ale#linter#Reset()
+
+Execute(The psscriptanalyzer handler should handle basic information or warnings):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 1,
+ \ 'type': 'I',
+ \ 'text': 'The cmdlet ''Get-GithubRepo'' does not have a help comment.',
+ \ 'code': 'PSProvideCommentHelp',
+ \ },
+ \ {
+ \ 'lnum': 9,
+ \ 'type': 'W',
+ \ 'text': '''%'' is an alias of ''ForEach-Object''. Alias can introduce possible problems and make scripts hard to maintain. Please consider changing alias to its full content.',
+ \ 'code': 'PSAvoidUsingCmdletAliases',
+ \ },
+ \ {
+ \ 'lnum': 23,
+ \ 'type': 'E',
+ \ 'text': 'The ComputerName parameter of a cmdlet should not be hardcoded as this will expose sensitive information about the system.',
+ \ 'code': 'PSAvoidUsingComputerNameHardcoded',
+ \ },
+ \ ],
+ \ ale_linters#powershell#psscriptanalyzer#Handle(bufnr(''), [
+ \ '1',
+ \ 'Information',
+ \ 'The cmdlet ''Get-GithubRepo'' does not have a help comment.',
+ \ 'PSProvideCommentHelp',
+ \ '9',
+ \ 'Warning',
+ \ '''%'' is an alias of ''ForEach-Object''. Alias can introduce possible problems and make scripts hard to maintain. Please consider changing alias to its full content.',
+ \ 'PSAvoidUsingCmdletAliases',
+ \ '23',
+ \ 'Error',
+ \ 'The ComputerName parameter of a cmdlet should not be hardcoded as this will expose sensitive information about the system.',
+ \ 'PSAvoidUsingComputerNameHardcoded',
+ \ ])