update
This commit is contained in:
35
dev.cmd
35
dev.cmd
@ -1,5 +1,34 @@
|
||||
@echo off
|
||||
rem dev.cmd — 双击即可启动本地开发环境(等同于 .\dev\dev.ps1)
|
||||
rem 参数原样透传,例如:dev.cmd -Vision -Open
|
||||
rem dev.cmd <EFBFBD><EFBFBD> ˫<><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC> .\dev\dev.ps1<EFBFBD><EFBFBD>
|
||||
rem <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>磺dev.cmd -Vision -Open dev.cmd -Foreground
|
||||
rem
|
||||
rem <20><><EFBFBD>ڲ<EFBFBD><DAB2>ԣ<EFBFBD>
|
||||
rem ʧ<><CAA7> <20><> pause<73><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
rem ǰ̨ģʽ <20><> <20>ű<EFBFBD><C5B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ctrl+C<><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pause
|
||||
rem <20>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>̨<EFBFBD><CCA8> <20><> pause<73><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>Ϣ<EFBFBD><CFA2><EFBFBD>ش<EFBFBD><D8B4>ڲ<EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
setlocal
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0dev\dev.ps1" %*
|
||||
if errorlevel 1 pause
|
||||
set RC=%ERRORLEVEL%
|
||||
|
||||
echo.
|
||||
if not "%RC%"=="0" (
|
||||
echo [<5B><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3>˳<EFBFBD><CBB3><EFBFBD> %RC%] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><F2A3ACB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>š<EFBFBD>
|
||||
echo <20><>ϸ<EFBFBD><CFB8>־<EFBFBD><D6BE>app-cli\.logs\ <20>鿴<EFBFBD><E9BFB4>.\dev\logs.ps1 -Follow
|
||||
pause
|
||||
exit /b %RC%
|
||||
)
|
||||
|
||||
echo %* | findstr /i /c:"-Foreground" >nul 2>&1
|
||||
if not errorlevel 1 (
|
||||
echo [ǰ̨ģʽ<C4A3>ѽ<EFBFBD><D1BD><EFBFBD>]
|
||||
pause
|
||||
exit /b 0
|
||||
)
|
||||
|
||||
echo [<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD>̨<EFBFBD><CCA8><EFBFBD>У<EFBFBD><D0A3>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>]
|
||||
echo <20><>ʵʱ<CAB5><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dev.cmd -Foreground ^(ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>^)
|
||||
echo <20>鿴<EFBFBD><E9BFB4>־<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>.\dev\logs.ps1 -Follow
|
||||
echo ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.\dev\stop.ps1
|
||||
echo.
|
||||
pause
|
||||
exit /b 0
|
||||
|
||||
139
dev/dev.ps1
139
dev/dev.ps1
@ -24,6 +24,18 @@
|
||||
.EXAMPLE
|
||||
.\dev\dev.ps1 -Force
|
||||
端口被占时先杀掉占用进程再启动
|
||||
|
||||
.EXAMPLE
|
||||
.\dev\dev.ps1 backend -Foreground
|
||||
前台运行后端:日志(含 gin 路由、8092 管理后台请求)直接打在终端,Ctrl+C 结束
|
||||
|
||||
.EXAMPLE
|
||||
.\dev\dev.ps1 frontend -Foreground
|
||||
前台运行前端:astro 的请求日志、编译告警直接打在终端,Ctrl+C 结束
|
||||
|
||||
.EXAMPLE
|
||||
.\dev\dev.ps1 -Foreground
|
||||
推荐日常调试:后端 + 前端都前台跑,两边输出一起打在当前终端
|
||||
#>
|
||||
param(
|
||||
[Parameter(Position = 0)]
|
||||
@ -33,7 +45,11 @@ param(
|
||||
[switch]$Vision,
|
||||
[switch]$SkipBuild,
|
||||
[switch]$Open,
|
||||
[switch]$Force
|
||||
[switch]$Force,
|
||||
|
||||
# 前台模式:不重定向、不隐藏窗口,服务输出直接打在当前终端(Ctrl+C 结束)。
|
||||
# 不带服务名(all)时,前后端输出会一起打在当前终端,适合日常调试。
|
||||
[switch]$Foreground
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
@ -43,6 +59,14 @@ $CliRoot = Split-Path -Parent $PSScriptRoot
|
||||
$envMap = Import-LocalEnv (Join-Path $CliRoot 'config\local.env')
|
||||
$svc = Resolve-Services -EnvMap $envMap -Root $CliRoot
|
||||
|
||||
if ($Foreground -and $Target -eq 'vision') {
|
||||
Write-Fail '视觉服务不支持 -Foreground(用 .\vision\vision.ps1 logs 查看输出)'
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 前台模式下正在运行的进程(all 模式会有多个,输出共用当前控制台)
|
||||
$script:fgProcs = @()
|
||||
|
||||
$backendPort = [int](Get-Setting $envMap 'BACKEND_PORT' '8090')
|
||||
$frontendPort = [int](Get-Setting $envMap 'FRONTEND_PORT' '4321')
|
||||
$visionPort = [int](Get-Setting $envMap 'VISION_PORT' '8900')
|
||||
@ -62,6 +86,18 @@ function Assert-CanStart {
|
||||
$owner = Get-PortOwnerPid $Port
|
||||
$saved = Get-ServicePid $Name
|
||||
if ($saved -gt 0 -and $saved -eq $owner) {
|
||||
# 前台模式的语义就是「把输出占在我的终端」,已在后台跑的那份必须让位。
|
||||
# 否则会出现「全部跳过 → 前台循环没进程 → 脚本直接退出」的假象。
|
||||
if ($Foreground) {
|
||||
Write-Note "$Name 已在后台运行(PID $owner),前台接管:先停止再前台启动"
|
||||
Stop-NamedService $Name | Out-Null
|
||||
Start-Sleep -Milliseconds 600
|
||||
if (Test-PortInUse $Port) {
|
||||
Write-Fail "端口 $Port 仍未释放,无法前台接管"
|
||||
return 'abort'
|
||||
}
|
||||
return 'start'
|
||||
}
|
||||
Write-Note "$Name 已在运行(PID $owner,端口 $Port),跳过"
|
||||
return 'skip'
|
||||
}
|
||||
@ -127,6 +163,30 @@ function Start-Backend {
|
||||
Remove-Item Env:\VISION_ENABLED -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
if ($Foreground) {
|
||||
Write-Step "前台运行后端(公开 $backendPort / SSG 8091 / 后台 8092)"
|
||||
|
||||
# 只起后端:直接阻塞在这个进程上,Ctrl+C 就是结束进程,最干净。
|
||||
if ($Target -eq 'backend') {
|
||||
Write-Note '输出直接打在下面;Ctrl+C 结束'
|
||||
Push-Location $svc.Backend.Path
|
||||
try {
|
||||
& $exe
|
||||
} finally {
|
||||
Pop-Location
|
||||
Remove-Item Env:\VISION_ENABLED -ErrorAction SilentlyContinue
|
||||
}
|
||||
exit 0
|
||||
}
|
||||
|
||||
# all 模式:-NoNewWindow 让子进程继承当前控制台,输出实时可见(不重定向)
|
||||
$p = Start-Process -FilePath $exe -WorkingDirectory $svc.Backend.Path -NoNewWindow -PassThru
|
||||
$script:fgProcs += [PSCustomObject]@{ Name = 'backend'; Proc = $p; Reported = $false }
|
||||
Remove-Item Env:\VISION_ENABLED -ErrorAction SilentlyContinue
|
||||
Write-Ok "后端已在前台启动(PID $($p.Id))"
|
||||
return $true
|
||||
}
|
||||
|
||||
Write-Step "启动后端(公开 $backendPort / SSG 8091 / 后台 8092)"
|
||||
Start-LoggedProcess -Name 'backend' -FilePath $exe -ArgumentList @() -WorkingDirectory $svc.Backend.Path | Out-Null
|
||||
Remove-Item Env:\VISION_ENABLED -ErrorAction SilentlyContinue
|
||||
@ -177,6 +237,9 @@ function Start-Frontend {
|
||||
if ($action -eq 'skip') { return $true }
|
||||
if ($action -eq 'abort') { return $false }
|
||||
|
||||
# 前台接管时旧实例刚被停掉,锁文件可能残留(PID 被复用会误判「已在运行」)
|
||||
if ($Foreground) { Remove-AstroDevLock $svc.Frontend.Path }
|
||||
|
||||
# astro 单实例锁:端口没冲突也可能起不来
|
||||
$lock = Get-AstroDevLock $svc.Frontend.Path
|
||||
if ($lock -and $lock.Alive) {
|
||||
@ -218,6 +281,28 @@ function Start-Frontend {
|
||||
return $false
|
||||
}
|
||||
|
||||
if ($Foreground) {
|
||||
Write-Step "前台运行前端(astro dev,端口 $frontendPort)"
|
||||
|
||||
if ($Target -eq 'frontend') {
|
||||
Write-Note '输出直接打在下面;Ctrl+C 结束'
|
||||
Push-Location $svc.Frontend.Path
|
||||
try {
|
||||
& node.exe $astro dev --port "$frontendPort"
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
exit 0
|
||||
}
|
||||
|
||||
$p = Start-Process -FilePath 'node.exe' `
|
||||
-ArgumentList @($astro, 'dev', '--port', "$frontendPort") `
|
||||
-WorkingDirectory $svc.Frontend.Path -NoNewWindow -PassThru
|
||||
$script:fgProcs += [PSCustomObject]@{ Name = 'frontend'; Proc = $p; Reported = $false }
|
||||
Write-Ok "前端已在前台启动(PID $($p.Id))"
|
||||
return $true
|
||||
}
|
||||
|
||||
Write-Step "启动前端(astro dev,端口 $frontendPort)"
|
||||
Start-LoggedProcess -Name 'frontend' -FilePath 'node.exe' `
|
||||
-ArgumentList @($astro, 'dev', '--port', "$frontendPort") `
|
||||
@ -310,6 +395,54 @@ if ($Vision -or $Target -eq 'vision') {
|
||||
if (-not (Start-Vision)) { $failed += 'vision' }
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- 前台聚合输出
|
||||
# 前台模式下半套启动没有意义(端口冲突等):直接报错退出,不留孤儿进程。
|
||||
if ($Foreground -and $failed.Count -gt 0) {
|
||||
Write-Fail ("前台启动失败:" + ($failed -join ', '))
|
||||
Write-Note '常见原因:8090/4323 已被之前的进程占用,先 .\dev\stop.ps1 再重试'
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 兜底:前台模式必须有进程在跑,否则静默退出会让人误以为脚本自己崩了。
|
||||
if ($Foreground -and $script:fgProcs.Count -eq 0) {
|
||||
Write-Fail '前台模式没有启动任何进程,请查看上面的输出'
|
||||
exit 1
|
||||
}
|
||||
|
||||
# all + -Foreground:子进程共用当前控制台,输出由它们直接写终端(无重定向、无延迟)。
|
||||
# 这里只负责等待与收尾:任一进程退出就报告,Ctrl+C 时一起停掉。
|
||||
if ($Foreground -and $script:fgProcs.Count -gt 0) {
|
||||
$names = ($script:fgProcs | ForEach-Object { $_.Name }) -join ' + '
|
||||
Write-Host ''
|
||||
Write-Host ' ----------------------------------------' -ForegroundColor DarkGray
|
||||
Write-Host " $names 的输出直接打在下面,Ctrl+C 一起停止" -ForegroundColor Yellow
|
||||
Write-Host ' ----------------------------------------' -ForegroundColor DarkGray
|
||||
Write-Host ''
|
||||
try {
|
||||
while ($true) {
|
||||
Start-Sleep -Milliseconds 400
|
||||
$alive = @($script:fgProcs | Where-Object { -not $_.Proc.HasExited })
|
||||
if ($alive.Count -eq 0) { break }
|
||||
foreach ($e in $script:fgProcs) {
|
||||
if (-not $e.Reported -and $e.Proc.HasExited) {
|
||||
Write-Fail "$($e.Name) 已退出(退出码 $($e.Proc.ExitCode)),另一个仍在运行"
|
||||
$e.Reported = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
foreach ($e in $script:fgProcs) {
|
||||
if (-not $e.Proc.HasExited) {
|
||||
Write-Note "停止 $($e.Name)(PID $($e.Proc.Id))"
|
||||
Stop-PidTree $e.Proc.Id | Out-Null
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Host ''
|
||||
Write-Note '前台模式已退出(这些进程不在 .run\ 登记,stop.ps1 不管它们)'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- 结果汇总
|
||||
|
||||
Write-Host ''
|
||||
@ -347,7 +480,9 @@ if (Test-PortInUse $backendPort) {
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Note '日志:.logs\backend.log / .logs\frontend.log / .logs\vision.log'
|
||||
Write-Note '本窗口只显示启动过程;服务输出写在 .logs\ 下,不会打到终端(这是后台模式的正常表现)'
|
||||
Write-Note '要实时看输出:.\dev\logs.ps1 backend -Follow 或 .\dev\logs.ps1 frontend -Follow'
|
||||
Write-Note '要实时看全部输出:.\dev\dev.ps1 -Foreground(前后端一起前台跑,Ctrl+C 停)'
|
||||
Write-Note '停止:.\dev\stop.ps1 状态:.\dev\status.ps1'
|
||||
|
||||
if ($Open) {
|
||||
|
||||
81
dev/logs.ps1
Normal file
81
dev/logs.ps1
Normal file
@ -0,0 +1,81 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
查看本地服务的运行日志(dev.ps1 用后台进程启动,输出不落在终端)。
|
||||
|
||||
.DESCRIPTION
|
||||
dev.ps1 把后端/前端的 stdout/stderr 重定向到 .logs\ 下的文件,
|
||||
所以「服务在跑但终端没有任何输出」是正常的。本脚本就是看那些文件的入口。
|
||||
|
||||
每个服务有两个文件:
|
||||
.logs\<name>.log 标准输出(业务日志、gin 路由、astro 启动信息)
|
||||
.logs\<name>.err.log 标准错误(编译报错、panic、连接失败)
|
||||
|
||||
.EXAMPLE
|
||||
.\dev\logs.ps1
|
||||
看后端最近 50 行(默认)
|
||||
|
||||
.EXAMPLE
|
||||
.\dev\logs.ps1 frontend -Lines 100
|
||||
看前端最近 100 行
|
||||
|
||||
.EXAMPLE
|
||||
.\dev\logs.ps1 backend -Follow
|
||||
持续跟随后端日志(Ctrl+C 退出),等价于 Get-Content -Wait
|
||||
|
||||
.EXAMPLE
|
||||
.\dev\logs.ps1 all
|
||||
三个服务的日志都看一遍(只看不跟随)
|
||||
#>
|
||||
param(
|
||||
[Parameter(Position = 0)]
|
||||
[ValidateSet('backend', 'frontend', 'vision', 'all')]
|
||||
[string]$Name = 'backend',
|
||||
|
||||
[int]$Lines = 50,
|
||||
|
||||
[switch]$Follow
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$CliRoot = Split-Path -Parent $PSScriptRoot
|
||||
$LogDir = Join-Path $CliRoot '.logs'
|
||||
|
||||
if (-not (Test-Path $LogDir)) {
|
||||
Write-Host " 还没有日志:$LogDir" -ForegroundColor Yellow
|
||||
Write-Host " 先跑 .\dev\dev.ps1 启动服务" -ForegroundColor Gray
|
||||
exit 1
|
||||
}
|
||||
|
||||
$targets = if ($Name -eq 'all') { @('backend', 'frontend', 'vision') } else { @($Name) }
|
||||
|
||||
if ($Follow -and $targets.Count -gt 1) {
|
||||
Write-Host " -Follow 一次只能跟一个服务,改成:.\dev\logs.ps1 backend -Follow" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
|
||||
foreach ($t in $targets) {
|
||||
foreach ($suffix in @('.log', '.err.log')) {
|
||||
$f = Join-Path $LogDir ($t + $suffix)
|
||||
if (-not (Test-Path $f)) { continue }
|
||||
|
||||
$size = (Get-Item $f).Length
|
||||
Write-Host ''
|
||||
Write-Host (" --- {0}{1} ({2} 字节) ---" -f $t, $suffix, $size) -ForegroundColor DarkGray
|
||||
|
||||
if ($size -eq 0) {
|
||||
Write-Host ' (空文件:进程可能刚启动,或输出还在缓冲区)' -ForegroundColor DarkGray
|
||||
continue
|
||||
}
|
||||
|
||||
if ($Follow) {
|
||||
# -Wait 会阻塞直到 Ctrl+C;先打最近 N 行再跟随新增内容
|
||||
Write-Host " 跟随中,Ctrl+C 退出" -ForegroundColor DarkGray
|
||||
Get-Content -Path $f -Tail $Lines -Wait
|
||||
} else {
|
||||
Get-Content -Path $f -Tail $Lines | ForEach-Object { Write-Host " $_" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host ' PID 登记:.run\<name>.pid 状态:.\dev\status.ps1' -ForegroundColor DarkGray
|
||||
Reference in New Issue
Block a user