fix(windows): WT-скрипт использует source вместо commandline для PS7

- Зачем:
  - на машине без pwsh в стандартном PATH профиль с `commandline = 'pwsh.exe'` ломался, потому что WT игнорировал динамический `source` в пользу явного `commandline`.
- Что:
  - PS7 профиль теперь управляется через `source = Windows.Terminal.PowershellCore`, `commandline` удаляется.
  - добавлена проверка `Test-PowerShell7Available`: если pwsh не найден, профиль не создаётся.
  - добавлена `Remove-JsonPropertyValue` для идемпотентного удаления свойств.
  - magic string вынесен в константу `$PowerShellSource`.
- Проверка:
  - `chezmoi -S "$HOME\dotfiles\chezmoi" apply --dry-run --verbose`.
  - `pwsh -NoProfile -Command "(Get-Content (Join-Path $env:LOCALAPPDATA 'Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json') -Raw | ConvertFrom-Json).profiles.list | Where-Object {$_.source -eq 'Windows.Terminal.PowershellCore'} | ConvertTo-Json"`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dmitry DementievandClaude Opus 4.6 committed 2026-03-22 17:41:37 +03:00
1 parent d8768a1642
commit c06ad1ecbb
1 file changed
+50 -20
@@ -9,6 +9,7 @@ if (-not (Test-Path -LiteralPath $settingsPath)) {
}
$PowerShellGuid = '{574e775e-4f2a-5b96-ac1e-a2962a402336}'
$PowerShellSource = 'Windows.Terminal.PowershellCore'
$LegacyPowerShellGuid = '{61c54bbd-c2c6-5271-96e7-009a87ff44bf}'
$changed = $false
@@ -74,6 +75,30 @@ function Set-JsonPropertyValue {
}
}
function Remove-JsonPropertyValue {
param(
[Parameter(Mandatory = $true)]
$Object,
[Parameter(Mandatory = $true)]
[string]$Name
)
$Property = $Object.PSObject.Properties[$Name]
if ($null -ne $Property) {
[void]$Object.PSObject.Properties.Remove($Name)
$script:changed = $true
}
}
function Test-PowerShell7Available {
try {
return $null -ne (Get-Command pwsh -ErrorAction SilentlyContinue | Select-Object -First 1)
}
catch {
return $false
}
}
function Test-IsPowerShell7Profile {
param(
[Parameter(Mandatory = $true)]
@@ -84,7 +109,7 @@ function Test-IsPowerShell7Profile {
$Name = [string](Get-JsonPropertyValue -Object $Profile -Name name)
$CommandLine = [string](Get-JsonPropertyValue -Object $Profile -Name commandline)
if ($Source -eq 'Windows.Terminal.PowershellCore') {
if ($Source -eq $PowerShellSource) {
return $true
}
@@ -108,7 +133,7 @@ function Test-IsDisposablePowerShell7Profile {
return (
$Name -match '^(PowerShell|PowerShell 7)$' -and
(
$Source -eq 'Windows.Terminal.PowershellCore' -or
$Source -eq $PowerShellSource -or
$CommandLine -match '(?i)(^|[\\/ ])pwsh(?:\.exe)?(?:\s|$)'
)
)
@@ -166,7 +191,7 @@ for ($i = 0; $i -lt $profiles.Count; $i++) {
$powerShell7Index = $null
foreach ($candidateIndex in $powerShell7CandidateIndices) {
$candidate = $profiles[$candidateIndex]
if ([string](Get-JsonPropertyValue -Object $candidate -Name source) -eq 'Windows.Terminal.PowershellCore') {
if ([string](Get-JsonPropertyValue -Object $candidate -Name source) -eq $PowerShellSource) {
$powerShell7Index = $candidateIndex
break
}
@@ -177,28 +202,33 @@ if ($null -eq $powerShell7Index -and $powerShell7CandidateIndices.Count -gt 0) {
}
if ($null -eq $powerShell7Index) {
$profiles += [pscustomobject]@{
commandline = 'pwsh.exe'
guid = $PowerShellGuid
hidden = $false
name = 'PowerShell 7'
startingDirectory = '%USERPROFILE%'
if (Test-PowerShell7Available) {
# Create a dynamic-profile override instead of a manual pwsh.exe launcher.
$profiles += [pscustomobject]@{
guid = $PowerShellGuid
hidden = $false
name = 'PowerShell 7'
source = $PowerShellSource
startingDirectory = '%USERPROFILE%'
}
$powerShell7Index = $profiles.Count - 1
$changed = $true
}
else {
Write-Warning 'PowerShell 7 was not detected; leaving Windows Terminal default profile unchanged.'
}
$powerShell7Index = $profiles.Count - 1
$changed = $true
}
$powerShell7Profile = $profiles[$powerShell7Index]
if ([string]::IsNullOrWhiteSpace([string](Get-JsonPropertyValue -Object $powerShell7Profile -Name guid))) {
if ($null -ne $powerShell7Index) {
$powerShell7Profile = $profiles[$powerShell7Index]
Set-JsonPropertyValue -Object $powerShell7Profile -Name guid -Value $PowerShellGuid
Set-JsonPropertyValue -Object $powerShell7Profile -Name source -Value $PowerShellSource
Remove-JsonPropertyValue -Object $powerShell7Profile -Name commandline
Set-JsonPropertyValue -Object $powerShell7Profile -Name name -Value 'PowerShell 7'
Set-JsonPropertyValue -Object $powerShell7Profile -Name hidden -Value $false
Set-JsonPropertyValue -Object $powerShell7Profile -Name startingDirectory -Value '%USERPROFILE%'
Set-JsonPropertyValue -Object $settings -Name defaultProfile -Value ([string](Get-JsonPropertyValue -Object $powerShell7Profile -Name guid))
}
if ($null -eq (Get-JsonPropertyValue -Object $powerShell7Profile -Name commandline) -and [string](Get-JsonPropertyValue -Object $powerShell7Profile -Name source) -ne 'Windows.Terminal.PowershellCore') {
Set-JsonPropertyValue -Object $powerShell7Profile -Name commandline -Value 'pwsh.exe'
}
Set-JsonPropertyValue -Object $powerShell7Profile -Name name -Value 'PowerShell 7'
Set-JsonPropertyValue -Object $powerShell7Profile -Name hidden -Value $false
Set-JsonPropertyValue -Object $powerShell7Profile -Name startingDirectory -Value '%USERPROFILE%'
Set-JsonPropertyValue -Object $settings -Name defaultProfile -Value ([string](Get-JsonPropertyValue -Object $powerShell7Profile -Name guid))
if ($null -ne $legacyPowerShellIndex) {
$legacyPowerShellProfile = $profiles[$legacyPowerShellIndex]