Add build and run scripts; drop the broken Avalonia.Diagnostics reference
A wrapper around `dotnet build` earns nothing, so build.ps1/build.sh are the full local gate instead — tool restore, package restore, format check, build, test — in the order that fails cheapest first, with a non-zero exit on failure. run.ps1/run.sh default to Debug and pass extra arguments through to the app. Both flavours ship because the Desktop head targets Windows, Linux and macOS. Writing them immediately paid for itself: the very first run failed restore on Avalonia.Diagnostics 12.1.1, which does not exist — the package stops at 11.3.x because Avalonia 12 moved the inspector into a separate tool with its own installation. The reference had survived because it sat behind Condition="'$(Configuration)' == 'Debug'", and `dotnet restore` evaluates with the default configuration while every build so far had passed -c Release. So `dotnet build -c Release` worked and a bare `dotnet restore` did not. Reference removed rather than replaced: AvaloniaUI.DiagnosticsSupport pulls in a separately installed tool, which is not a dependency to add to a skeleton without asking. README and CLAUDE.md no longer promise F12, and both traps are written down where the next person will hit them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3db9d4dfc6
commit
aeafe0af36
@@ -1,5 +1,9 @@
|
||||
<Solution>
|
||||
<Folder Name="/Solution Items/">
|
||||
<File Path="build.ps1" />
|
||||
<File Path="build.sh" />
|
||||
<File Path="run.ps1" />
|
||||
<File Path="run.sh" />
|
||||
<File Path=".editorconfig" />
|
||||
<File Path=".gitattributes" />
|
||||
<File Path=".gitignore" />
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
|
||||
## Команды
|
||||
|
||||
Полный локальный гейт (формат → сборка → тесты) — то, что нужно прогнать перед коммитом:
|
||||
|
||||
```bash
|
||||
./build.ps1
|
||||
```
|
||||
|
||||
Отдельные шаги, если нужен только один из них:
|
||||
|
||||
```bash
|
||||
dotnet build AvParser.slnx -c Release
|
||||
```
|
||||
@@ -14,9 +22,11 @@ dotnet test AvParser.slnx -c Release
|
||||
dotnet csharpier check .
|
||||
```
|
||||
```bash
|
||||
dotnet run --project src/AvParser.Desktop
|
||||
./run.ps1
|
||||
```
|
||||
|
||||
На Linux/macOS — `./build.sh` и `./run.sh` с теми же шагами.
|
||||
|
||||
## Слои
|
||||
|
||||
`Core ← Infrastructure ← UI ← Desktop`, строго в одну сторону.
|
||||
@@ -95,6 +105,14 @@ dotnet run --project src/AvParser.Desktop
|
||||
открепленного контрола не строится визуальное дерево.
|
||||
- **csharpier — единственный владелец форматирования** (включая `.axaml` и `.csproj`).
|
||||
`IDE0055` понижен до suggestion: два форматтера с `TreatWarningsAsErrors` дерутся насмерть.
|
||||
- **`Condition="'$(Configuration)' == 'Debug'"` на `PackageReference` — ловушка.**
|
||||
`dotnet restore` вычисляется с конфигурацией по умолчанию, поэтому пакет обязан
|
||||
резолвиться, даже если эту конфигурацию никто не собирает. Так тут проехал мёртвый
|
||||
`Avalonia.Diagnostics` (его нет под Avalonia 12): `dotnet build -c Release` работал,
|
||||
а голый `dotnet restore` падал.
|
||||
- **Инспектора в Avalonia 12 нет из коробки.** `Avalonia.Diagnostics` закончился на 11.3.x;
|
||||
DevTools живут отдельно (`AvaloniaUI.DiagnosticsSupport` + `.WithDeveloperTools()`), со своей
|
||||
установкой. Зависимость намеренно не добавлена.
|
||||
|
||||
## Качество
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
<ItemGroup Label="Avalonia">
|
||||
<PackageVersion Include="Avalonia" Version="$(AvaloniaVersion)" />
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="$(AvaloniaVersion)" />
|
||||
<PackageVersion Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)" />
|
||||
<PackageVersion Include="Avalonia.Fonts.Inter" Version="$(AvaloniaVersion)" />
|
||||
<PackageVersion Include="Avalonia.Headless" Version="$(AvaloniaVersion)" />
|
||||
<PackageVersion Include="Avalonia.Headless.XUnit" Version="$(AvaloniaVersion)" />
|
||||
|
||||
@@ -13,9 +13,31 @@ end-to-end до появления настоящей логики.
|
||||
|
||||
Нужен .NET SDK **10.0.100** (закреплён в `global.json`).
|
||||
|
||||
Полный локальный гейт — восстановление, проверка форматирования, сборка, тесты:
|
||||
|
||||
```bash
|
||||
dotnet restore AvParser.slnx
|
||||
./build.ps1
|
||||
```
|
||||
|
||||
Запуск приложения (по умолчанию Debug):
|
||||
|
||||
```bash
|
||||
./run.ps1
|
||||
```
|
||||
|
||||
На Linux и macOS — `./build.sh` и `./run.sh`, аргументы те же.
|
||||
|
||||
Полезные флаги:
|
||||
|
||||
```bash
|
||||
./build.ps1 -Fix -Configuration Debug
|
||||
```
|
||||
|
||||
`-Fix` переформатирует код вместо того, чтобы падать на непрошедшей проверке; `-SkipTests`
|
||||
собирает без прогона тестов. То же в bash: `--fix`, `-c Debug`, `--skip-tests`.
|
||||
|
||||
Если нужны отдельные шаги, скрипты ничего не прячут:
|
||||
|
||||
```bash
|
||||
dotnet build AvParser.slnx -c Release
|
||||
```
|
||||
@@ -23,13 +45,7 @@ dotnet build AvParser.slnx -c Release
|
||||
dotnet test AvParser.slnx -c Release
|
||||
```
|
||||
```bash
|
||||
dotnet run --project src/AvParser.Desktop
|
||||
```
|
||||
|
||||
Форматирование (csharpier — единственный владелец форматирования, включая `.axaml` и `.csproj`):
|
||||
|
||||
```bash
|
||||
dotnet tool restore && dotnet csharpier check .
|
||||
dotnet csharpier check .
|
||||
```
|
||||
|
||||
---
|
||||
@@ -117,7 +133,9 @@ Semi.Avalonia даёт темы контролов; токены — это се
|
||||
2. Переключить тему кнопкой в заголовке и в Settings; перезапустить — выбор сохранился.
|
||||
3. На странице Parse нажать **50k rows**, затем **Parse** — виден прогресс; **Cancel**
|
||||
останавливает на середине и пишет, сколько успело разобраться.
|
||||
4. `F12` в Debug-сборке открывает Avalonia DevTools — там видно, как переключаются
|
||||
`:compact` / `:medium` / `:expanded`.
|
||||
В Avalonia 12 инспектора «из коробки» больше нет: `Avalonia.Diagnostics` остановился на 11.3.x,
|
||||
а DevTools вынесли в отдельный инструмент со своей установкой
|
||||
(`AvaloniaUI.DiagnosticsSupport` + `.WithDeveloperTools()`). Поэтому `F12` здесь ничего не
|
||||
открывает — зависимость намеренно не добавлена.
|
||||
|
||||
Настройки и логи лежат в `%APPDATA%/AvParser` (Windows) или `~/.config/AvParser` (Linux/macOS).
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Полный локальный гейт: формат, сборка, тесты.
|
||||
|
||||
.DESCRIPTION
|
||||
То, что имеет смысл прогнать перед коммитом. Обёртка вокруг `dotnet build` сама по себе
|
||||
бесполезна — ценность здесь в том, что шаги идут в правильном порядке, падают быстро и
|
||||
возвращают ненулевой код возврата.
|
||||
|
||||
.PARAMETER Configuration
|
||||
Debug или Release. По умолчанию Release — гейт должен проверять то, что уедет.
|
||||
|
||||
.PARAMETER Fix
|
||||
Переформатировать код вместо проверки. Без этого флага несформатированный код валит сборку.
|
||||
|
||||
.PARAMETER SkipFormat
|
||||
Пропустить проверку форматирования.
|
||||
|
||||
.PARAMETER SkipTests
|
||||
Только собрать, не запускать тесты.
|
||||
|
||||
.EXAMPLE
|
||||
./build.ps1
|
||||
Формат, сборка и тесты в Release.
|
||||
|
||||
.EXAMPLE
|
||||
./build.ps1 -Fix
|
||||
Переформатировать код, затем собрать и прогнать тесты.
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateSet('Debug', 'Release')]
|
||||
[string] $Configuration = 'Release',
|
||||
|
||||
[switch] $Fix,
|
||||
[switch] $SkipFormat,
|
||||
[switch] $SkipTests
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Set-Location $PSScriptRoot
|
||||
|
||||
$solution = 'AvParser.slnx'
|
||||
$started = Get-Date
|
||||
|
||||
function Invoke-Step {
|
||||
param(
|
||||
[Parameter(Mandatory)] [string] $Name,
|
||||
[Parameter(Mandatory)] [scriptblock] $Action
|
||||
)
|
||||
|
||||
Write-Host ''
|
||||
Write-Host "==> $Name" -ForegroundColor Cyan
|
||||
|
||||
& $Action
|
||||
|
||||
# Native executables do not raise terminating errors, so the exit code is the only signal.
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "$Name — код возврата $LASTEXITCODE"
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Invoke-Step 'Локальные инструменты' { dotnet tool restore }
|
||||
|
||||
Invoke-Step 'Восстановление пакетов' { dotnet restore $solution }
|
||||
|
||||
if (-not $SkipFormat) {
|
||||
if ($Fix) {
|
||||
Invoke-Step 'Форматирование (csharpier format)' { dotnet csharpier format . }
|
||||
}
|
||||
else {
|
||||
# Before the build: an unformatted file is the cheapest possible failure.
|
||||
Invoke-Step 'Проверка форматирования (csharpier check)' { dotnet csharpier check . }
|
||||
}
|
||||
}
|
||||
|
||||
Invoke-Step "Сборка ($Configuration)" {
|
||||
dotnet build $solution -c $Configuration --no-restore --nologo
|
||||
}
|
||||
|
||||
if (-not $SkipTests) {
|
||||
Invoke-Step 'Тесты' {
|
||||
dotnet test $solution -c $Configuration --no-build --nologo
|
||||
}
|
||||
}
|
||||
|
||||
$elapsed = (Get-Date) - $started
|
||||
Write-Host ''
|
||||
Write-Host ("OK — {0:mm\:ss}" -f $elapsed) -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Host ''
|
||||
Write-Host "СБОЙ: $_" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env bash
|
||||
# Полный локальный гейт: формат, сборка, тесты.
|
||||
#
|
||||
# Обёртка вокруг `dotnet build` сама по себе бесполезна — ценность в том, что шаги идут в
|
||||
# правильном порядке, падают быстро и возвращают ненулевой код возврата.
|
||||
#
|
||||
# ./build.sh формат, сборка и тесты в Release
|
||||
# ./build.sh --fix переформатировать код, затем собрать и прогнать тесты
|
||||
# ./build.sh -c Debug другая конфигурация
|
||||
# ./build.sh --skip-tests только собрать
|
||||
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
SOLUTION=AvParser.slnx
|
||||
CONFIGURATION=Release
|
||||
FIX=0
|
||||
SKIP_FORMAT=0
|
||||
SKIP_TESTS=0
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-c|--configuration) CONFIGURATION="$2"; shift 2 ;;
|
||||
--fix) FIX=1; shift ;;
|
||||
--skip-format) SKIP_FORMAT=1; shift ;;
|
||||
--skip-tests) SKIP_TESTS=1; shift ;;
|
||||
-h|--help) sed -n '2,10p' "$0"; exit 0 ;;
|
||||
*) echo "Неизвестный аргумент: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "$CONFIGURATION" in
|
||||
Debug|Release) ;;
|
||||
*) echo "Конфигурация должна быть Debug или Release, получено: $CONFIGURATION" >&2; exit 2 ;;
|
||||
esac
|
||||
|
||||
step() { printf '\n\033[36m==> %s\033[0m\n' "$1"; }
|
||||
|
||||
trap 'printf "\n\033[31mСБОЙ на шаге: %s\033[0m\n" "${CURRENT_STEP:-?}" >&2' ERR
|
||||
|
||||
CURRENT_STEP='Локальные инструменты'; step "$CURRENT_STEP"
|
||||
dotnet tool restore
|
||||
|
||||
CURRENT_STEP='Восстановление пакетов'; step "$CURRENT_STEP"
|
||||
dotnet restore "$SOLUTION"
|
||||
|
||||
if [ "$SKIP_FORMAT" -eq 0 ]; then
|
||||
if [ "$FIX" -eq 1 ]; then
|
||||
CURRENT_STEP='Форматирование (csharpier format)'; step "$CURRENT_STEP"
|
||||
dotnet csharpier format .
|
||||
else
|
||||
# До сборки: несформатированный файл — самый дешёвый повод упасть.
|
||||
CURRENT_STEP='Проверка форматирования (csharpier check)'; step "$CURRENT_STEP"
|
||||
dotnet csharpier check .
|
||||
fi
|
||||
fi
|
||||
|
||||
CURRENT_STEP="Сборка ($CONFIGURATION)"; step "$CURRENT_STEP"
|
||||
dotnet build "$SOLUTION" -c "$CONFIGURATION" --no-restore --nologo
|
||||
|
||||
if [ "$SKIP_TESTS" -eq 0 ]; then
|
||||
CURRENT_STEP='Тесты'; step "$CURRENT_STEP"
|
||||
dotnet test "$SOLUTION" -c "$CONFIGURATION" --no-build --nologo
|
||||
fi
|
||||
|
||||
printf '\n\033[32mOK\033[0m\n'
|
||||
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Запускает desktop-приложение.
|
||||
|
||||
.DESCRIPTION
|
||||
По умолчанию Debug: быстрее собирается и даёт осмысленные стеки. Инспектора в Avalonia 12
|
||||
из коробки нет — см. README.
|
||||
|
||||
.PARAMETER Configuration
|
||||
Debug или Release. По умолчанию Debug.
|
||||
|
||||
.PARAMETER NoBuild
|
||||
Не пересобирать — запустить то, что уже собрано.
|
||||
|
||||
.PARAMETER AppArgs
|
||||
Всё остальное уходит в приложение как аргументы командной строки.
|
||||
|
||||
.EXAMPLE
|
||||
./run.ps1
|
||||
|
||||
.EXAMPLE
|
||||
./run.ps1 -Configuration Release -NoBuild
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateSet('Debug', 'Release')]
|
||||
[string] $Configuration = 'Debug',
|
||||
|
||||
[switch] $NoBuild,
|
||||
|
||||
[Parameter(ValueFromRemainingArguments = $true)]
|
||||
[string[]] $AppArgs = @()
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Set-Location $PSScriptRoot
|
||||
|
||||
$arguments = @('run', '--project', 'src/AvParser.Desktop', '-c', $Configuration)
|
||||
if ($NoBuild) {
|
||||
$arguments += '--no-build'
|
||||
}
|
||||
if ($AppArgs.Count -gt 0) {
|
||||
$arguments += '--'
|
||||
$arguments += $AppArgs
|
||||
}
|
||||
|
||||
Write-Host "==> dotnet $($arguments -join ' ')" -ForegroundColor Cyan
|
||||
& dotnet @arguments
|
||||
exit $LASTEXITCODE
|
||||
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
# Запускает desktop-приложение.
|
||||
#
|
||||
# По умолчанию Debug: быстрее собирается и даёт осмысленные стеки. Инспектора в Avalonia 12
|
||||
# из коробки нет — см. README.
|
||||
#
|
||||
# ./run.sh Debug
|
||||
# ./run.sh -c Release --no-build запустить уже собранное
|
||||
# ./run.sh -- --какой-то-аргумент передать аргументы приложению
|
||||
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
CONFIGURATION=Debug
|
||||
NO_BUILD=0
|
||||
APP_ARGS=()
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-c|--configuration) CONFIGURATION="$2"; shift 2 ;;
|
||||
--no-build) NO_BUILD=1; shift ;;
|
||||
-h|--help) sed -n '2,9p' "$0"; exit 0 ;;
|
||||
--) shift; APP_ARGS=("$@"); break ;;
|
||||
*) echo "Неизвестный аргумент: $1 (аргументы приложения — после --)" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
ARGS=(run --project src/AvParser.Desktop -c "$CONFIGURATION")
|
||||
[ "$NO_BUILD" -eq 1 ] && ARGS+=(--no-build)
|
||||
[ ${#APP_ARGS[@]} -gt 0 ] && ARGS+=(-- "${APP_ARGS[@]}")
|
||||
|
||||
printf '\033[36m==> dotnet %s\033[0m\n' "${ARGS[*]}"
|
||||
exec dotnet "${ARGS[@]}"
|
||||
@@ -28,8 +28,13 @@
|
||||
<PackageReference Include="Serilog.Extensions.Logging" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<!-- F12 opens DevTools, which is the fastest way to see :compact/:medium/:expanded toggle. -->
|
||||
<PackageReference Include="Avalonia.Diagnostics" />
|
||||
</ItemGroup>
|
||||
<!--
|
||||
No Avalonia.Diagnostics here: it stops at 11.3.x and has no Avalonia 12 build. Avalonia 12
|
||||
moved the inspector out of the framework into a separate tool with its own installation
|
||||
(AvaloniaUI.DiagnosticsSupport + `.WithDeveloperTools()`), so there is no built-in F12.
|
||||
|
||||
Note also that Condition="'$(Configuration)' == 'Debug'" on a PackageReference is a trap:
|
||||
`dotnet restore` evaluates with the default configuration, so the package still has to
|
||||
resolve even if nothing ever builds that configuration.
|
||||
-->
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user