From 337acb808d058ce35e440d64a3470a389f303b52 Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Thu, 29 Dec 2016 16:35:20 -0700 Subject: [PATCH 1/3] Add VSCode settings.json file. The settings file specifies trimTrailingWhitespace which is good for PowerShell scripts. Also specifies a path to a PSScriptAnalyzerSettings file. VSCode with the PowerShell extension will automatically lint the PowerShell scripts to find potential issues. I also took a whach at elminating some of the easy warnings to fix - like replacing aliases with full command names. --- .vscode/settings.json | 4 ++ GitPrompt.ps1 | 10 ++++- GitTabExpansion.ps1 | 80 +++++++++++++++++++---------------- PSScriptAnalyzerSettings.psd1 | 32 ++++++++++++++ Utils.ps1 | 2 +- 5 files changed, 88 insertions(+), 40 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 PSScriptAnalyzerSettings.psd1 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..9a1090086 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "files.trimTrailingWhitespace": true, + "powershell.scriptAnalysis.settingsPath": "PSScriptAnalyzerSettings.psd1" +} \ No newline at end of file diff --git a/GitPrompt.ps1 b/GitPrompt.ps1 index 97b2843a0..8579a1ef2 100644 --- a/GitPrompt.ps1 +++ b/GitPrompt.ps1 @@ -270,12 +270,18 @@ if ($Host.UI.RawUI.BackgroundColor -eq [ConsoleColor]::DarkMagenta) { $s.WorkingForegroundColor = $s.WorkingForegroundBrightColor } -function Global:Write-VcsStatus { $Global:VcsPromptStatuses | foreach { & $_ } } +function Global:Write-VcsStatus { + $Global:VcsPromptStatuses | ForEach-Object { & $_ } +} # Add scriptblock that will execute for Write-VcsStatus $PoshGitVcsPrompt = { $Global:GitStatus = Get-GitStatus Write-GitStatus $GitStatus } + +# Install handler for removal/unload of the module $Global:VcsPromptStatuses += $PoshGitVcsPrompt -$ExecutionContext.SessionState.Module.OnRemove = { $Global:VcsPromptStatuses = $Global:VcsPromptStatuses | ? { $_ -ne $PoshGitVcsPrompt} } +$ExecutionContext.SessionState.Module.OnRemove = { + $Global:VcsPromptStatuses = $Global:VcsPromptStatuses | Where-Object { $_ -ne $PoshGitVcsPrompt } +} diff --git a/GitTabExpansion.ps1 b/GitTabExpansion.ps1 index c163b91dc..550ee674e 100644 --- a/GitTabExpansion.ps1 +++ b/GitTabExpansion.ps1 @@ -25,17 +25,22 @@ $gitflowsubcommands = @{ function script:gitCmdOperations($commands, $command, $filter) { $commands.$command -split ' ' | - where { $_ -like "$filter*" } + Where-Object { $_ -like "$filter*" } } -$script:someCommands = @('add','am','annotate','archive','bisect','blame','branch','bundle','checkout','cherry','cherry-pick','citool','clean','clone','commit','config','describe','diff','difftool','fetch','format-patch','gc','grep','gui','help','init','instaweb','log','merge','mergetool','mv','notes','prune','pull','push','rebase','reflog','remote','rerere','reset','revert','rm','shortlog','show','stash','status','submodule','svn','tag','whatchanged') +$script:someCommands = @('add','am','annotate','archive','bisect','blame','branch','bundle','checkout','cherry', + 'cherry-pick','citool','clean','clone','commit','config','describe','diff','difftool','fetch', + 'format-patch','gc','grep','gui','help','init','instaweb','log','merge','mergetool','mv', + 'notes','prune','pull','push','rebase','reflog','remote','rerere','reset','revert','rm', + 'shortlog','show','stash','status','submodule','svn','tag','whatchanged') try { - if ((git help -a 2>&1 | Select-String flow) -ne $null) { + if ($null -ne (git help -a 2>&1 | Select-String flow)) { $script:someCommands += 'flow' } } catch { + Write-Debug "Search for 'flow' in 'git help' output failed with error: $_" } function script:gitCommands($filter, $includeAliases) { @@ -44,20 +49,20 @@ function script:gitCommands($filter, $includeAliases) { $cmdList += $someCommands -like "$filter*" } else { $cmdList += git help --all | - where { $_ -match '^ \S.*' } | - foreach { $_.Split(' ', [StringSplitOptions]::RemoveEmptyEntries) } | - where { $_ -like "$filter*" } + Where-Object { $_ -match '^ \S.*' } | + ForEach-Object { $_.Split(' ', [StringSplitOptions]::RemoveEmptyEntries) } | + Where-Object { $_ -like "$filter*" } } if ($includeAliases) { $cmdList += gitAliases $filter } - $cmdList | sort + $cmdList | Sort-Object } function script:gitRemotes($filter) { git remote | - where { $_ -like "$filter*" } + Where-Object { $_ -like "$filter*" } } function script:gitBranches($filter, $includeHEAD = $false) { @@ -66,49 +71,49 @@ function script:gitBranches($filter, $includeHEAD = $false) { $prefix = $matches['from'] $filter = $matches['to'] } - $branches = @(git branch --no-color | foreach { if($_ -match "^\*?\s*(?.*)") { $matches['ref'] } }) + - @(git branch --no-color -r | foreach { if($_ -match "^ (?\S+)(?: -> .+)?") { $matches['ref'] } }) + + $branches = @(git branch --no-color | ForEach-Object { if($_ -match "^\*?\s*(?.*)") { $matches['ref'] } }) + + @(git branch --no-color -r | ForEach-Object { if($_ -match "^ (?\S+)(?: -> .+)?") { $matches['ref'] } }) + @(if ($includeHEAD) { 'HEAD','FETCH_HEAD','ORIG_HEAD','MERGE_HEAD' }) $branches | - where { $_ -ne '(no branch)' -and $_ -like "$filter*" } | - foreach { $prefix + $_ } + Where-Object { $_ -ne '(no branch)' -and $_ -like "$filter*" } | + ForEach-Object { $prefix + $_ } } function script:gitTags($filter) { git tag | - where { $_ -like "$filter*" } + Where-Object { $_ -like "$filter*" } } function script:gitFeatures($filter, $command){ $featurePrefix = git config --local --get "gitflow.prefix.$command" - $branches = @(git branch --no-color | foreach { if($_ -match "^\*?\s*$featurePrefix(?.*)") { $matches['ref'] } }) + $branches = @(git branch --no-color | ForEach-Object { if($_ -match "^\*?\s*$featurePrefix(?.*)") { $matches['ref'] } }) $branches | - where { $_ -ne '(no branch)' -and $_ -like "$filter*" } | - foreach { $prefix + $_ } + Where-Object { $_ -ne '(no branch)' -and $_ -like "$filter*" } | + ForEach-Object { $prefix + $_ } } function script:gitRemoteBranches($remote, $ref, $filter) { git branch --no-color -r | - where { $_ -like " $remote/$filter*" } | - foreach { $ref + ($_ -replace " $remote/","") } + Where-Object { $_ -like " $remote/$filter*" } | + ForEach-Object { $ref + ($_ -replace " $remote/","") } } function script:gitStashes($filter) { (git stash list) -replace ':.*','' | - where { $_ -like "$filter*" } | - foreach { "'$_'" } + Where-Object { $_ -like "$filter*" } | + ForEach-Object { "'$_'" } } function script:gitTfsShelvesets($filter) { (git tfs shelve-list) | - where { $_ -like "$filter*" } | - foreach { "'$_'" } + Where-Object { $_ -like "$filter*" } | + ForEach-Object { "'$_'" } } function script:gitFiles($filter, $files) { - $files | sort | - where { $_ -like "$filter*" } | - foreach { if($_ -like '* *') { "'$_'" } else { $_ } } + $files | Sort-Object | + Where-Object { $_ -like "$filter*" } | + ForEach-Object { if($_ -like '* *') { "'$_'" } else { $_ } } } function script:gitIndex($filter) { @@ -126,7 +131,8 @@ function script:gitCheckoutFiles($filter) { function script:gitDiffFiles($filter, $staged) { if ($staged) { gitFiles $filter $GitStatus.Index.Modified - } else { + } + else { gitFiles $filter (@($GitStatus.Working.Unmerged) + @($GitStatus.Working.Modified) + @($GitStatus.Index.Modified)) } } @@ -140,38 +146,39 @@ function script:gitDeleted($filter) { } function script:gitAliases($filter) { - git config --get-regexp ^alias\. | foreach { + git config --get-regexp ^alias\. | ForEach-Object{ if($_ -match "^alias\.(?\S+) .*") { $alias = $Matches['alias'] if($alias -like "$filter*") { $alias } } - } | Sort + } | Sort-Object } function script:expandGitAlias($cmd, $rest) { - if((git config --get-regexp "^alias\.$cmd`$") -match "^alias\.$cmd (?[^!].*)`$") { + if ((git config --get-regexp "^alias\.$cmd`$") -match "^alias\.$cmd (?[^!].*)`$") { return "git $($Matches['cmd'])$rest" - } else { + } + else { return "git $cmd$rest" } } function GitTabExpansion($lastBlock) { - if($lastBlock -match "^$(Get-AliasPattern git) (?\S+)(? .*)$") { + if ($lastBlock -match "^$(Get-AliasPattern git) (?\S+)(? .*)$") { $lastBlock = expandGitAlias $Matches['cmd'] $Matches['args'] } # Handles tgit (tortoisegit) - if($lastBlock -match "^$(Get-AliasPattern tgit) (?\S*)$") { - # Need return statement to prevent fall-through. - return $tortoiseGitCommands | where { $_ -like "$($matches['cmd'])*" } + if ($lastBlock -match "^$(Get-AliasPattern tgit) (?\S*)$") { + # Need return statement to prevent fall-through. + return $tortoiseGitCommands | Where-Object { $_ -like "$($matches['cmd'])*" } } # Handles gitk - if($lastBlock -match "^$(Get-AliasPattern gitk).* (?\S*)$"){ + if ($lastBlock -match "^$(Get-AliasPattern gitk).* (?\S*)$"){ return gitBranches $matches['ref'] $true } @@ -293,8 +300,7 @@ function GitTabExpansion($lastBlock) { } $PowerTab_RegisterTabExpansion = if (Get-Module -Name powertab) { Get-Command Register-TabExpansion -Module powertab -ErrorAction SilentlyContinue } -if ($PowerTab_RegisterTabExpansion) -{ +if ($PowerTab_RegisterTabExpansion) { & $PowerTab_RegisterTabExpansion "git.exe" -Type Command { param($Context, [ref]$TabExpansionHasOutput, [ref]$QuoteSpaces) # 1: diff --git a/PSScriptAnalyzerSettings.psd1 b/PSScriptAnalyzerSettings.psd1 new file mode 100644 index 000000000..caa200069 --- /dev/null +++ b/PSScriptAnalyzerSettings.psd1 @@ -0,0 +1,32 @@ +@{ + # Use Severity when you want to limit the generated diagnostic records to a + # subset of: Error, Warning and Information. + # Uncomment the following line if you only want Errors and Warnings but + # not Information diagnostic records. + Severity = @('Error','Warning') + + # Use IncludeRules when you want to run only a subset of the default rule set. + #IncludeRules = @('PSAvoidDefaultValueSwitchParameter', + # 'PSMissingModuleManifestField', + # 'PSReservedCmdletChar', + # 'PSReservedParams', + # 'PSShouldProcess', + # 'PSUseApprovedVerbs', + # 'PSUseDeclaredVarsMoreThanAssigments') + + # Use ExcludeRules when you want to run most of the default set of rules except + # for a few rules you wish to "exclude". Note: if a rule is in both IncludeRules + # and ExcludeRules, the rule will be excluded. + ExcludeRules = @('PSAvoidUsingWriteHost', 'PSAvoidGlobalVars') + + # You can use the following entry to supply parameters to rules that take parameters. + # For instance, the PSAvoidUsingCmdletAliases rule takes a whitelist for aliases you + # want to allow. + Rules = @{ + # Do not flag 'cd' alias. + # PSAvoidUsingCmdletAliases = @{Whitelist = @('cd')} + + # Check if your script uses cmdlets that are compatible on PowerShell Core, version 6.0.0-alpha, on Linux. + # PSUseCompatibleCmdlets = @{Compatibility = @("core-6.0.0-alpha-linux")} + } +} diff --git a/Utils.ps1 b/Utils.ps1 index b1aceb549..a6a43086e 100644 --- a/Utils.ps1 +++ b/Utils.ps1 @@ -20,7 +20,7 @@ function Get-LocalOrParentPath($path) { if ($checkIn.PSProvider.Name -ne 'FileSystem') { return $null } - while ($checkIn -ne $NULL) { + while ($null -ne $checkIn) { $pathToTest = [System.IO.Path]::Combine($checkIn.fullname, $path) if (Test-Path -LiteralPath $pathToTest) { return $pathToTest From 8e9d8fb35a98c79d24624edcde8afb740bd26b8e Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Thu, 29 Dec 2016 18:08:12 -0700 Subject: [PATCH 2/3] Add blank line at end of file. --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9a1090086..34313e0e0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,4 @@ { "files.trimTrailingWhitespace": true, "powershell.scriptAnalysis.settingsPath": "PSScriptAnalyzerSettings.psd1" -} \ No newline at end of file +} From 8df498a6bd502d78bcba5eeeb53ce3ae5315690a Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Thu, 29 Dec 2016 18:13:27 -0700 Subject: [PATCH 3/3] Add insertFinalNewLine VSCode setting And a few more helpful ones as well. --- .vscode/settings.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index 34313e0e0..26ad2bff6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,8 @@ { + "editor.insertSpaces": true, + "editor.tabSize": 4, + "editor.rulers": [ 120 ], "files.trimTrailingWhitespace": true, + "files.insertFinalNewline": true, "powershell.scriptAnalysis.settingsPath": "PSScriptAnalyzerSettings.psd1" }