You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Our code formatter (.build/Invoke-CodeFormatterOnFiles.ps1) has no check that flags backtick (`) line continuation in .ps1 / .psm1 files. Backtick continuation is a well-known PowerShell anti-pattern — trailing whitespace after the backtick silently breaks the continuation, and the character is easy to miss in review. Splatting, breaking after a pipe (|), or breaking inside an open paren / brace is preferred in every case.
Neither PSSA (as configured in PSScriptAnalyzerSettings.psd1) nor any of the existing CodeFormatterChecks/ files (CheckContainsCurlyQuotes, CheckFileHasNewlineAtEndOfFile, CheckMarkdownFileHasNoBOM, CheckMultipleEmptyLines, CheckScriptFileHasBOM, CheckScriptFileHasComplianceHeader, CheckScriptFormat, CheckTokenTypeCasing) target backtick continuation. PSAvoidUsingBackticks is not a built-in PSSA rule (it lives in the community CommunityAnalyzerRules module) and is not referenced anywhere in this repo.
Every occurrence in the PR is either a cmdlet call that would be more readable as a splat, or an expression that could break naturally after | / (. Example:
Detection strategy: tokenize with [System.Management.Automation.PSParser]::Tokenize (already used by CheckTokenTypeCasing) and flag any LineContinuation token, OR match the regex `\s*$ on non-blank source lines that are outside here-strings, comments, and string literals (token stream is safer than the regex — regex would produce false positives inside single-line here-strings or ` characters inside strings).
Reporting: each occurrence should be reported with file + 1-based line number so contributors can locate them quickly.
-Save behavior: none. Auto-fixing backticks to splats is not safe (requires choosing splat variable names, deciding on placement), so this check should be report-only and let the author refactor by hand.
Acceptance criteria
CheckBacktickLineContinuation.ps1 exists and is dot-sourced by Invoke-CodeFormatterOnFiles.ps1.
Invoke-CodeFormatterOnFiles calls it for each file and increments $errorCount on hits.
Running against a repro script containing a backtick continuation returns a non-zero error count and prints file + line number.
Backticks inside strings, here-strings (@" ... "@, @' ... '@), and comments do not trigger the check.
Escaped characters that legitimately use backticks in strings ("`t", "`n", "`$var") are not flagged.
-Save is a no-op for this check (auto-rewrite is not attempted).
A follow-up sweep PR (or PRs, if scope requires) removes existing offenders across Admin/, Diagnostics/, Shared/, Transport/, Setup/, and the Tests/ folders.
Non-goals
Auto-fix. Refactoring backtick continuations into splats or natural pipe/paren breaks is an authoring decision, not a formatter transformation.
Blocking backticks in interactive PowerShell examples inside docs/ markdown files.
Adding the CommunityAnalyzerRules module as a formatter dependency.
Summary
Our code formatter (
.build/Invoke-CodeFormatterOnFiles.ps1) has no check that flags backtick (`) line continuation in.ps1/.psm1files. Backtick continuation is a well-known PowerShell anti-pattern — trailing whitespace after the backtick silently breaks the continuation, and the character is easy to miss in review. Splatting, breaking after a pipe (|), or breaking inside an open paren / brace is preferred in every case.Neither PSSA (as configured in
PSScriptAnalyzerSettings.psd1) nor any of the existingCodeFormatterChecks/files (CheckContainsCurlyQuotes,CheckFileHasNewlineAtEndOfFile,CheckMarkdownFileHasNoBOM,CheckMultipleEmptyLines,CheckScriptFileHasBOM,CheckScriptFileHasComplianceHeader,CheckScriptFormat,CheckTokenTypeCasing) target backtick continuation.PSAvoidUsingBackticksis not a built-in PSSA rule (it lives in the communityCommunityAnalyzerRulesmodule) and is not referenced anywhere in this repo.Evidence
Discovered while reviewing PR #2571.
Transport/Get-TerrlExternalRecipientEstimate.ps1— 9 backtick continuations (lines 316–319, 830–833, 879).Transport/Tests/Get-TerrlExternalRecipientEstimate.Tests.ps1— 39 backtick continuations.Every occurrence in the PR is either a cmdlet call that would be more readable as a splat, or an expression that could break naturally after
|/(. Example:Proposed change
Add a new
CheckBacktickLineContinuation.ps1under.build/CodeFormatterChecks/and wire it into.build/Invoke-CodeFormatterOnFiles.ps1:Detection strategy: tokenize with
[System.Management.Automation.PSParser]::Tokenize(already used byCheckTokenTypeCasing) and flag anyLineContinuationtoken, OR match the regex`\s*$on non-blank source lines that are outside here-strings, comments, and string literals (token stream is safer than the regex — regex would produce false positives inside single-line here-strings or`characters inside strings).Reporting: each occurrence should be reported with file + 1-based line number so contributors can locate them quickly.
-Savebehavior: none. Auto-fixing backticks to splats is not safe (requires choosing splat variable names, deciding on placement), so this check should be report-only and let the author refactor by hand.Acceptance criteria
CheckBacktickLineContinuation.ps1exists and is dot-sourced byInvoke-CodeFormatterOnFiles.ps1.Invoke-CodeFormatterOnFilescalls it for each file and increments$errorCounton hits.@" ... "@,@' ... '@), and comments do not trigger the check."`t","`n","`$var") are not flagged.-Saveis a no-op for this check (auto-rewrite is not attempted).Admin/,Diagnostics/,Shared/,Transport/,Setup/, and theTests/folders.Non-goals
docs/markdown files.CommunityAnalyzerRulesmodule as a formatter dependency.Repro
Related