PSScriptAnalyzer icon indicating copy to clipboard operation
PSScriptAnalyzer copied to clipboard

Indentation inconsistent when using more than 1 line continuation

Open studoot opened this issue 5 years ago • 4 comments

Before submitting a bug report:

  • Make sure you are able to repro it on the latest released version
  • Perform a quick search for existing issues to check if this bug has already been reported

Steps to reproduce

Execute the following script & compare the formatted output to the input (as defined by the variable $scriptDefinition)

$scriptDefinition = @'
$all_links = `
    [array](Get-ChildItem -Path ([Environment]::GetFolderPath('StartMenu')) -Recurse -Include '*.lnk') + `
    (Get-ChildItem -Path ([Environment]::GetFolderPath('CommonStartMenu')) -Recurse -Include '*.lnk')
'@

Invoke-Formatter -ScriptDefinition $scriptDefinition

Expected behavior

The output of the call to Invoke-Formatter should be the same as the input.

Actual behavior

The third line of the output is not indented to the same level as the second line - the output of Invoke-Formatter is as shown below.

$all_links = `
    [array](Get-ChildItem -Path ([Environment]::GetFolderPath('StartMenu')) -Recurse -Include '*.lnk') + `
(Get-ChildItem -Path ([Environment]::GetFolderPath('CommonStartMenu')) -Recurse -Include '*.lnk')

Environment data

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      5.1.18356.1
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.18356.1
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
> (Get-Module -ListAvailable PSScriptAnalyzer).Version | ForEach-Object { $_.ToString() }
1.18.0

studoot avatar Mar 22 '19 14:03 studoot

  • I disagree with your expected behaviour paragraph where you state that The output of the call to Invoke-Formatter should be the same as the input. in general because the output of Invoke-Formatter is the corrected version. In theory, I'd expect though that the result of Invoke-Formatter (Invoke-Formatter $scriptDefinition) should be the same as Invoke-Formatter $scriptDefinition although I have seen scenarios where one needs to format twice to get to the desired final state (which can happen when there are violations on the same AST element and is something very tricky to fix)
  • I agree though that for your case, that one could tweak the UseConsistentIndentation rule to have consistent newline indentation for the 2nd and 3rd line, one probably would need a configuration option to either have just one or no level of indentation on consecutive lines.
  • Behaviour for this case has not changed between 1.17.1 and 1.18.0, therefore this is rather something that one could tweak for the next release, we'd be happy if you open a PR for it.

bergmeister avatar Mar 22 '19 16:03 bergmeister

FYI, the use of backticks in the example are totally unnecessary If one removes the backticks, all lines will lose their indention.

The second line's backtick fails to cause the expected indention.

Technically even without the backticks, the lines should indent as expected, because they are in fact continued.

msftrncs avatar May 06 '19 22:05 msftrncs

I have similar but different problem related to this.

Here is example line which is now put as I want: (yes it's a single command line)

Set-NetFirewallProfile -Name Domain -PolicyStore $PolicyStore `
-Enabled NotConfigured -DefaultInboundAction NotConfigured -DefaultOutboundAction NotConfigured -AllowInboundRules NotConfigured `
-AllowLocalFirewallRules NotConfigured -AllowLocalIPsecRules NotConfigured -AllowUnicastResponseToMulticast NotConfigured `
-NotifyOnListen NotConfigured -EnableStealthModeForIPsec NotConfigured `
-LogAllowed NotConfigured -LogBlocked NotConfigured -LogIgnored NotConfigured -LogMaxSizeKilobytes 4096 `
-AllowUserApps NotConfigured -AllowUserPorts NotConfigured `
-LogFileName "%SystemRoot%\System32\LogFiles\Firewall\pfirewall.log" @Logs

Here is the setting I have in my PSScriptAnalyzerSettings.psd1 file:

		PSUseConsistentIndentation = @{
			Enable = $false
			Kind = 'tab'
			PipelineIndentation = 'NoIndentation' 
			IndentationSize = 4
		}

As you can see I have disabled the setting because it will tell me my indentation is not consistent.

So far so good to get rid of warnings, but another problem is that when I right click into a file and select "format document" it will indent consecutive lines in above example which is something I do not want, and I have no clue how to prevent indenting the consecutive lines in above example?

What should I configure to keep the line as it is when right-click -> format document? and how to prevent warnings about non consistent indentation? I would like to have the setting on for other cases.

metablaster avatar Feb 29 '20 20:02 metablaster

I think this is related to this issue. The code below is based on actual code, but simplified as much as possible.

        'PSUseConsistentIndentation'                     = @{
            'Enable'              = $true
            'IndentationSize'     = 4
            'PipelineIndentation' = 'IncreaseIndentationForFirstPipeline'
            'Kind'                = 'space'
        }

Expected behavior

No PSUseConsistentIndentation issues:

image

Actual behavior

Two PSUseConsistentIndentation issues:

image

If I format the document. The last two lines are incorrectly indented:

image

Environment data

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.1.0
PSEdition                      Core
GitCommitId                    7.1.0
OS                             Microsoft Windows 10.0.19042
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

(Get-Module -ListAvailable PSScriptAnalyzer).Version | ForEach-Object { $_.ToString() }

Directory: C:\Users<removed>\Documents\PowerShell\Modules: 1.19.1 1.18.3 1.18.2 1.18.1 1.18.0

Directory: C:\Users<removed>.vscode\extensions\ms-vscode.powershell-preview-2020.9.0\modules: 1.19.1

mrboring avatar Dec 07 '20 10:12 mrboring