Files
kompas3d-mcp/tools/dev/rebuild-mcp.ps1
T
mikhail dfe5636290 Dev-скрипт сборки: .Count падал на единственном держателе bin
Get-BlockingProcess возвращает скаляр, когда bin занят ровно одним процессом
MCP, и .Count под Set-StrictMode роняет скрипт вместо диагностики. Та же
ловушка, что описана для лаунчера, — теперь результат заворачивается в @().
2026-07-31 14:50:38 +03:00

105 lines
5.6 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#requires -Version 7.0
<#
.SYNOPSIS
Сборка MCP-сервера для dev-цикла: с диагностикой блокировки bin живыми сессиями.
.DESCRIPTION
Три режима, по возрастанию стоимости:
-Check компиляция мимо bin (сервер можно не останавливать) — «оно вообще собирается?»
(по умолчанию) полная сборка в bin + юнит-тесты — новый бинарь для теневого запуска
-NoTest то же без юнит-тестов
Каталог bin занят, пока хотя бы одна сессия MCP запущена ПРЯМО из него (см. .mcp.json).
С tools/dev/launch-dev-mcp.ps1 сервер работает из теневой копии, и bin свободен всегда.
.EXAMPLE
pwsh -NoProfile -File tools/dev/rebuild-mcp.ps1 -Check
.EXAMPLE
pwsh -NoProfile -File tools/dev/rebuild-mcp.ps1
#>
[CmdletBinding()]
param(
[switch] $Check,
[switch] $NoTest
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
$binDir = Join-Path $repo 'src\Kompas.Mcp.Host\bin\x64\Release\net8.0-windows'
function Get-BlockingProcess {
param([Parameter(Mandatory)] [string] $Directory)
$target = $Directory.TrimEnd('\').ToLowerInvariant()
$found = @()
foreach ($p in (Get-Process -Name 'kompas-mcp' -ErrorAction SilentlyContinue)) {
try {
if (-not $p.Path) { continue }
if ((Split-Path -Parent $p.Path).TrimEnd('\').ToLowerInvariant() -eq $target) { $found += $p }
}
catch {
# .Path недоступен (чужой пользователь / процесс уже умер) — считать такой
# процесс блокирующим нельзя, но и молчать нехорошо: сборка ниже всё равно
# покажет настоящего держателя файла в тексте MSB3027.
Write-Verbose "не удалось прочитать путь процесса $($p.Id): $($_.Exception.Message)"
}
}
return $found
}
if ($Check) {
# Стабильный (не случайный) каталог — чтобы работала инкрементальная сборка.
# Перенаправляем ТОЛЬКО BaseOutputPath: если увести ещё и BaseIntermediateOutputPath,
# старый obj\ в дереве остаётся видимым для glob'а и даёт CS0579 «Повторяющийся
# атрибут» на сгенерированном AssemblyInfo. Обратная сторона — obj\ остаётся общим
# с обычной сборкой, поэтому два параллельных прогона топчут инкрементальный кэш
# друг друга (безопасно, но лишняя перекомпиляция).
$stamp = [System.BitConverter]::ToString(
[System.Security.Cryptography.SHA256]::HashData(
[System.Text.Encoding]::UTF8.GetBytes($repo.ToLowerInvariant()))[0..3]).Replace('-', '')
$out = Join-Path ([System.IO.Path]::GetTempPath()) "kompas-mcp-check\$stamp\"
Write-Host "Проверка компиляции (bin не трогаем, выход → $out)" -ForegroundColor Cyan
dotnet build -c Release -p:BaseOutputPath=$out
exit $LASTEXITCODE
}
# @() обязательно: единственный найденный процесс вернулся бы скаляром, и .Count под
# Set-StrictMode падает — та же ловушка, что в лаунчере с Get-ChildItem.
$blocking = @(Get-BlockingProcess -Directory $binDir)
if ($blocking.Count -gt 0) {
Write-Host 'Сборка невозможна: bin занят живыми сессиями MCP.' -ForegroundColor Red
foreach ($p in $blocking) {
Write-Host (" PID {0}, запущен {1}" -f $p.Id, $p.StartTime.ToString('HH:mm:ss'))
}
Write-Host ''
Write-Host 'Варианты:' -ForegroundColor Yellow
Write-Host ' 1. Перевести .mcp.json на tools/dev/launch-dev-mcp.ps1 (теневой запуск) — тогда'
Write-Host ' bin свободен всегда, и эта ситуация больше не повторится.'
Write-Host ' 2. Закрыть все сессии Claude Code с этим MCP и повторить.'
Write-Host ' 3. Разовая проверка компиляции без остановки сервера: -Check'
exit 2
}
Write-Host 'Сборка (Release)…' -ForegroundColor Cyan
dotnet build -c Release
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
if (-not $NoTest) {
Write-Host 'Юнит-тесты…' -ForegroundColor Cyan
dotnet test --filter 'Category=Unit' --nologo
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
Import-Module (Join-Path $PSScriptRoot 'KompasMcpDev.psm1') -Force
$fp = Get-KompasMcpBuildFingerprint -Directory $binDir
Write-Host ''
Write-Host "Готово. Отпечаток сборки: $fp" -ForegroundColor Green
Write-Host 'Сервер подхватит её при следующем запуске процесса MCP:'
Write-Host ' /mcp → переподключить kompas (если клиент умеет), иначе — перезапуск сессии.'
Write-Host 'После переподключения: kompas_status покажет живое соединение; эскизы по id теряются.'