前情提要
-
问题起源:工作上平常开发的几个专案,有个共用的元件,被抽出封装成 Nuget 套件的形式在使用,因为日常开发经常需要改动这个共用元件,流程就会是:
- 先修改共用元件专案,发 PR 进 Code 后,发布新的 NuGet 版本
- 再升级到使用该元件的专案继续开发和测试
- 如果发现问题,就可能要再次重复前面的步骤来回一次
-
我的痛点:有时候动到元件里一些稍微复杂的功能,像第三方 API Client 的串接,就会一直来来回回,令我困扰的事就出现了,例如:
- 本机测试来回:因为每次修改共用元件后,都需要重新升级 NuGet 套件版本,发布后再回到主专案升级,才能测试功能是否正常,导致测试发现问题的时候,就要一直来回才能继续测。
- NuGet 套件是在进版后才发现问题:一直把没有测过的功能上版,看着一堆修复的 commit 觉得无奈。
- Debug 进不去共元元件里面看(超困扰)
-
结论:我有个梦想,我想在本机直接对 Nuget 套件 Debug,边改边测,直到功能正常再发共用元件的 PR,于是我写了点 PowerShell~(也许 TDD 的开发模式,或是写点 Mock Code 可以解决这个问题,但我不想更改我的梦想所以先放着(?
方法原理
目的:把专案的 Nuget 套件替换成 Source Code 专案来 Debug
作法
移除 NuGet 套件,改用参考专案
- 把下面内容存成.ps1档,把前置参数设定好($pkgProjFile 和 $slnFile),执行
# Set variables for the NuGet package and solution paths
$pkgProjFile= "C:\\......\\XXX.csproj" # 替换成 NuGet 原始码专案路径
$slnFile = "C:\\......\\XXX.sln" # 替换成你的使用端专案 Solution 路径
$pkgName = "XXXXXX" # 替换成你的 NuGet 套件名称
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# Initialize an empty array to store project files that reference the NuGet package
$projFilesToMunge = @()
# Get all project files in the solution
$projects = dotnet sln $slnFile list | ForEach-Object { $_ -replace \'\\s\', \'\' } | Where-Object { $_ -like \'*.csproj\' }
# Get the directory of the solution file
$slnDirectory = Split-Path -Path $slnFile
# Check each project for the NuGet package
echo "正在寻找有引用 $pkgName 套件的专案..."
foreach ($projFile in $projects) {
$projFilePath = Join-Path -Path $slnDirectory -ChildPath $projFile
echo "正在确认: $projFilePath"
$packageList = dotnet list $projFilePath package
$packageMatch = $packageList | Select-String -Pattern $pkgName
if ($packageMatch) {
# Add project file to the list if it references the NuGet package
$projFilesToMunge += $projFilePath
}
}
echo "需修改的专案:"
echo $projFilesToMunge
echo "添加专案 $pkgProjFile 到解决方案..."
# Add the source code project to the solution
dotnet sln $slnFile add $pkgProjFile
echo "开始替换nuget套件为实体专案..."
# Remove NuGet package and add project reference for each project
foreach ($projFile in $projFilesToMunge) {
dotnet remove $projFile package $pkgName # 移除 NuGet 套件
dotnet add $projFile reference $pkgProjFile # 添加专案引用
}
Write-Host "按 Enter 键结束..."
Read-Host | Out-Null
本机 Debug 开发测试
- 下中断点,下监看式,找到谁忘了注入,找出谁变成null等.....
把参考专案移除,把 NuGet 套件还原
- 把下面内容存成.ps1档,把前置参数设定好($pkgProjFile 和 $slnFile),执行
- PS:这步是直接使用 Git 的 discard change,复原.csproj档,所以会提示是否真的要还原这些档案,这个暂解是因为我在用 .dotnet 还原的时候一直无法成功。
# Set variables for the NuGet package and solution paths
$pkgProjFile= "C:\\......\\XXX.csproj" # 替换成 NuGet 原始码专案路径
$slnFile = "C:\\......\\XXX.sln" # 替换成你的使用端专案 Solution 路径
$pkgName = "XXXXXX" # 替换成你的 NuGet 套件名称
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# Initialize an empty array to store project files that reference the NuGet project
$projFilesToMunge = @()
# Get all project files in the solution
$projects = dotnet sln $slnFile list | ForEach-Object { $_ -replace \'\\s\', \'\' } | Where-Object { $_ -like \'*.csproj\' }
# Get the directory of the solution file
$slnDirectory = Split-Path -Path $slnFile
# Check each project for the ProjectReference in the csproj file
echo "正在寻找有引用 $pkgProjFile 的专案..."
foreach ($projFile in $projects) {
$projFilePath = Join-Path -Path $slnDirectory -ChildPath $projFile
echo "正在确认: $projFilePath"
$referenceList = dotnet list $projFilePath reference
foreach ($reference in $referenceList) {
# 只处理有效的路径,排除非专案引用行
if ($reference -like "*csproj") {
$porjectDir = Join-Path -Path $slnDirectory -ChildPath (Split-Path -Path $projFile)
$resolvedPath = Resolve-Path -Path (Join-Path -Path $porjectDir -ChildPath $reference)
$resolvedPath = [System.IO.Path]::GetFullPath($resolvedPath)
# 检查路径是否有效并且是否匹配目标专案
if ($resolvedPath -eq $pkgProjFile) {
echo "耶,找到了 $projFilePath"
$projFilesToMunge += $projFilePath
}
}
}
}
echo "需还原的专案:"
echo $projFilesToMunge
Write-Host "即将使用git版控还原以上专案档,按 Enter 键以继续..."
Read-Host | Out-Null
cd $slnDirectory
echo "开始暴力还原专案引用为 NuGet 套件..."
# Remove project reference and add NuGet package for each project
# 使用 Git 暴力丢弃专案档案的变更
foreach ($projFile in $projFilesToMunge) {
git restore $projFile
#dotnet remove $projFile reference $pkgProjFile # 移除专案引用
#dotnet add $projFile package $pkgName --version $nugetVersion # 还原为 NuGet 套件,$nugetVersion指定要还原的 NuGet 套件版本
echo "已还原: $projFile"
}
# Optional: Remove the source code project from the solution
echo "从解决方案移除专案 $pkgProjFile ..."
dotnet sln $slnFile remove $pkgProjFile
Write-Host "按 Enter 键结束..."
Read-Host | Out-Null
以上是我跟 ChatGPT 搏斗的结果,虽然最后用 Git 还原我还没有更好的解法,但目前还算是堪用
这是我为了实现能 Debug 开发而花了点时间整理出的脚本,希望某天谁有一样的想法的时候,可以帮助到你